diff --git a/core/allnet.py b/core/allnet.py
index 31065d2..9ffa4e4 100644
--- a/core/allnet.py
+++ b/core/allnet.py
@@ -112,6 +112,8 @@ class AllnetServlet:
)
resp.uri = f"http://{self.config.title.hostname}:{self.config.title.port}/{req.game_id}/{req.ver.replace('.', '')}/"
resp.host = f"{self.config.title.hostname}:{self.config.title.port}"
+
+ self.logger.debug(f"Allnet response: {vars(resp)}")
return self.dict_to_http_form_string([vars(resp)])
resp.uri, resp.host = self.uri_registry[req.game_id]
@@ -204,16 +206,17 @@ class AllnetServlet:
else: # TODO: Keychip check
if path.exists(
- f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver}-app.ini"
+ f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver.replace('.', '')}-app.ini"
):
resp.uri = f"http://{self.config.title.hostname}:{self.config.title.port}/dl/ini/{req.game_id}-{req.ver.replace('.', '')}-app.ini"
if path.exists(
- f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver}-opt.ini"
+ f"{self.config.allnet.update_cfg_folder}/{req.game_id}-{req.ver.replace('.', '')}-opt.ini"
):
resp.uri += f"|http://{self.config.title.hostname}:{self.config.title.port}/dl/ini/{req.game_id}-{req.ver.replace('.', '')}-opt.ini"
self.logger.debug(f"Sending download uri {resp.uri}")
+ self.data.base.log_event("allnet", "DLORDER_REQ_SUCCESS", logging.INFO, f"{Utils.get_ip_addr(request)} requested DL Order for {req.serial} {req.game_id} v{req.ver}")
return self.dict_to_http_form_string([vars(resp)])
def handle_dlorder_ini(self, request: Request, match: Dict) -> bytes:
@@ -223,6 +226,8 @@ class AllnetServlet:
req_file = match["file"].replace("%0A", "")
if path.exists(f"{self.config.allnet.update_cfg_folder}/{req_file}"):
+ self.logger.info(f"Request for DL INI file {req_file} from {Utils.get_ip_addr(request)} successful")
+ self.data.base.log_event("allnet", "DLORDER_INI_SENT", logging.INFO, f"{Utils.get_ip_addr(request)} successfully recieved {req_file}")
return open(
f"{self.config.allnet.update_cfg_folder}/{req_file}", "rb"
).read()
@@ -410,8 +415,8 @@ class AllnetPowerOnResponse3:
self.uri = ""
self.host = ""
self.place_id = "123"
- self.name = ""
- self.nickname = ""
+ self.name = "ARTEMiS"
+ self.nickname = "ARTEMiS"
self.region0 = "1"
self.region_name0 = "W"
self.region_name1 = ""
@@ -435,8 +440,8 @@ class AllnetPowerOnResponse2:
self.uri = ""
self.host = ""
self.place_id = "123"
- self.name = "Test"
- self.nickname = "Test123"
+ self.name = "ARTEMiS"
+ self.nickname = "ARTEMiS"
self.region0 = "1"
self.region_name0 = "W"
self.region_name1 = "X"
diff --git a/core/data/database.py b/core/data/database.py
index 719d05e..ffbefc0 100644
--- a/core/data/database.py
+++ b/core/data/database.py
@@ -333,3 +333,8 @@ class Data:
if not failed:
self.base.set_schema_ver(latest_ver, game)
+
+ def show_versions(self) -> None:
+ all_game_versions = self.base.get_all_schema_vers()
+ for ver in all_game_versions:
+ self.logger.info(f"{ver['game']} -> v{ver['version']}")
diff --git a/core/data/schema/user.py b/core/data/schema/user.py
index 98663d1..6a95005 100644
--- a/core/data/schema/user.py
+++ b/core/data/schema/user.py
@@ -79,6 +79,9 @@ class UserData(BaseData):
if usr["password"] is None:
return False
+
+ if passwd is None or not passwd:
+ return False
return bcrypt.checkpw(passwd, usr["password"].encode())
diff --git a/core/data/schema/versions/SDBT_3_rollback.sql b/core/data/schema/versions/SDBT_3_rollback.sql
new file mode 100644
index 0000000..ff78c54
--- /dev/null
+++ b/core/data/schema/versions/SDBT_3_rollback.sql
@@ -0,0 +1,30 @@
+SET FOREIGN_KEY_CHECKS = 0;
+
+ALTER TABLE chuni_score_playlog
+ DROP COLUMN regionId,
+ DROP COLUMN machineType;
+
+ALTER TABLE chuni_static_events
+ DROP COLUMN startDate;
+
+ALTER TABLE chuni_profile_data
+ DROP COLUMN rankUpChallengeResults;
+
+ALTER TABLE chuni_static_login_bonus
+ DROP FOREIGN KEY chuni_static_login_bonus_ibfk_1;
+
+ALTER TABLE chuni_static_login_bonus_preset
+ DROP PRIMARY KEY;
+
+ALTER TABLE chuni_static_login_bonus_preset
+ CHANGE COLUMN presetId id INT NOT NULL;
+ALTER TABLE chuni_static_login_bonus_preset
+ ADD PRIMARY KEY(id);
+ALTER TABLE chuni_static_login_bonus_preset
+ ADD CONSTRAINT chuni_static_login_bonus_preset_uk UNIQUE(id, version);
+
+ALTER TABLE chuni_static_login_bonus
+ ADD CONSTRAINT chuni_static_login_bonus_ibfk_1 FOREIGN KEY(presetId)
+ REFERENCES chuni_static_login_bonus_preset(id) ON UPDATE CASCADE ON DELETE CASCADE;
+
+SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
diff --git a/core/data/schema/versions/SDBT_4_upgrade.sql b/core/data/schema/versions/SDBT_4_upgrade.sql
new file mode 100644
index 0000000..984447e
--- /dev/null
+++ b/core/data/schema/versions/SDBT_4_upgrade.sql
@@ -0,0 +1,29 @@
+SET FOREIGN_KEY_CHECKS = 0;
+
+ALTER TABLE chuni_score_playlog
+ ADD COLUMN regionId INT,
+ ADD COLUMN machineType INT;
+
+ALTER TABLE chuni_static_events
+ ADD COLUMN startDate TIMESTAMP NOT NULL DEFAULT current_timestamp();
+
+ALTER TABLE chuni_profile_data
+ ADD COLUMN rankUpChallengeResults JSON;
+
+ALTER TABLE chuni_static_login_bonus
+ DROP FOREIGN KEY chuni_static_login_bonus_ibfk_1;
+
+ALTER TABLE chuni_static_login_bonus_preset
+ CHANGE COLUMN id presetId INT NOT NULL;
+ALTER TABLE chuni_static_login_bonus_preset
+ DROP PRIMARY KEY;
+ALTER TABLE chuni_static_login_bonus_preset
+ DROP INDEX chuni_static_login_bonus_preset_uk;
+ALTER TABLE chuni_static_login_bonus_preset
+ ADD CONSTRAINT chuni_static_login_bonus_preset_pk PRIMARY KEY (presetId, version);
+
+ALTER TABLE chuni_static_login_bonus
+ ADD CONSTRAINT chuni_static_login_bonus_ibfk_1 FOREIGN KEY (presetId, version)
+ REFERENCES chuni_static_login_bonus_preset(presetId, version) ON UPDATE CASCADE ON DELETE CASCADE;
+
+SET FOREIGN_KEY_CHECKS = 1;
\ No newline at end of file
diff --git a/core/data/schema/versions/SDEZ_4_rollback.sql b/core/data/schema/versions/SDEZ_4_rollback.sql
index 290fa85..b8be7b3 100644
--- a/core/data/schema/versions/SDEZ_4_rollback.sql
+++ b/core/data/schema/versions/SDEZ_4_rollback.sql
@@ -1,26 +1,3 @@
-DELETE FROM mai2_static_event WHERE version < 13;
-UPDATE mai2_static_event SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_static_music WHERE version < 13;
-UPDATE mai2_static_music SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_static_ticket WHERE version < 13;
-UPDATE mai2_static_ticket SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_static_cards WHERE version < 13;
-UPDATE mai2_static_cards SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_profile_detail WHERE version < 13;
-UPDATE mai2_profile_detail SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_profile_extend WHERE version < 13;
-UPDATE mai2_profile_extend SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_profile_option WHERE version < 13;
-UPDATE mai2_profile_option SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_profile_ghost WHERE version < 13;
-UPDATE mai2_profile_ghost SET version = version - 13 WHERE version >= 13;
-
-DELETE FROM mai2_profile_rating WHERE version < 13;
-UPDATE mai2_profile_rating SET version = version - 13 WHERE version >= 13;
+ALTER TABLE mai2_item_card
+ CHANGE COLUMN startDate startDate TIMESTAMP DEFAULT "2018-01-01 00:00:00.0",
+ CHANGE COLUMN endDate endDate TIMESTAMP DEFAULT "2038-01-01 00:00:00.0";
\ No newline at end of file
diff --git a/core/data/schema/versions/SDEZ_5_upgrade.sql b/core/data/schema/versions/SDEZ_5_upgrade.sql
index 18ba4ac..cc4912f 100644
--- a/core/data/schema/versions/SDEZ_5_upgrade.sql
+++ b/core/data/schema/versions/SDEZ_5_upgrade.sql
@@ -1,17 +1,3 @@
-UPDATE mai2_static_event SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_static_music SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_static_ticket SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_static_cards SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_profile_detail SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_profile_extend SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_profile_option SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_profile_ghost SET version = version + 13 WHERE version < 1000;
-
-UPDATE mai2_profile_rating SET version = version + 13 WHERE version < 1000;
\ No newline at end of file
+ALTER TABLE mai2_item_card
+ CHANGE COLUMN startDate startDate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ CHANGE COLUMN endDate endDate TIMESTAMP NOT NULL;
\ No newline at end of file
diff --git a/core/frontend.py b/core/frontend.py
index c992e76..9eb30e6 100644
--- a/core/frontend.py
+++ b/core/frontend.py
@@ -182,7 +182,7 @@ class FE_Gate(FE_Base):
access_code: str = request.args[b"access_code"][0].decode()
username: str = request.args[b"username"][0]
email: str = request.args[b"email"][0].decode()
- passwd: str = request.args[b"passwd"][0]
+ passwd: bytes = request.args[b"passwd"][0]
uid = self.data.card.get_user_id_from_card(access_code)
if uid is None:
@@ -197,7 +197,7 @@ class FE_Gate(FE_Base):
if result is None:
return redirectTo(b"/gate?e=3", request)
- if not self.data.user.check_password(uid, passwd.encode()):
+ if not self.data.user.check_password(uid, passwd):
return redirectTo(b"/gate", request)
return redirectTo(b"/user", request)
@@ -227,9 +227,22 @@ class FE_User(FE_Base):
usr_sesh = IUserSession(sesh)
if usr_sesh.userId == 0:
return redirectTo(b"/gate", request)
+
+ cards = self.data.card.get_user_cards(usr_sesh.userId)
+ user = self.data.user.get_user(usr_sesh.userId)
+ card_data = []
+ for c in cards:
+ if c['is_locked']:
+ status = 'Locked'
+ elif c['is_banned']:
+ status = 'Banned'
+ else:
+ status = 'Active'
+
+ card_data.append({'access_code': c['access_code'], 'status': status})
return template.render(
- title=f"{self.core_config.server.name} | Account", sesh=vars(usr_sesh)
+ title=f"{self.core_config.server.name} | Account", sesh=vars(usr_sesh), cards=card_data, username=user['username']
).encode("utf-16")
diff --git a/core/frontend/user/index.jinja b/core/frontend/user/index.jinja
index eabdd18..2911e67 100644
--- a/core/frontend/user/index.jinja
+++ b/core/frontend/user/index.jinja
@@ -1,4 +1,31 @@
{% extends "core/frontend/index.jinja" %}
{% block content %}
-
testing
+Management for {{ username }}
+Cards Add
+
+{% for c in cards %}
+{{ c.access_code }}: {{ c.status }} Delete
+{% endfor %}
+
+
+
+
+
+
+ HOW TO:
+ Scan your card on any networked game and press the "View Access Code" button (varies by game) and enter the 20 digit code below.
+ !!FOR AMUSEIC CARDS: DO NOT ENTER THE CODE SHOWN ON THE BACK OF THE CARD ITSELF OR IT WILL NOT WORK!!
+
Access Code:
+
+
+
+
+
+
{% endblock content %}
\ No newline at end of file
diff --git a/core/frontend/widgets/topbar.jinja b/core/frontend/widgets/topbar.jinja
index d196361..fb63ebe 100644
--- a/core/frontend/widgets/topbar.jinja
+++ b/core/frontend/widgets/topbar.jinja
@@ -4,7 +4,7 @@
diff --git a/core/mucha.py b/core/mucha.py
index a90ab53..eecae3a 100644
--- a/core/mucha.py
+++ b/core/mucha.py
@@ -33,8 +33,8 @@ class MuchaServlet:
self.logger.addHandler(fileHandler)
self.logger.addHandler(consoleHandler)
- self.logger.setLevel(logging.INFO)
- coloredlogs.install(level=logging.INFO, logger=self.logger, fmt=log_fmt_str)
+ self.logger.setLevel(cfg.mucha.loglevel)
+ coloredlogs.install(level=cfg.mucha.loglevel, logger=self.logger, fmt=log_fmt_str)
all_titles = Utils.get_all_titles()
diff --git a/core/title.py b/core/title.py
index 7a0a99b..ab53773 100644
--- a/core/title.py
+++ b/core/title.py
@@ -84,7 +84,7 @@ class TitleServlet:
request.setResponseCode(405)
return b""
- return index.render_GET(request, endpoints["version"], endpoints["endpoint"])
+ return index.render_GET(request, int(endpoints["version"]), endpoints["endpoint"])
def render_POST(self, request: Request, endpoints: dict) -> bytes:
code = endpoints["game"]
diff --git a/dbutils.py b/dbutils.py
index d959232..caae9d8 100644
--- a/dbutils.py
+++ b/dbutils.py
@@ -84,5 +84,8 @@ if __name__ == "__main__":
elif args.action == "cleanup":
data.delete_hanging_users()
+
+ elif args.action == "version":
+ data.show_versions()
data.logger.info("Done")
diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md
index a2a916a..e4abb03 100644
--- a/docs/game_specific_info.md
+++ b/docs/game_specific_info.md
@@ -9,42 +9,44 @@ using the megaime database. Clean installations always create the latest databas
# Table of content
- [Supported Games](#supported-games)
- - [Chunithm](#chunithm)
+ - [CHUNITHM](#chunithm)
- [crossbeats REV.](#crossbeats-rev)
- [maimai DX](#maimai-dx)
- [O.N.G.E.K.I.](#o-n-g-e-k-i)
- [Card Maker](#card-maker)
- [WACCA](#wacca)
+ - [Sword Art Online Arcade](#sao)
# Supported Games
Games listed below have been tested and confirmed working.
-## Chunithm
+## CHUNITHM
### SDBT
-| Version ID | Version Name |
-|------------|--------------------|
-| 0 | Chunithm |
-| 1 | Chunithm+ |
-| 2 | Chunithm Air |
-| 3 | Chunithm Air + |
-| 4 | Chunithm Star |
-| 5 | Chunithm Star + |
-| 6 | Chunithm Amazon |
-| 7 | Chunithm Amazon + |
-| 8 | Chunithm Crystal |
-| 9 | Chunithm Crystal + |
-| 10 | Chunithm Paradise |
+| Version ID | Version Name |
+|------------|-----------------------|
+| 0 | CHUNITHM |
+| 1 | CHUNITHM PLUS |
+| 2 | CHUNITHM AIR |
+| 3 | CHUNITHM AIR PLUS |
+| 4 | CHUNITHM STAR |
+| 5 | CHUNITHM STAR PLUS |
+| 6 | CHUNITHM AMAZON |
+| 7 | CHUNITHM AMAZON PLUS |
+| 8 | CHUNITHM CRYSTAL |
+| 9 | CHUNITHM CRYSTAL PLUS |
+| 10 | CHUNITHM PARADISE |
### SDHD/SDBT
-| Version ID | Version Name |
-|------------|-----------------|
-| 11 | Chunithm New!! |
-| 12 | Chunithm New!!+ |
+| Version ID | Version Name |
+|------------|---------------------|
+| 11 | CHUNITHM NEW!! |
+| 12 | CHUNITHM NEW PLUS!! |
+| 13 | CHUNITHM SUN |
### Importer
@@ -60,13 +62,33 @@ The importer for Chunithm will import: Events, Music, Charge Items and Avatar Ac
### Database upgrade
Always make sure your database (tables) are up-to-date, to do so go to the `core/data/schema/versions` folder and see
-which version is the latest, f.e. `SDBT_3_upgrade.sql`. In order to upgrade to version 3 in this case you need to
+which version is the latest, f.e. `SDBT_4_upgrade.sql`. In order to upgrade to version 4 in this case you need to
perform all previous updates as well:
```shell
python dbutils.py --game SDBT upgrade
```
+### Online Battle
+
+**Only matchmaking (with your imaginary friends) is supported! Online Battle does not (yet?) work!**
+
+The first person to start the Online Battle (now called host) will create a "matching room" with a given `roomId`, after that max 3 other people can join the created room.
+Non used slots during the matchmaking will be filled with CPUs after the timer runs out.
+As soon as a new member will join the room the timer will jump back to 60 secs again.
+Sending those 4 messages to all other users is also working properly.
+In order to use the Online Battle every user needs the same ICF, same rom version and same data version!
+If a room is full a new room will be created if another user starts an Online Battle.
+After a failed Online Battle the room will be deleted. The host is used for the timer countdown, so if the connection failes to the host the timer will stop and could create a "frozen" state.
+
+#### Information/Problems:
+
+- Online Battle uses UDP hole punching and opens port 50201?
+- `reflectorUri` seems related to that?
+- Timer countdown should be handled globally and not by one user
+- Game can freeze or can crash if someone (especially the host) leaves the matchmaking
+
+
## crossbeats REV.
### SDCA
@@ -253,20 +275,20 @@ python dbutils.py --game SDDT upgrade
| Version ID | Version Name |
|------------|-----------------|
-| 0 | Card Maker 1.34 |
+| 0 | Card Maker 1.30 |
| 1 | Card Maker 1.35 |
### Support status
-* Card Maker 1.34:
- * Chunithm New!!: Yes
- * maimai DX Universe: Yes
+* Card Maker 1.30:
+ * CHUNITHM NEW!!: Yes
+ * maimai DX UNiVERSE: Yes
* O.N.G.E.K.I. Bright: Yes
* Card Maker 1.35:
- * Chunithm New!!+: Yes
- * maimai DX Universe PLUS: Yes
+ * CHUNITHM SUN: Yes (NEW PLUS!! up to A032)
+ * maimai DX FESTiVAL: Yes (up to A035) (UNiVERSE PLUS up to A031)
* O.N.G.E.K.I. Bright Memory: Yes
@@ -285,19 +307,46 @@ python read.py --series SDED --version --binfolder titles/cm/cm_dat
python read.py --series SDDT --version --binfolder /path/to/game/folder --optfolder /path/to/game/option/folder
```
-Also make sure to import all maimai and Chunithm data as well:
+Also make sure to import all maimai DX and CHUNITHM data as well:
```shell
python read.py --series SDED --version --binfolder /path/to/cardmaker/CardMaker_Data
```
-The importer for Card Maker will import all required Gachas (Banners) and cards (for maimai/Chunithm) and the hardcoded
+The importer for Card Maker will import all required Gachas (Banners) and cards (for maimai DX/CHUNITHM) and the hardcoded
Cards for each Gacha (O.N.G.E.K.I. only).
**NOTE: Without executing the importer Card Maker WILL NOT work!**
-### O.N.G.E.K.I. Gachas
+### Config setup
+
+Make sure to update your `config/cardmaker.yaml` with the correct version for each game. To get the current version required to run a specific game, open every opt (Axxx) folder descending until you find all three folders:
+
+- `MU3`: O.N.G.E.K.I.
+- `MAI`: maimai DX
+- `CHU`: CHUNITHM
+
+Inside each folder is a `DataConfig.xml` file, for example:
+
+`MU3/DataConfig.xml`:
+```xml
+
+ 1
+ 35
+ 3
+
+```
+
+Now update your `config/cardmaker.yaml` with the correct version number, for example:
+
+```yaml
+version:
+ 1: # Card Maker 1.35
+ ongeki: 1.35.03
+```
+
+### O.N.G.E.K.I.
Gacha "無料ガチャ" can only pull from the free cards with the following probabilities: 94%: R, 5% SR and 1% chance of
getting an SSR card
@@ -310,20 +359,24 @@ and 3% chance of getting an SSR card
All other (limited) gachas can pull from every card added to ongeki_static_cards but with the promoted cards
(click on the green button under the banner) having a 10 times higher chance to get pulled
-### Chunithm Gachas
+### CHUNITHM
-All cards in Chunithm (basically just the characters) have the same rarity to it just pulls randomly from all cards
+All cards in CHUNITHM (basically just the characters) have the same rarity to it just pulls randomly from all cards
from a given gacha but made sure you cannot pull the same card twice in the same 5 times gacha roll.
+### maimai DX
+
+Printed maimai DX cards: Freedom (`cardTypeId=6`) or Gold Pass (`cardTypeId=4`) can now be selected during the login process. You can only have ONE Freedom and ONE Gold Pass active at a given time. The cards will expire after 15 days.
+
+Thanks GetzeAvenue for the `selectedCardList` rarity hint!
+
### Notes
-Card Maker 1.34 will only load an O.N.G.E.K.I. Bright profile (1.30). Card Maker 1.35 will only load an O.N.G.E.K.I.
+Card Maker 1.30-1.34 will only load an O.N.G.E.K.I. Bright profile (1.30). Card Maker 1.35+ will only load an O.N.G.E.K.I.
Bright Memory profile (1.35).
-The gachas inside the `ongeki.yaml` will make sure only the right gacha ids for the right CM version will be loaded.
+The gachas inside the `config/ongeki.yaml` will make sure only the right gacha ids for the right CM version will be loaded.
Gacha IDs up to 1140 will be loaded for CM 1.34 and all gachas will be loaded for CM 1.35.
-**NOTE: There is currently no way to load/use the (printed) maimai DX cards!**
-
## WACCA
### SDFE
@@ -366,3 +419,52 @@ Always make sure your database (tables) are up-to-date, to do so go to the `core
```shell
python dbutils.py --game SDFE upgrade
```
+
+## SAO
+
+### SDEW
+
+| Version ID | Version Name |
+|------------|---------------|
+| 0 | SAO |
+
+
+### Importer
+
+In order to use the importer locate your game installation folder and execute:
+
+```shell
+python read.py --series SDEW --version --binfolder /path/to/game/extractedassets
+```
+
+The importer for SAO will import all items, heroes, support skills and titles data.
+
+### Config
+
+Config file is located in `config/sao.yaml`.
+
+| Option | Info |
+|--------------------|-----------------------------------------------------------------------------|
+| `hostname` | Changes the server listening address for Mucha |
+| `port` | Changes the listing port |
+| `auto_register` | Allows the game to handle the automatic registration of new cards |
+
+
+### Database upgrade
+
+Always make sure your database (tables) are up-to-date, to do so go to the `core/data/schema/versions` folder and see which version is the latest, f.e. `SDEW_1_upgrade.sql`. In order to upgrade to version 3 in this case you need to perform all previous updates as well:
+
+```shell
+python dbutils.py --game SDEW upgrade
+```
+
+### Notes
+- Co-Op (matching) is not supported
+- Shop is not functionnal
+- Player title is currently static and cannot be changed in-game
+
+### Credits for SAO support:
+
+- Midorica - Limited Network Support
+- Dniel97 - Helping with network base
+- tungnotpunk - Source
\ No newline at end of file
diff --git a/example_config/cardmaker.yaml b/example_config/cardmaker.yaml
index a04dda5..fb17756 100644
--- a/example_config/cardmaker.yaml
+++ b/example_config/cardmaker.yaml
@@ -1,3 +1,13 @@
server:
enable: True
loglevel: "info"
+
+version:
+ 0:
+ ongeki: 1.30.01
+ chuni: 2.00.00
+ maimai: 1.20.00
+ 1:
+ ongeki: 1.35.03
+ chuni: 2.10.00
+ maimai: 1.30.00
\ No newline at end of file
diff --git a/example_config/chuni.yaml b/example_config/chuni.yaml
index bbac976..59db51e 100644
--- a/example_config/chuni.yaml
+++ b/example_config/chuni.yaml
@@ -15,6 +15,9 @@ version:
12:
rom: 2.05.00
data: 2.05.00
+ 13:
+ rom: 2.10.00
+ data: 2.10.00
crypto:
encrypted_only: False
\ No newline at end of file
diff --git a/example_config/pokken.yaml b/example_config/pokken.yaml
index 225e980..423d9d3 100644
--- a/example_config/pokken.yaml
+++ b/example_config/pokken.yaml
@@ -2,8 +2,11 @@ server:
hostname: "localhost"
enable: True
loglevel: "info"
- port: 9000
- port_stun: 9001
- port_turn: 9002
- port_admission: 9003
- auto_register: True
\ No newline at end of file
+ auto_register: True
+ enable_matching: False
+ stun_server_host: "stunserver.stunprotocol.org"
+ stun_server_port: 3478
+
+ports:
+ game: 9000
+ admission: 9001
diff --git a/example_config/sao.yaml b/example_config/sao.yaml
new file mode 100644
index 0000000..7e3ecf2
--- /dev/null
+++ b/example_config/sao.yaml
@@ -0,0 +1,6 @@
+server:
+ hostname: "localhost"
+ enable: True
+ loglevel: "info"
+ port: 9000
+ auto_register: True
\ No newline at end of file
diff --git a/readme.md b/readme.md
index ec25191..224fa5b 100644
--- a/readme.md
+++ b/readme.md
@@ -3,32 +3,36 @@ A network service emulator for games running SEGA'S ALL.NET service, and similar
# Supported games
Games listed below have been tested and confirmed working. Only game versions older then the version currently active in arcades, or games versions that have not recieved a major update in over one year, are supported.
-+ Chunithm
- + All versions up to New!! Plus
-+ Crossbeats Rev
++ CHUNITHM
+ + All versions up to SUN
+
++ crossbeats REV.
+ All versions + omnimix
+ maimai DX
- + All versions up to Festival
+ + All versions up to FESTiVAL
-+ Hatsune Miku Arcade
++ Hatsune Miku: Project DIVA Arcade
+ All versions
+ Card Maker
- + 1.34.xx
- + 1.35.xx
+ + 1.30
+ + 1.35
-+ Ongeki
++ O.N.G.E.K.I.
+ All versions up to Bright Memory
-+ Wacca
++ WACCA
+ Lily R
+ Reverse
-+ Pokken
++ POKKÉN TOURNAMENT
+ Final Online
++ Sword Art Online Arcade (partial support)
+ + Final
+
## Requirements
- python 3 (tested working with 3.9 and 3.10, other versions YMMV)
- pip
diff --git a/requirements.txt b/requirements.txt
index ebb17c9..6d37728 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -16,3 +16,4 @@ Routes
bcrypt
jinja2
protobuf
+autobahn
diff --git a/titles/chuni/__init__.py b/titles/chuni/__init__.py
index 89cd4f5..0c3cc79 100644
--- a/titles/chuni/__init__.py
+++ b/titles/chuni/__init__.py
@@ -7,4 +7,4 @@ index = ChuniServlet
database = ChuniData
reader = ChuniReader
game_codes = [ChuniConstants.GAME_CODE, ChuniConstants.GAME_CODE_NEW]
-current_schema_version = 3
+current_schema_version = 4
diff --git a/titles/chuni/base.py b/titles/chuni/base.py
index 0eaabff..689c2fe 100644
--- a/titles/chuni/base.py
+++ b/titles/chuni/base.py
@@ -44,13 +44,15 @@ class ChuniBase:
# check if a user already has some pogress and if not add the
# login bonus entry
user_login_bonus = self.data.item.get_login_bonus(
- user_id, self.version, preset["id"]
+ user_id, self.version, preset["presetId"]
)
if user_login_bonus is None:
- self.data.item.put_login_bonus(user_id, self.version, preset["id"])
+ self.data.item.put_login_bonus(
+ user_id, self.version, preset["presetId"]
+ )
# yeah i'm lazy
user_login_bonus = self.data.item.get_login_bonus(
- user_id, self.version, preset["id"]
+ user_id, self.version, preset["presetId"]
)
# skip the login bonus entirely if its already finished
@@ -66,13 +68,13 @@ class ChuniBase:
last_update_date = datetime.now()
all_login_boni = self.data.static.get_login_bonus(
- self.version, preset["id"]
+ self.version, preset["presetId"]
)
# skip the current bonus preset if no boni were found
if all_login_boni is None or len(all_login_boni) < 1:
self.logger.warn(
- f"No bonus entries found for bonus preset {preset['id']}"
+ f"No bonus entries found for bonus preset {preset['presetId']}"
)
continue
@@ -83,14 +85,14 @@ class ChuniBase:
if bonus_count > max_needed_days:
# assume that all login preset ids under 3000 needs to be
# looped, like 30 and 40 are looped, 40 does not work?
- if preset["id"] < 3000:
+ if preset["presetId"] < 3000:
bonus_count = 1
else:
is_finished = True
# grab the item for the corresponding day
login_item = self.data.static.get_login_bonus_by_required_days(
- self.version, preset["id"], bonus_count
+ self.version, preset["presetId"], bonus_count
)
if login_item is not None:
# now add the present to the database so the
@@ -108,7 +110,7 @@ class ChuniBase:
self.data.item.put_login_bonus(
user_id,
self.version,
- preset["id"],
+ preset["presetId"],
bonusCount=bonus_count,
lastUpdateDate=last_update_date,
isWatched=False,
@@ -156,12 +158,18 @@ class ChuniBase:
event_list = []
for evt_row in game_events:
- tmp = {}
- tmp["id"] = evt_row["eventId"]
- tmp["type"] = evt_row["type"]
- tmp["startDate"] = "2017-12-05 07:00:00.0"
- tmp["endDate"] = "2099-12-31 00:00:00.0"
- event_list.append(tmp)
+ event_list.append(
+ {
+ "id": evt_row["eventId"],
+ "type": evt_row["type"],
+ # actually use the startDate from the import so it
+ # properly shows all the events when new ones are imported
+ "startDate": datetime.strftime(
+ evt_row["startDate"], "%Y-%m-%d %H:%M:%S"
+ ),
+ "endDate": "2099-12-31 00:00:00",
+ }
+ )
return {
"type": data["type"],
@@ -228,29 +236,36 @@ class ChuniBase:
def handle_get_user_character_api_request(self, data: Dict) -> Dict:
characters = self.data.item.get_characters(data["userId"])
if characters is None:
- return {}
- next_idx = -1
+ return {
+ "userId": data["userId"],
+ "length": 0,
+ "nextIndex": -1,
+ "userCharacterList": [],
+ }
- characterList = []
- for x in range(int(data["nextIndex"]), len(characters)):
+ character_list = []
+ next_idx = int(data["nextIndex"])
+ max_ct = int(data["maxCount"])
+
+ for x in range(next_idx, len(characters)):
tmp = characters[x]._asdict()
tmp.pop("user")
tmp.pop("id")
- characterList.append(tmp)
+ character_list.append(tmp)
- if len(characterList) >= int(data["maxCount"]):
+ if len(character_list) >= max_ct:
break
- if len(characterList) >= int(data["maxCount"]) and len(characters) > int(
- data["maxCount"]
- ) + int(data["nextIndex"]):
- next_idx = int(data["maxCount"]) + int(data["nextIndex"]) + 1
+ if len(characters) >= next_idx + max_ct:
+ next_idx += max_ct
+ else:
+ next_idx = -1
return {
"userId": data["userId"],
- "length": len(characterList),
+ "length": len(character_list),
"nextIndex": next_idx,
- "userCharacterList": characterList,
+ "userCharacterList": character_list,
}
def handle_get_user_charge_api_request(self, data: Dict) -> Dict:
@@ -292,8 +307,8 @@ class ChuniBase:
if len(user_course_list) >= max_ct:
break
- if len(user_course_list) >= max_ct:
- next_idx = next_idx + max_ct
+ if len(user_course_list) >= next_idx + max_ct:
+ next_idx += max_ct
else:
next_idx = -1
@@ -347,12 +362,23 @@ class ChuniBase:
}
def handle_get_user_favorite_item_api_request(self, data: Dict) -> Dict:
+ user_fav_item_list = []
+
+ # still needs to be implemented on WebUI
+ # 1: Music, 3: Character
+ fav_list = self.data.item.get_all_favorites(
+ data["userId"], self.version, fav_kind=int(data["kind"])
+ )
+ if fav_list is not None:
+ for fav in fav_list:
+ user_fav_item_list.append({"id": fav["favId"]})
+
return {
"userId": data["userId"],
- "length": 0,
+ "length": len(user_fav_item_list),
"kind": data["kind"],
"nextIndex": -1,
- "userFavoriteItemList": [],
+ "userFavoriteItemList": user_fav_item_list,
}
def handle_get_user_favorite_music_api_request(self, data: Dict) -> Dict:
@@ -387,13 +413,13 @@ class ChuniBase:
xout = kind * 10000000000 + next_idx + len(items)
if len(items) < int(data["maxCount"]):
- nextIndex = 0
+ next_idx = 0
else:
- nextIndex = xout
+ next_idx = xout
return {
"userId": data["userId"],
- "nextIndex": nextIndex,
+ "nextIndex": next_idx,
"itemKind": kind,
"length": len(items),
"userItemList": items,
@@ -452,6 +478,7 @@ class ChuniBase:
"nextIndex": -1,
"userMusicList": [], # 240
}
+
song_list = []
next_idx = int(data["nextIndex"])
max_ct = int(data["maxCount"])
@@ -474,10 +501,10 @@ class ChuniBase:
if len(song_list) >= max_ct:
break
- if len(song_list) >= max_ct:
+ if len(song_list) >= next_idx + max_ct:
next_idx += max_ct
else:
- next_idx = 0
+ next_idx = -1
return {
"userId": data["userId"],
@@ -623,12 +650,15 @@ class ChuniBase:
self.data.profile.put_profile_data(
user_id, self.version, upsert["userData"][0]
)
+
if "userDataEx" in upsert:
self.data.profile.put_profile_data_ex(
user_id, self.version, upsert["userDataEx"][0]
)
+
if "userGameOption" in upsert:
self.data.profile.put_profile_option(user_id, upsert["userGameOption"][0])
+
if "userGameOptionEx" in upsert:
self.data.profile.put_profile_option_ex(
user_id, upsert["userGameOptionEx"][0]
@@ -672,6 +702,10 @@ class ChuniBase:
if "userPlaylogList" in upsert:
for playlog in upsert["userPlaylogList"]:
+ # convert the player names to utf-8
+ playlog["playedUserName1"] = self.read_wtf8(playlog["playedUserName1"])
+ playlog["playedUserName2"] = self.read_wtf8(playlog["playedUserName2"])
+ playlog["playedUserName3"] = self.read_wtf8(playlog["playedUserName3"])
self.data.score.put_playlog(user_id, playlog)
if "userTeamPoint" in upsert:
diff --git a/titles/chuni/const.py b/titles/chuni/const.py
index 6ab3cc3..b3a4cb5 100644
--- a/titles/chuni/const.py
+++ b/titles/chuni/const.py
@@ -17,21 +17,23 @@ class ChuniConstants:
VER_CHUNITHM_PARADISE = 10
VER_CHUNITHM_NEW = 11
VER_CHUNITHM_NEW_PLUS = 12
+ VER_CHUNITHM_SUN = 13
VERSION_NAMES = [
- "Chunithm",
- "Chunithm+",
- "Chunithm Air",
- "Chunithm Air+",
- "Chunithm Star",
- "Chunithm Star+",
- "Chunithm Amazon",
- "Chunithm Amazon+",
- "Chunithm Crystal",
- "Chunithm Crystal+",
- "Chunithm Paradise",
- "Chunithm New!!",
- "Chunithm New!!+",
+ "CHUNITHM",
+ "CHUNITHM PLUS",
+ "CHUNITHM AIR",
+ "CHUNITHM AIR PLUS",
+ "CHUNITHM STAR",
+ "CHUNITHM STAR PLUS",
+ "CHUNITHM AMAZON",
+ "CHUNITHM AMAZON PLUS",
+ "CHUNITHM CRYSTAL",
+ "CHUNITHM CRYSTAL PLUS",
+ "CHUNITHM PARADISE",
+ "CHUNITHM NEW!!",
+ "CHUNITHM NEW PLUS!!",
+ "CHUNITHM SUN"
]
@classmethod
diff --git a/titles/chuni/index.py b/titles/chuni/index.py
index a7545ba..5d185e9 100644
--- a/titles/chuni/index.py
+++ b/titles/chuni/index.py
@@ -29,6 +29,7 @@ from titles.chuni.crystalplus import ChuniCrystalPlus
from titles.chuni.paradise import ChuniParadise
from titles.chuni.new import ChuniNew
from titles.chuni.newplus import ChuniNewPlus
+from titles.chuni.sun import ChuniSun
class ChuniServlet:
@@ -55,6 +56,7 @@ class ChuniServlet:
ChuniParadise,
ChuniNew,
ChuniNewPlus,
+ ChuniSun,
]
self.logger = logging.getLogger("chuni")
@@ -96,15 +98,18 @@ class ChuniServlet:
]
for method in method_list:
method_fixed = inflection.camelize(method)[6:-7]
+ # number of iterations was changed to 70 in SUN
+ iter_count = 70 if version >= ChuniConstants.VER_CHUNITHM_SUN else 44
hash = PBKDF2(
method_fixed,
bytes.fromhex(keys[2]),
128,
- count=44,
+ count=iter_count,
hmac_hash_module=SHA1,
)
- self.hash_table[version][hash.hex()] = method_fixed
+ hashed_name = hash.hex()[:32] # truncate unused bytes like the game does
+ self.hash_table[version][hashed_name] = method_fixed
self.logger.debug(
f"Hashed v{version} method {method_fixed} with {bytes.fromhex(keys[2])} to get {hash.hex()}"
@@ -145,30 +150,32 @@ class ChuniServlet:
if version < 105: # 1.0
internal_ver = ChuniConstants.VER_CHUNITHM
- elif version >= 105 and version < 110: # Plus
+ elif version >= 105 and version < 110: # PLUS
internal_ver = ChuniConstants.VER_CHUNITHM_PLUS
- elif version >= 110 and version < 115: # Air
+ elif version >= 110 and version < 115: # AIR
internal_ver = ChuniConstants.VER_CHUNITHM_AIR
- elif version >= 115 and version < 120: # Air Plus
+ elif version >= 115 and version < 120: # AIR PLUS
internal_ver = ChuniConstants.VER_CHUNITHM_AIR_PLUS
- elif version >= 120 and version < 125: # Star
+ elif version >= 120 and version < 125: # STAR
internal_ver = ChuniConstants.VER_CHUNITHM_STAR
- elif version >= 125 and version < 130: # Star Plus
+ elif version >= 125 and version < 130: # STAR PLUS
internal_ver = ChuniConstants.VER_CHUNITHM_STAR_PLUS
- elif version >= 130 and version < 135: # Amazon
+ elif version >= 130 and version < 135: # AMAZON
internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON
- elif version >= 135 and version < 140: # Amazon Plus
+ elif version >= 135 and version < 140: # AMAZON PLUS
internal_ver = ChuniConstants.VER_CHUNITHM_AMAZON_PLUS
- elif version >= 140 and version < 145: # Crystal
+ elif version >= 140 and version < 145: # CRYSTAL
internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL
- elif version >= 145 and version < 150: # Crystal Plus
+ elif version >= 145 and version < 150: # CRYSTAL PLUS
internal_ver = ChuniConstants.VER_CHUNITHM_CRYSTAL_PLUS
- elif version >= 150 and version < 200: # Paradise
+ elif version >= 150 and version < 200: # PARADISE
internal_ver = ChuniConstants.VER_CHUNITHM_PARADISE
- elif version >= 200 and version < 205: # New
+ elif version >= 200 and version < 205: # NEW!!
internal_ver = ChuniConstants.VER_CHUNITHM_NEW
- elif version >= 205 and version < 210: # New Plus
+ elif version >= 205 and version < 210: # NEW PLUS!!
internal_ver = ChuniConstants.VER_CHUNITHM_NEW_PLUS
+ elif version >= 210: # SUN
+ internal_ver = ChuniConstants.VER_CHUNITHM_SUN
if all(c in string.hexdigits for c in endpoint) and len(endpoint) == 32:
# If we get a 32 character long hex string, it's a hash and we're
diff --git a/titles/chuni/new.py b/titles/chuni/new.py
index 67b6fcc..40dee9b 100644
--- a/titles/chuni/new.py
+++ b/titles/chuni/new.py
@@ -23,41 +23,44 @@ class ChuniNew(ChuniBase):
self.version = ChuniConstants.VER_CHUNITHM_NEW
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
+ # use UTC time and convert it to JST time by adding +9
+ # matching therefore starts one hour before and lasts for 8 hours
match_start = datetime.strftime(
- datetime.now() - timedelta(hours=10), self.date_time_format
+ datetime.utcnow() + timedelta(hours=8), self.date_time_format
)
match_end = datetime.strftime(
- datetime.now() + timedelta(hours=10), self.date_time_format
+ datetime.utcnow() + timedelta(hours=16), self.date_time_format
)
reboot_start = datetime.strftime(
- datetime.now() - timedelta(hours=11), self.date_time_format
+ datetime.utcnow() + timedelta(hours=6), self.date_time_format
)
reboot_end = datetime.strftime(
- datetime.now() - timedelta(hours=10), self.date_time_format
+ datetime.utcnow() + timedelta(hours=7), self.date_time_format
)
return {
"gameSetting": {
- "isMaintenance": "false",
+ "isMaintenance": False,
"requestInterval": 10,
"rebootStartTime": reboot_start,
"rebootEndTime": reboot_end,
- "isBackgroundDistribute": "false",
+ "isBackgroundDistribute": False,
"maxCountCharacter": 300,
"maxCountItem": 300,
"maxCountMusic": 300,
"matchStartTime": match_start,
"matchEndTime": match_end,
- "matchTimeLimit": 99,
+ "matchTimeLimit": 60,
"matchErrorLimit": 9999,
"romVersion": self.game_cfg.version.version(self.version)["rom"],
"dataVersion": self.game_cfg.version.version(self.version)["data"],
"matchingUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
"matchingUriX": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
+ # might be really important for online battle to connect the cabs via UDP port 50201
"udpHolePunchUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
"reflectorUri": f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/200/ChuniServlet/",
},
- "isDumpUpload": "false",
- "isAou": "false",
+ "isDumpUpload": False,
+ "isAou": False,
}
def handle_remove_token_api_request(self, data: Dict) -> Dict:
@@ -468,3 +471,162 @@ class ChuniNew(ChuniBase):
self.data.item.put_user_print_state(user_id, id=order_id, hasCompleted=True)
return {"returnCode": "1", "apiName": "CMUpsertUserPrintCancelApi"}
+
+ def handle_ping_request(self, data: Dict) -> Dict:
+ # matchmaking ping request
+ return {"returnCode": "1"}
+
+ def handle_begin_matching_api_request(self, data: Dict) -> Dict:
+ room_id = 1
+ # check if there is a free matching room
+ matching_room = self.data.item.get_oldest_free_matching(self.version)
+
+ if matching_room is None:
+ # grab the latest roomId and add 1 for the new room
+ newest_matching = self.data.item.get_newest_matching(self.version)
+ if newest_matching is not None:
+ room_id = newest_matching["roomId"] + 1
+
+ # fix userName WTF8
+ new_member = data["matchingMemberInfo"]
+ new_member["userName"] = self.read_wtf8(new_member["userName"])
+
+ # create the new room with room_id and the current user id (host)
+ # user id is required for the countdown later on
+ self.data.item.put_matching(
+ self.version, room_id, [new_member], user_id=new_member["userId"]
+ )
+
+ # get the newly created matching room
+ matching_room = self.data.item.get_matching(self.version, room_id)
+ else:
+ # a room already exists, so just add the new member to it
+ matching_member_list = matching_room["matchingMemberInfoList"]
+ # fix userName WTF8
+ new_member = data["matchingMemberInfo"]
+ new_member["userName"] = self.read_wtf8(new_member["userName"])
+ matching_member_list.append(new_member)
+
+ # add the updated room to the database, make sure to set isFull correctly!
+ self.data.item.put_matching(
+ self.version,
+ matching_room["roomId"],
+ matching_member_list,
+ user_id=matching_room["user"],
+ is_full=True if len(matching_member_list) >= 4 else False,
+ )
+
+ matching_wait = {
+ "isFinish": False,
+ "restMSec": matching_room["restMSec"], # in sec
+ "pollingInterval": 1, # in sec
+ "matchingMemberInfoList": matching_room["matchingMemberInfoList"],
+ }
+
+ return {"roomId": 1, "matchingWaitState": matching_wait}
+
+ def handle_end_matching_api_request(self, data: Dict) -> Dict:
+ matching_room = self.data.item.get_matching(self.version, data["roomId"])
+ members = matching_room["matchingMemberInfoList"]
+
+ # only set the host user to role 1 every other to 0?
+ role_list = [
+ {"role": 1} if m["userId"] == matching_room["user"] else {"role": 0}
+ for m in members
+ ]
+
+ self.data.item.put_matching(
+ self.version,
+ matching_room["roomId"],
+ members,
+ user_id=matching_room["user"],
+ rest_sec=0, # make sure to always set 0
+ is_full=True, # and full, so no one can join
+ )
+
+ return {
+ "matchingResult": 1, # needs to be 1 for successful matching
+ "matchingMemberInfoList": members,
+ # no idea, maybe to differentiate between CPUs and real players?
+ "matchingMemberRoleList": role_list,
+ # TCP/UDP connection?
+ "reflectorUri": f"{self.core_cfg.title.hostname}",
+ }
+
+ def handle_remove_matching_member_api_request(self, data: Dict) -> Dict:
+ # get all matching rooms, because Chuni only returns the userId
+ # not the actual roomId
+ matching_rooms = self.data.item.get_all_matchings(self.version)
+ if matching_rooms is None:
+ return {"returnCode": "1"}
+
+ for room in matching_rooms:
+ old_members = room["matchingMemberInfoList"]
+ new_members = [m for m in old_members if m["userId"] != data["userId"]]
+
+ # if nothing changed go to the next room
+ if len(old_members) == len(new_members):
+ continue
+
+ # if the last user got removed, delete the matching room
+ if len(new_members) <= 0:
+ self.data.item.delete_matching(self.version, room["roomId"])
+ else:
+ # remove the user from the room
+ self.data.item.put_matching(
+ self.version,
+ room["roomId"],
+ new_members,
+ user_id=room["user"],
+ rest_sec=room["restMSec"],
+ )
+
+ return {"returnCode": "1"}
+
+ def handle_get_matching_state_api_request(self, data: Dict) -> Dict:
+ polling_interval = 1
+ # get the current active room
+ matching_room = self.data.item.get_matching(self.version, data["roomId"])
+ members = matching_room["matchingMemberInfoList"]
+ rest_sec = matching_room["restMSec"]
+
+ # grab the current member
+ current_member = data["matchingMemberInfo"]
+
+ # only the host user can decrease the countdown
+ if matching_room["user"] == int(current_member["userId"]):
+ # cap the restMSec to 0
+ if rest_sec > 0:
+ rest_sec -= polling_interval
+ else:
+ rest_sec = 0
+
+ # update the members in order to recieve messages
+ for i, member in enumerate(members):
+ if member["userId"] == current_member["userId"]:
+ # replace the old user data with the current user data,
+ # also parse WTF-8 everytime
+ current_member["userName"] = self.read_wtf8(current_member["userName"])
+ members[i] = current_member
+
+ self.data.item.put_matching(
+ self.version,
+ data["roomId"],
+ members,
+ rest_sec=rest_sec,
+ user_id=matching_room["user"],
+ )
+
+ # only add the other members to the list
+ diff_members = [m for m in members if m["userId"] != current_member["userId"]]
+
+ matching_wait = {
+ # makes no difference? Always use False?
+ "isFinish": True if rest_sec == 0 else False,
+ "restMSec": rest_sec,
+ "pollingInterval": polling_interval,
+ # the current user needs to be the first one?
+ "matchingMemberInfoList": [current_member] + diff_members,
+ }
+
+ return {"matchingWaitState": matching_wait}
diff --git a/titles/chuni/newplus.py b/titles/chuni/newplus.py
index 4faf47a..bbe1419 100644
--- a/titles/chuni/newplus.py
+++ b/titles/chuni/newplus.py
@@ -36,6 +36,6 @@ class ChuniNewPlus(ChuniNew):
def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
user_data = super().handle_cm_get_user_preview_api_request(data)
- # hardcode lastDataVersion for CardMaker 1.35
+ # hardcode lastDataVersion for CardMaker 1.35 A028
user_data["lastDataVersion"] = "2.05.00"
return user_data
diff --git a/titles/chuni/schema/item.py b/titles/chuni/schema/item.py
index 4ffcf93..94c4fd8 100644
--- a/titles/chuni/schema/item.py
+++ b/titles/chuni/schema/item.py
@@ -1,5 +1,12 @@
from typing import Dict, List, Optional
-from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
+from sqlalchemy import (
+ Table,
+ Column,
+ UniqueConstraint,
+ PrimaryKeyConstraint,
+ and_,
+ delete,
+)
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
from sqlalchemy.engine.base import Connection
from sqlalchemy.schema import ForeignKey
@@ -203,8 +210,141 @@ login_bonus = Table(
mysql_charset="utf8mb4",
)
+favorite = Table(
+ "chuni_item_favorite",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("version", Integer, nullable=False),
+ Column("favId", Integer, nullable=False),
+ Column("favKind", Integer, nullable=False, server_default="1"),
+ UniqueConstraint("version", "user", "favId", name="chuni_item_favorite_uk"),
+ mysql_charset="utf8mb4",
+)
+
+matching = Table(
+ "chuni_item_matching",
+ metadata,
+ Column("roomId", Integer, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("version", Integer, nullable=False),
+ Column("restMSec", Integer, nullable=False, server_default="60"),
+ Column("isFull", Boolean, nullable=False, server_default="0"),
+ PrimaryKeyConstraint("roomId", "version", name="chuni_item_matching_pk"),
+ Column("matchingMemberInfoList", JSON, nullable=False),
+ mysql_charset="utf8mb4",
+)
+
class ChuniItemData(BaseData):
+ def get_oldest_free_matching(self, version: int) -> Optional[Row]:
+ sql = matching.select(
+ and_(
+ matching.c.version == version,
+ matching.c.isFull == False
+ )
+ ).order_by(matching.c.roomId.asc())
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_newest_matching(self, version: int) -> Optional[Row]:
+ sql = matching.select(
+ and_(
+ matching.c.version == version
+ )
+ ).order_by(matching.c.roomId.desc())
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_all_matchings(self, version: int) -> Optional[List[Row]]:
+ sql = matching.select(
+ and_(
+ matching.c.version == version
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
+ def get_matching(self, version: int, room_id: int) -> Optional[Row]:
+ sql = matching.select(
+ and_(matching.c.version == version, matching.c.roomId == room_id)
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def put_matching(
+ self,
+ version: int,
+ room_id: int,
+ matching_member_info_list: list,
+ user_id: int = None,
+ rest_sec: int = 60,
+ is_full: bool = False
+ ) -> Optional[int]:
+ sql = insert(matching).values(
+ roomId=room_id,
+ version=version,
+ restMSec=rest_sec,
+ user=user_id,
+ isFull=is_full,
+ matchingMemberInfoList=matching_member_info_list,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ restMSec=rest_sec, matchingMemberInfoList=matching_member_info_list
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def delete_matching(self, version: int, room_id: int):
+ sql = delete(matching).where(
+ and_(matching.c.roomId == room_id, matching.c.version == version)
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def get_all_favorites(
+ self, user_id: int, version: int, fav_kind: int = 1
+ ) -> Optional[List[Row]]:
+ sql = favorite.select(
+ and_(
+ favorite.c.version == version,
+ favorite.c.user == user_id,
+ favorite.c.favKind == fav_kind,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
def put_login_bonus(
self, user_id: int, version: int, preset_id: int, **login_bonus_data
) -> Optional[int]:
diff --git a/titles/chuni/schema/profile.py b/titles/chuni/schema/profile.py
index e35769c..f8edc33 100644
--- a/titles/chuni/schema/profile.py
+++ b/titles/chuni/schema/profile.py
@@ -89,8 +89,6 @@ profile = Table(
Integer,
ForeignKey("chuni_profile_team.id", ondelete="SET NULL", onupdate="SET NULL"),
),
- Column("avatarBack", Integer, server_default="0"),
- Column("avatarFace", Integer, server_default="0"),
Column("eliteRankPoint", Integer, server_default="0"),
Column("stockedGridCount", Integer, server_default="0"),
Column("netBattleLoseCount", Integer, server_default="0"),
@@ -98,10 +96,8 @@ profile = Table(
Column("netBattle4thCount", Integer, server_default="0"),
Column("overPowerRate", Integer, server_default="0"),
Column("battleRewardStatus", Integer, server_default="0"),
- Column("avatarPoint", Integer, server_default="0"),
Column("netBattle1stCount", Integer, server_default="0"),
Column("charaIllustId", Integer, server_default="0"),
- Column("avatarItem", Integer, server_default="0"),
Column("userNameEx", String(8), server_default=""),
Column("netBattleWinCount", Integer, server_default="0"),
Column("netBattleCorrection", Integer, server_default="0"),
@@ -112,7 +108,6 @@ profile = Table(
Column("netBattle3rdCount", Integer, server_default="0"),
Column("netBattleConsecutiveWinCount", Integer, server_default="0"),
Column("overPowerLowerRank", Integer, server_default="0"),
- Column("avatarWear", Integer, server_default="0"),
Column("classEmblemBase", Integer, server_default="0"),
Column("battleRankPoint", Integer, server_default="0"),
Column("netBattle2ndCount", Integer, server_default="0"),
@@ -120,13 +115,19 @@ profile = Table(
Column("skillId", Integer, server_default="0"),
Column("lastCountryCode", String(5), server_default="JPN"),
Column("isNetBattleHost", Boolean, server_default="0"),
- Column("avatarFront", Integer, server_default="0"),
- Column("avatarSkin", Integer, server_default="0"),
Column("battleRewardCount", Integer, server_default="0"),
Column("battleRewardIndex", Integer, server_default="0"),
Column("netBattlePlayCount", Integer, server_default="0"),
Column("exMapLoopCount", Integer, server_default="0"),
Column("netBattleEndState", Integer, server_default="0"),
+ Column("rankUpChallengeResults", JSON),
+ Column("avatarBack", Integer, server_default="0"),
+ Column("avatarFace", Integer, server_default="0"),
+ Column("avatarPoint", Integer, server_default="0"),
+ Column("avatarItem", Integer, server_default="0"),
+ Column("avatarWear", Integer, server_default="0"),
+ Column("avatarFront", Integer, server_default="0"),
+ Column("avatarSkin", Integer, server_default="0"),
Column("avatarHead", Integer, server_default="0"),
UniqueConstraint("user", "version", name="chuni_profile_profile_uk"),
mysql_charset="utf8mb4",
@@ -417,8 +418,8 @@ class ChuniProfileData(BaseData):
sql = (
select([profile, option])
.join(option, profile.c.user == option.c.user)
- .filter(and_(profile.c.user == aime_id, profile.c.version == version))
- )
+ .filter(and_(profile.c.user == aime_id, profile.c.version <= version))
+ ).order_by(profile.c.version.desc())
result = self.execute(sql)
if result is None:
@@ -429,9 +430,9 @@ class ChuniProfileData(BaseData):
sql = select(profile).where(
and_(
profile.c.user == aime_id,
- profile.c.version == version,
+ profile.c.version <= version,
)
- )
+ ).order_by(profile.c.version.desc())
result = self.execute(sql)
if result is None:
@@ -461,9 +462,9 @@ class ChuniProfileData(BaseData):
sql = select(profile_ex).where(
and_(
profile_ex.c.user == aime_id,
- profile_ex.c.version == version,
+ profile_ex.c.version <= version,
)
- )
+ ).order_by(profile_ex.c.version.desc())
result = self.execute(sql)
if result is None:
diff --git a/titles/chuni/schema/score.py b/titles/chuni/schema/score.py
index 6a94813..203aa11 100644
--- a/titles/chuni/schema/score.py
+++ b/titles/chuni/schema/score.py
@@ -134,7 +134,9 @@ playlog = Table(
Column("charaIllustId", Integer),
Column("romVersion", String(255)),
Column("judgeHeaven", Integer),
- mysql_charset="utf8mb4",
+ Column("regionId", Integer),
+ Column("machineType", Integer),
+ mysql_charset="utf8mb4"
)
diff --git a/titles/chuni/schema/static.py b/titles/chuni/schema/static.py
index 4537518..85d0397 100644
--- a/titles/chuni/schema/static.py
+++ b/titles/chuni/schema/static.py
@@ -1,11 +1,19 @@
from typing import Dict, List, Optional
-from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
+from sqlalchemy import (
+ ForeignKeyConstraint,
+ Table,
+ Column,
+ UniqueConstraint,
+ PrimaryKeyConstraint,
+ and_,
+)
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, Float
from sqlalchemy.engine.base import Connection
from sqlalchemy.engine import Row
from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select
from sqlalchemy.dialects.mysql import insert
+from datetime import datetime
from core.data.schema import BaseData, metadata
@@ -17,6 +25,7 @@ events = Table(
Column("eventId", Integer),
Column("type", Integer),
Column("name", String(255)),
+ Column("startDate", TIMESTAMP, server_default=func.now()),
Column("enabled", Boolean, server_default="1"),
UniqueConstraint("version", "eventId", name="chuni_static_events_uk"),
mysql_charset="utf8mb4",
@@ -125,11 +134,13 @@ gacha_cards = Table(
login_bonus_preset = Table(
"chuni_static_login_bonus_preset",
metadata,
- Column("id", Integer, primary_key=True, nullable=False),
+ Column("presetId", Integer, nullable=False),
Column("version", Integer, nullable=False),
Column("presetName", String(255), nullable=False),
Column("isEnabled", Boolean, server_default="1"),
- UniqueConstraint("version", "id", name="chuni_static_login_bonus_preset_uk"),
+ PrimaryKeyConstraint(
+ "presetId", "version", name="chuni_static_login_bonus_preset_pk"
+ ),
mysql_charset="utf8mb4",
)
@@ -138,15 +149,7 @@ login_bonus = Table(
metadata,
Column("id", Integer, primary_key=True, nullable=False),
Column("version", Integer, nullable=False),
- Column(
- "presetId",
- ForeignKey(
- "chuni_static_login_bonus_preset.id",
- ondelete="cascade",
- onupdate="cascade",
- ),
- nullable=False,
- ),
+ Column("presetId", Integer, nullable=False),
Column("loginBonusId", Integer, nullable=False),
Column("loginBonusName", String(255), nullable=False),
Column("presentId", Integer, nullable=False),
@@ -157,6 +160,16 @@ login_bonus = Table(
UniqueConstraint(
"version", "presetId", "loginBonusId", name="chuni_static_login_bonus_uk"
),
+ ForeignKeyConstraint(
+ ["presetId", "version"],
+ [
+ "chuni_static_login_bonus_preset.presetId",
+ "chuni_static_login_bonus_preset.version",
+ ],
+ onupdate="CASCADE",
+ ondelete="CASCADE",
+ name="chuni_static_login_bonus_ibfk_1",
+ ),
mysql_charset="utf8mb4",
)
@@ -236,7 +249,7 @@ class ChuniStaticData(BaseData):
self, version: int, preset_id: int, preset_name: str, is_enabled: bool
) -> Optional[int]:
sql = insert(login_bonus_preset).values(
- id=preset_id,
+ presetId=preset_id,
version=version,
presetName=preset_name,
isEnabled=is_enabled,
@@ -416,6 +429,14 @@ class ChuniStaticData(BaseData):
return None
return result.fetchall()
+ def get_music(self, version: int) -> Optional[List[Row]]:
+ sql = music.select(music.c.version <= version)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
def get_music_chart(
self, version: int, song_id: int, chart_id: int
) -> Optional[List[Row]]:
diff --git a/titles/chuni/sun.py b/titles/chuni/sun.py
new file mode 100644
index 0000000..b56fa29
--- /dev/null
+++ b/titles/chuni/sun.py
@@ -0,0 +1,37 @@
+from typing import Dict, Any
+
+from core.config import CoreConfig
+from titles.chuni.newplus import ChuniNewPlus
+from titles.chuni.const import ChuniConstants
+from titles.chuni.config import ChuniConfig
+
+
+class ChuniSun(ChuniNewPlus):
+ def __init__(self, core_cfg: CoreConfig, game_cfg: ChuniConfig) -> None:
+ super().__init__(core_cfg, game_cfg)
+ self.version = ChuniConstants.VER_CHUNITHM_SUN
+
+ def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
+ ret = super().handle_get_game_setting_api_request(data)
+ ret["gameSetting"]["romVersion"] = self.game_cfg.version.version(self.version)["rom"]
+ ret["gameSetting"]["dataVersion"] = self.game_cfg.version.version(self.version)["data"]
+ ret["gameSetting"][
+ "matchingUri"
+ ] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
+ ret["gameSetting"][
+ "matchingUriX"
+ ] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
+ ret["gameSetting"][
+ "udpHolePunchUri"
+ ] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
+ ret["gameSetting"][
+ "reflectorUri"
+ ] = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}/SDHD/210/ChuniServlet/"
+ return ret
+
+ def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
+ user_data = super().handle_cm_get_user_preview_api_request(data)
+
+ # hardcode lastDataVersion for CardMaker 1.35 A032
+ user_data["lastDataVersion"] = "2.10.00"
+ return user_data
diff --git a/titles/cm/base.py b/titles/cm/base.py
index ff38489..dae6ecb 100644
--- a/titles/cm/base.py
+++ b/titles/cm/base.py
@@ -23,19 +23,40 @@ class CardMakerBase:
self.game = CardMakerConstants.GAME_CODE
self.version = CardMakerConstants.VER_CARD_MAKER
+ @staticmethod
+ def _parse_int_ver(version: str) -> str:
+ return version.replace(".", "")[:3]
+
def handle_get_game_connect_api_request(self, data: Dict) -> Dict:
if self.core_cfg.server.is_develop:
uri = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}"
else:
uri = f"http://{self.core_cfg.title.hostname}"
- # CHUNITHM = 0, maimai = 1, ONGEKI = 2
+ # grab the dict with all games version numbers from user config
+ games_ver = self.game_cfg.version.version(self.version)
+
return {
"length": 3,
"gameConnectList": [
- {"modelKind": 0, "type": 1, "titleUri": f"{uri}/SDHD/200/"},
- {"modelKind": 1, "type": 1, "titleUri": f"{uri}/SDEZ/120/"},
- {"modelKind": 2, "type": 1, "titleUri": f"{uri}/SDDT/130/"},
+ # CHUNITHM
+ {
+ "modelKind": 0,
+ "type": 1,
+ "titleUri": f"{uri}/SDHD/{self._parse_int_ver(games_ver['chuni'])}/",
+ },
+ # maimai DX
+ {
+ "modelKind": 1,
+ "type": 1,
+ "titleUri": f"{uri}/SDEZ/{self._parse_int_ver(games_ver['maimai'])}/",
+ },
+ # ONGEKI
+ {
+ "modelKind": 2,
+ "type": 1,
+ "titleUri": f"{uri}/SDDT/{self._parse_int_ver(games_ver['ongeki'])}/",
+ },
],
}
@@ -47,12 +68,15 @@ class CardMakerBase:
datetime.now() + timedelta(hours=4), self.date_time_format
)
+ # grab the dict with all games version numbers from user config
+ games_ver = self.game_cfg.version.version(self.version)
+
return {
"gameSetting": {
"dataVersion": "1.30.00",
- "ongekiCmVersion": "1.30.01",
- "chuniCmVersion": "2.00.00",
- "maimaiCmVersion": "1.20.00",
+ "ongekiCmVersion": games_ver["ongeki"],
+ "chuniCmVersion": games_ver["chuni"],
+ "maimaiCmVersion": games_ver["maimai"],
"requestInterval": 10,
"rebootStartTime": reboot_start,
"rebootEndTime": reboot_end,
diff --git a/titles/cm/cm135.py b/titles/cm/cm135.py
index 782f07a..e134974 100644
--- a/titles/cm/cm135.py
+++ b/titles/cm/cm135.py
@@ -1,8 +1,4 @@
-from datetime import date, datetime, timedelta
-from typing import Any, Dict, List
-import json
-import logging
-from enum import Enum
+from typing import Dict
from core.config import CoreConfig
from core.data.cache import cached
@@ -16,23 +12,7 @@ class CardMaker135(CardMakerBase):
super().__init__(core_cfg, game_cfg)
self.version = CardMakerConstants.VER_CARD_MAKER_135
- def handle_get_game_connect_api_request(self, data: Dict) -> Dict:
- ret = super().handle_get_game_connect_api_request(data)
- if self.core_cfg.server.is_develop:
- uri = f"http://{self.core_cfg.title.hostname}:{self.core_cfg.title.port}"
- else:
- uri = f"http://{self.core_cfg.title.hostname}"
-
- ret["gameConnectList"][0]["titleUri"] = f"{uri}/SDHD/205/"
- ret["gameConnectList"][1]["titleUri"] = f"{uri}/SDEZ/125/"
- ret["gameConnectList"][2]["titleUri"] = f"{uri}/SDDT/135/"
-
- return ret
-
def handle_get_game_setting_api_request(self, data: Dict) -> Dict:
ret = super().handle_get_game_setting_api_request(data)
ret["gameSetting"]["dataVersion"] = "1.35.00"
- ret["gameSetting"]["ongekiCmVersion"] = "1.35.03"
- ret["gameSetting"]["chuniCmVersion"] = "2.05.00"
- ret["gameSetting"]["maimaiCmVersion"] = "1.25.00"
return ret
diff --git a/titles/cm/config.py b/titles/cm/config.py
index ea96ca1..8bb23ec 100644
--- a/titles/cm/config.py
+++ b/titles/cm/config.py
@@ -1,3 +1,4 @@
+from typing import Dict
from core.config import CoreConfig
@@ -20,6 +21,21 @@ class CardMakerServerConfig:
)
+class CardMakerVersionConfig:
+ def __init__(self, parent_config: "CardMakerConfig") -> None:
+ self.__config = parent_config
+
+ def version(self, version: int) -> Dict:
+ """
+ in the form of:
+ 1: {"ongeki": 1.30.01, "chuni": 2.00.00, "maimai": 1.20.00}
+ """
+ return CoreConfig.get_config_field(
+ self.__config, "cardmaker", "version", default={}
+ )[version]
+
+
class CardMakerConfig(dict):
def __init__(self) -> None:
self.server = CardMakerServerConfig(self)
+ self.version = CardMakerVersionConfig(self)
diff --git a/titles/cm/const.py b/titles/cm/const.py
index 09f289e..5bb6d1f 100644
--- a/titles/cm/const.py
+++ b/titles/cm/const.py
@@ -6,7 +6,7 @@ class CardMakerConstants:
VER_CARD_MAKER = 0
VER_CARD_MAKER_135 = 1
- VERSION_NAMES = ("Card Maker 1.34", "Card Maker 1.35")
+ VERSION_NAMES = ("Card Maker 1.30", "Card Maker 1.35")
@classmethod
def game_ver_to_string(cls, ver: int):
diff --git a/titles/cm/index.py b/titles/cm/index.py
index 74d3a0d..3bde49c 100644
--- a/titles/cm/index.py
+++ b/titles/cm/index.py
@@ -30,7 +30,7 @@ class CardMakerServlet:
self.versions = [
CardMakerBase(core_cfg, self.game_cfg),
- CardMaker135(core_cfg, self.game_cfg),
+ CardMaker135(core_cfg, self.game_cfg)
]
self.logger = logging.getLogger("cardmaker")
@@ -89,7 +89,7 @@ class CardMakerServlet:
if version >= 130 and version < 135: # Card Maker
internal_ver = CardMakerConstants.VER_CARD_MAKER
- elif version >= 135 and version < 136: # Card Maker 1.35
+ elif version >= 135 and version < 140: # Card Maker 1.35
internal_ver = CardMakerConstants.VER_CARD_MAKER_135
if all(c in string.hexdigits for c in endpoint) and len(endpoint) == 32:
diff --git a/titles/cxb/index.py b/titles/cxb/index.py
index 0c38d55..0ef8667 100644
--- a/titles/cxb/index.py
+++ b/titles/cxb/index.py
@@ -103,7 +103,7 @@ class CxbServlet(resource.Resource):
else:
self.logger.info(f"Ready on port {self.game_cfg.server.port}")
- def render_POST(self, request: Request):
+ def render_POST(self, request: Request, version: int, endpoint: str):
version = 0
internal_ver = 0
func_to_find = ""
diff --git a/titles/idz/userdb.py b/titles/idz/userdb.py
index 2f70ba4..2ac765e 100644
--- a/titles/idz/userdb.py
+++ b/titles/idz/userdb.py
@@ -83,7 +83,13 @@ class IDZUserDBProtocol(Protocol):
def dataReceived(self, data: bytes) -> None:
self.logger.debug(f"Receive data {data.hex()}")
crypt = AES.new(self.static_key, AES.MODE_ECB)
- data_dec = crypt.decrypt(data)
+
+ try:
+ data_dec = crypt.decrypt(data)
+
+ except Exception as e:
+ self.logger.error(f"Failed to decrypt UserDB request from {self.transport.getPeer().host} because {e} - {data.hex()}")
+
self.logger.debug(f"Decrypt data {data_dec.hex()}")
magic = struct.unpack_from(" Dict:
- songs = self.data.score.get_best_scores(data["userId"])
+ user_id = data.get("userId", 0)
+ next_index = data.get("nextIndex", 0)
+ max_ct = data.get("maxCount", 50)
+ upper_lim = next_index + max_ct
music_detail_list = []
- next_index = 0
- if songs is not None:
- for song in songs:
- tmp = song._asdict()
- tmp.pop("id")
- tmp.pop("user")
- music_detail_list.append(tmp)
+ if user_id <= 0:
+ self.logger.warn("handle_get_user_music_api_request: Could not find userid in data, or userId is 0")
+ return {}
+
+ songs = self.data.score.get_best_scores(user_id)
+ if songs is None:
+ self.logger.debug("handle_get_user_music_api_request: get_best_scores returned None!")
+ return {
+ "userId": data["userId"],
+ "nextIndex": 0,
+ "userMusicList": [],
+ }
- if len(music_detail_list) == data["maxCount"]:
- next_index = data["maxCount"] + data["nextIndex"]
- break
+ num_user_songs = len(songs)
+ for x in range(next_index, upper_lim):
+ if num_user_songs <= x:
+ break
+
+ tmp = songs[x]._asdict()
+ tmp.pop("id")
+ tmp.pop("user")
+ music_detail_list.append(tmp)
+
+ next_index = 0 if len(music_detail_list) < max_ct or num_user_songs == upper_lim else upper_lim
+ self.logger.info(f"Send songs {next_index}-{upper_lim} ({len(music_detail_list)}) out of {num_user_songs} for user {user_id} (next idx {next_index})")
return {
"userId": data["userId"],
"nextIndex": next_index,
diff --git a/titles/mai2/const.py b/titles/mai2/const.py
index d8f5941..6e9a070 100644
--- a/titles/mai2/const.py
+++ b/titles/mai2/const.py
@@ -71,9 +71,9 @@ class Mai2Constants:
"maimai DX PLUS",
"maimai DX Splash",
"maimai DX Splash PLUS",
- "maimai DX Universe",
- "maimai DX Universe PLUS",
- "maimai DX Festival",
+ "maimai DX UNiVERSE",
+ "maimai DX UNiVERSE PLUS",
+ "maimai DX FESTiVAL",
)
@classmethod
diff --git a/titles/mai2/schema/item.py b/titles/mai2/schema/item.py
index 6280bbb..6b70ed1 100644
--- a/titles/mai2/schema/item.py
+++ b/titles/mai2/schema/item.py
@@ -39,8 +39,8 @@ card = Table(
Column("cardTypeId", Integer, nullable=False),
Column("charaId", Integer, nullable=False),
Column("mapId", Integer, nullable=False),
- Column("startDate", TIMESTAMP, server_default="2018-01-01 00:00:00.0"),
- Column("endDate", TIMESTAMP, server_default="2038-01-01 00:00:00.0"),
+ Column("startDate", TIMESTAMP, nullable=False, server_default=func.now()),
+ Column("endDate", TIMESTAMP, nullable=False),
UniqueConstraint("user", "cardId", "cardTypeId", name="mai2_item_card_uk"),
mysql_charset="utf8mb4",
)
@@ -444,6 +444,8 @@ class Mai2ItemData(BaseData):
card_kind: int,
chara_id: int,
map_id: int,
+ start_date: datetime,
+ end_date: datetime,
) -> Optional[Row]:
sql = insert(card).values(
user=user_id,
@@ -451,9 +453,13 @@ class Mai2ItemData(BaseData):
cardTypeId=card_kind,
charaId=chara_id,
mapId=map_id,
+ startDate=start_date,
+ endDate=end_date,
)
- conflict = sql.on_duplicate_key_update(charaId=chara_id, mapId=map_id)
+ conflict = sql.on_duplicate_key_update(
+ charaId=chara_id, mapId=map_id, startDate=start_date, endDate=end_date
+ )
result = self.execute(conflict)
if result is None:
diff --git a/titles/mai2/schema/score.py b/titles/mai2/schema/score.py
index 0f7f239..85dff16 100644
--- a/titles/mai2/schema/score.py
+++ b/titles/mai2/schema/score.py
@@ -7,6 +7,7 @@ from sqlalchemy.engine import Row
from sqlalchemy.dialects.mysql import insert
from core.data.schema import BaseData, metadata
+from core.data import cached
best_score = Table(
"mai2_score_best",
@@ -190,6 +191,7 @@ class Mai2ScoreData(BaseData):
return None
return result.lastrowid
+ @cached(2)
def get_best_scores(self, user_id: int, song_id: int = None) -> Optional[List[Row]]:
sql = best_score.select(
and_(
diff --git a/titles/mai2/universe.py b/titles/mai2/universe.py
index adcb205..f5b2515 100644
--- a/titles/mai2/universe.py
+++ b/titles/mai2/universe.py
@@ -14,3 +14,202 @@ class Mai2Universe(Mai2DX):
def __init__(self, cfg: CoreConfig, game_cfg: Mai2Config) -> None:
super().__init__(cfg, game_cfg)
self.version = Mai2Constants.VER_MAIMAI_DX_UNIVERSE
+
+ def handle_cm_get_user_preview_api_request(self, data: Dict) -> Dict:
+ p = self.data.profile.get_profile_detail(data["userId"], self.version)
+ if p is None:
+ return {}
+
+ return {
+ "userName": p["userName"],
+ "rating": p["playerRating"],
+ # hardcode lastDataVersion for CardMaker 1.34
+ "lastDataVersion": "1.20.00",
+ "isLogin": False,
+ "isExistSellingCard": False,
+ }
+
+ def handle_cm_get_user_data_api_request(self, data: Dict) -> Dict:
+ # user already exists, because the preview checks that already
+ p = self.data.profile.get_profile_detail(data["userId"], self.version)
+
+ cards = self.data.card.get_user_cards(data["userId"])
+ if cards is None or len(cards) == 0:
+ # This should never happen
+ self.logger.error(
+ f"handle_get_user_data_api_request: Internal error - No cards found for user id {data['userId']}"
+ )
+ return {}
+
+ # get the dict representation of the row so we can modify values
+ user_data = p._asdict()
+
+ # remove the values the game doesn't want
+ user_data.pop("id")
+ user_data.pop("user")
+ user_data.pop("version")
+
+ return {"userId": data["userId"], "userData": user_data}
+
+ def handle_cm_login_api_request(self, data: Dict) -> Dict:
+ return {"returnCode": 1}
+
+ def handle_cm_logout_api_request(self, data: Dict) -> Dict:
+ return {"returnCode": 1}
+
+ def handle_cm_get_selling_card_api_request(self, data: Dict) -> Dict:
+ selling_cards = self.data.static.get_enabled_cards(self.version)
+ if selling_cards is None:
+ return {"length": 0, "sellingCardList": []}
+
+ selling_card_list = []
+ for card in selling_cards:
+ tmp = card._asdict()
+ tmp.pop("id")
+ tmp.pop("version")
+ tmp.pop("cardName")
+ tmp.pop("enabled")
+
+ tmp["startDate"] = datetime.strftime(tmp["startDate"], "%Y-%m-%d %H:%M:%S")
+ tmp["endDate"] = datetime.strftime(tmp["endDate"], "%Y-%m-%d %H:%M:%S")
+ tmp["noticeStartDate"] = datetime.strftime(
+ tmp["noticeStartDate"], "%Y-%m-%d %H:%M:%S"
+ )
+ tmp["noticeEndDate"] = datetime.strftime(
+ tmp["noticeEndDate"], "%Y-%m-%d %H:%M:%S"
+ )
+
+ selling_card_list.append(tmp)
+
+ return {"length": len(selling_card_list), "sellingCardList": selling_card_list}
+
+ def handle_cm_get_user_card_api_request(self, data: Dict) -> Dict:
+ user_cards = self.data.item.get_cards(data["userId"])
+ if user_cards is None:
+ return {"returnCode": 1, "length": 0, "nextIndex": 0, "userCardList": []}
+
+ max_ct = data["maxCount"]
+ next_idx = data["nextIndex"]
+ start_idx = next_idx
+ end_idx = max_ct + start_idx
+
+ if len(user_cards[start_idx:]) > max_ct:
+ next_idx += max_ct
+ else:
+ next_idx = 0
+
+ card_list = []
+ for card in user_cards:
+ tmp = card._asdict()
+ tmp.pop("id")
+ tmp.pop("user")
+
+ tmp["startDate"] = datetime.strftime(
+ tmp["startDate"], Mai2Constants.DATE_TIME_FORMAT
+ )
+ tmp["endDate"] = datetime.strftime(
+ tmp["endDate"], Mai2Constants.DATE_TIME_FORMAT
+ )
+ card_list.append(tmp)
+
+ return {
+ "returnCode": 1,
+ "length": len(card_list[start_idx:end_idx]),
+ "nextIndex": next_idx,
+ "userCardList": card_list[start_idx:end_idx],
+ }
+
+ def handle_cm_get_user_item_api_request(self, data: Dict) -> Dict:
+ super().handle_get_user_item_api_request(data)
+
+ def handle_cm_get_user_character_api_request(self, data: Dict) -> Dict:
+ characters = self.data.item.get_characters(data["userId"])
+
+ chara_list = []
+ for chara in characters:
+ chara_list.append(
+ {
+ "characterId": chara["characterId"],
+ # no clue why those values are even needed
+ "point": 0,
+ "count": 0,
+ "level": chara["level"],
+ "nextAwake": 0,
+ "nextAwakePercent": 0,
+ "favorite": False,
+ "awakening": chara["awakening"],
+ "useCount": chara["useCount"],
+ }
+ )
+
+ return {
+ "returnCode": 1,
+ "length": len(chara_list),
+ "userCharacterList": chara_list,
+ }
+
+ def handle_cm_get_user_card_print_error_api_request(self, data: Dict) -> Dict:
+ return {"length": 0, "userPrintDetailList": []}
+
+ def handle_cm_upsert_user_print_api_request(self, data: Dict) -> Dict:
+ user_id = data["userId"]
+ upsert = data["userPrintDetail"]
+
+ # set a random card serial number
+ serial_id = "".join([str(randint(0, 9)) for _ in range(20)])
+
+ # calculate start and end date of the card
+ start_date = datetime.utcnow()
+ end_date = datetime.utcnow() + timedelta(days=15)
+
+ user_card = upsert["userCard"]
+ self.data.item.put_card(
+ user_id,
+ user_card["cardId"],
+ user_card["cardTypeId"],
+ user_card["charaId"],
+ user_card["mapId"],
+ # add the correct start date and also the end date in 15 days
+ start_date,
+ end_date,
+ )
+
+ # get the profile extend to save the new bought card
+ extend = self.data.profile.get_profile_extend(user_id, self.version)
+ if extend:
+ extend = extend._asdict()
+ # parse the selectedCardList
+ # 6 = Freedom Pass, 4 = Gold Pass (cardTypeId)
+ selected_cards: list = extend["selectedCardList"]
+
+ # if no pass is already added, add the corresponding pass
+ if not user_card["cardTypeId"] in selected_cards:
+ selected_cards.insert(0, user_card["cardTypeId"])
+
+ extend["selectedCardList"] = selected_cards
+ self.data.profile.put_profile_extend(user_id, self.version, extend)
+
+ # properly format userPrintDetail for the database
+ upsert.pop("userCard")
+ upsert.pop("serialId")
+ upsert["printDate"] = datetime.strptime(upsert["printDate"], "%Y-%m-%d")
+
+ self.data.item.put_user_print_detail(user_id, serial_id, upsert)
+
+ return {
+ "returnCode": 1,
+ "orderId": 0,
+ "serialId": serial_id,
+ "startDate": datetime.strftime(start_date, Mai2Constants.DATE_TIME_FORMAT),
+ "endDate": datetime.strftime(end_date, Mai2Constants.DATE_TIME_FORMAT),
+ }
+
+ def handle_cm_upsert_user_printlog_api_request(self, data: Dict) -> Dict:
+ return {
+ "returnCode": 1,
+ "orderId": 0,
+ "serialId": data["userPrintlog"]["serialId"],
+ }
+
+ def handle_cm_upsert_buy_card_api_request(self, data: Dict) -> Dict:
+ return {"returnCode": 1}
diff --git a/titles/pokken/base.py b/titles/pokken/base.py
index 40e6444..50bc760 100644
--- a/titles/pokken/base.py
+++ b/titles/pokken/base.py
@@ -1,6 +1,6 @@
from datetime import datetime, timedelta
import json, logging
-from typing import Any, Dict
+from typing import Any, Dict, List
import random
from core.data import Data
@@ -44,19 +44,19 @@ class PokkenBase:
biwa_setting = {
"MatchingServer": {
"host": f"https://{self.game_cfg.server.hostname}",
- "port": self.game_cfg.server.port,
+ "port": self.game_cfg.ports.game,
"url": "/SDAK/100/matching",
},
"StunServer": {
- "addr": self.game_cfg.server.hostname,
- "port": self.game_cfg.server.port_stun,
+ "addr": self.game_cfg.server.stun_server_host,
+ "port": self.game_cfg.server.stun_server_port,
},
"TurnServer": {
- "addr": self.game_cfg.server.hostname,
- "port": self.game_cfg.server.port_turn,
+ "addr": self.game_cfg.server.stun_server_host,
+ "port": self.game_cfg.server.stun_server_port,
},
- "AdmissionUrl": f"ws://{self.game_cfg.server.hostname}:{self.game_cfg.server.port_admission}",
- "locationId": 123,
+ "AdmissionUrl": f"ws://{self.game_cfg.server.hostname}:{self.game_cfg.ports.admission}",
+ "locationId": 123, # FIXME: Get arcade's ID from the database
"logfilename": "JackalMatchingLibrary.log",
"biwalogfilename": "./biwa.log",
}
@@ -94,6 +94,7 @@ class PokkenBase:
res.type = jackal_pb2.MessageType.LOAD_CLIENT_SETTINGS
settings = jackal_pb2.LoadClientSettingsResponseData()
+ # TODO: Make configurable
settings.money_magnification = 1
settings.continue_bonus_exp = 100
settings.continue_fight_money = 100
@@ -274,6 +275,60 @@ class PokkenBase:
res.result = 1
res.type = jackal_pb2.MessageType.SAVE_USER
+ req = request.save_user
+ user_id = req.banapass_id
+
+ tut_flgs: List[int] = []
+ ach_flgs: List[int] = []
+ evt_flgs: List[int] = []
+ evt_params: List[int] = []
+
+ get_rank_pts: int = req.get_trainer_rank_point if req.get_trainer_rank_point else 0
+ get_money: int = req.get_money
+ get_score_pts: int = req.get_score_point if req.get_score_point else 0
+ grade_max: int = req.grade_max_num
+ extra_counter: int = req.extra_counter
+ evt_reward_get_flg: int = req.event_reward_get_flag
+ num_continues: int = req.continue_num
+ total_play_days: int = req.total_play_days
+ awake_num: int = req.awake_num # ?
+ use_support_ct: int = req.use_support_num
+ beat_num: int = req.beat_num # ?
+ evt_state: int = req.event_state
+ aid_skill: int = req.aid_skill
+ last_evt: int = req.last_play_event_id
+
+ battle = req.battle_data
+ mon = req.pokemon_data
+
+ self.data.profile.update_support_team(user_id, 1, req.support_set_1[0], req.support_set_1[1])
+ self.data.profile.update_support_team(user_id, 2, req.support_set_2[0], req.support_set_2[1])
+ self.data.profile.update_support_team(user_id, 3, req.support_set_3[0], req.support_set_3[1])
+
+ if req.trainer_name_pending: # we're saving for the first time
+ self.data.profile.set_profile_name(user_id, req.trainer_name_pending, req.avatar_gender if req.avatar_gender else None)
+
+ for tut_flg in req.tutorial_progress_flag:
+ tut_flgs.append(tut_flg)
+
+ self.data.profile.update_profile_tutorial_flags(user_id, tut_flgs)
+
+ for ach_flg in req.achievement_flag:
+ ach_flgs.append(ach_flg)
+
+ self.data.profile.update_profile_tutorial_flags(user_id, ach_flg)
+
+ for evt_flg in req.event_achievement_flag:
+ evt_flgs.append(evt_flg)
+
+ for evt_param in req.event_achievement_param:
+ evt_params.append(evt_param)
+
+ self.data.profile.update_profile_event(user_id, evt_state, evt_flgs, evt_params, )
+
+ for reward in req.reward_data:
+ self.data.item.add_reward(user_id, reward.get_category_id, reward.get_content_id, reward.get_type_id)
+
return res.SerializeToString()
def handle_save_ingame_log(self, data: jackal_pb2.Request) -> bytes:
@@ -302,16 +357,35 @@ class PokkenBase:
self, data: Dict = {}, client_ip: str = "127.0.0.1"
) -> Dict:
"""
- "sessionId":"12345678",
+ "sessionId":"12345678",
+ "A":{
+ "pcb_id": data["data"]["must"]["pcb_id"],
+ "gip": client_ip
+ },
+ """
+ return {
+ "data": {
+ "sessionId":"12345678",
"A":{
"pcb_id": data["data"]["must"]["pcb_id"],
"gip": client_ip
},
"list":[]
- """
- return {}
+ }
+ }
def handle_matching_stop_matching(
self, data: Dict = {}, client_ip: str = "127.0.0.1"
) -> Dict:
return {}
+
+ def handle_admission_noop(self, data: Dict, req_ip: str = "127.0.0.1") -> Dict:
+ return {}
+
+ def handle_admission_joinsession(self, data: Dict, req_ip: str = "127.0.0.1") -> Dict:
+ self.logger.info(f"Admission: JoinSession from {req_ip}")
+ return {
+ 'data': {
+ "id": 12345678
+ }
+ }
diff --git a/titles/pokken/config.py b/titles/pokken/config.py
index 84da8d2..d3741af 100644
--- a/titles/pokken/config.py
+++ b/titles/pokken/config.py
@@ -25,30 +25,6 @@ class PokkenServerConfig:
)
)
- @property
- def port(self) -> int:
- return CoreConfig.get_config_field(
- self.__config, "pokken", "server", "port", default=9000
- )
-
- @property
- def port_stun(self) -> int:
- return CoreConfig.get_config_field(
- self.__config, "pokken", "server", "port_stun", default=9001
- )
-
- @property
- def port_turn(self) -> int:
- return CoreConfig.get_config_field(
- self.__config, "pokken", "server", "port_turn", default=9002
- )
-
- @property
- def port_admission(self) -> int:
- return CoreConfig.get_config_field(
- self.__config, "pokken", "server", "port_admission", default=9003
- )
-
@property
def auto_register(self) -> bool:
"""
@@ -59,7 +35,51 @@ class PokkenServerConfig:
self.__config, "pokken", "server", "auto_register", default=True
)
+ @property
+ def enable_matching(self) -> bool:
+ """
+ If global matching should happen
+ """
+ return CoreConfig.get_config_field(
+ self.__config, "pokken", "server", "enable_matching", default=False
+ )
+
+ @property
+ def stun_server_host(self) -> str:
+ """
+ Hostname of the EXTERNAL stun server the game should connect to. This is not handled by artemis.
+ """
+ return CoreConfig.get_config_field(
+ self.__config, "pokken", "server", "stun_server_host", default="stunserver.stunprotocol.org"
+ )
+
+ @property
+ def stun_server_port(self) -> int:
+ """
+ Port of the EXTERNAL stun server the game should connect to. This is not handled by artemis.
+ """
+ return CoreConfig.get_config_field(
+ self.__config, "pokken", "server", "stun_server_port", default=3478
+ )
+
+class PokkenPortsConfig:
+ def __init__(self, parent_config: "PokkenConfig"):
+ self.__config = parent_config
+
+ @property
+ def game(self) -> int:
+ return CoreConfig.get_config_field(
+ self.__config, "pokken", "ports", "game", default=9000
+ )
+
+ @property
+ def admission(self) -> int:
+ return CoreConfig.get_config_field(
+ self.__config, "pokken", "ports", "admission", default=9001
+ )
+
class PokkenConfig(dict):
def __init__(self) -> None:
self.server = PokkenServerConfig(self)
+ self.ports = PokkenPortsConfig(self)
diff --git a/titles/pokken/const.py b/titles/pokken/const.py
index 2eb5357..e7ffdd8 100644
--- a/titles/pokken/const.py
+++ b/titles/pokken/const.py
@@ -11,14 +11,14 @@ class PokkenConstants:
VERSION_NAMES = "Pokken Tournament"
class BATTLE_TYPE(Enum):
- BATTLE_TYPE_TUTORIAL = 1
- BATTLE_TYPE_AI = 2
- BATTLE_TYPE_LAN = 3
- BATTLE_TYPE_WAN = 4
+ TUTORIAL = 1
+ AI = 2
+ LAN = 3
+ WAN = 4
class BATTLE_RESULT(Enum):
- BATTLE_RESULT_WIN = 1
- BATTLE_RESULT_LOSS = 2
+ WIN = 1
+ LOSS = 2
@classmethod
def game_ver_to_string(cls, ver: int):
diff --git a/titles/pokken/frontend.py b/titles/pokken/frontend.py
index e4e8947..af344dc 100644
--- a/titles/pokken/frontend.py
+++ b/titles/pokken/frontend.py
@@ -2,8 +2,9 @@ import yaml
import jinja2
from twisted.web.http import Request
from os import path
+from twisted.web.server import Session
-from core.frontend import FE_Base
+from core.frontend import FE_Base, IUserSession
from core.config import CoreConfig
from .database import PokkenData
from .config import PokkenConfig
@@ -27,7 +28,12 @@ class PokkenFrontend(FE_Base):
template = self.environment.get_template(
"titles/pokken/frontend/pokken_index.jinja"
)
+
+ sesh: Session = request.getSession()
+ usr_sesh = IUserSession(sesh)
+
return template.render(
title=f"{self.core_config.server.name} | {self.nav_name}",
game_list=self.environment.globals["game_list"],
+ sesh=vars(usr_sesh)
).encode("utf-16")
diff --git a/titles/pokken/index.py b/titles/pokken/index.py
index bccdcaf..3ccb3fc 100644
--- a/titles/pokken/index.py
+++ b/titles/pokken/index.py
@@ -1,6 +1,7 @@
from typing import Tuple
from twisted.web.http import Request
from twisted.web import resource
+from twisted.internet import reactor
import json, ast
from datetime import datetime
import yaml
@@ -11,10 +12,11 @@ from os import path
from google.protobuf.message import DecodeError
from core import CoreConfig, Utils
-from titles.pokken.config import PokkenConfig
-from titles.pokken.base import PokkenBase
-from titles.pokken.const import PokkenConstants
-from titles.pokken.proto import jackal_pb2
+from .config import PokkenConfig
+from .base import PokkenBase
+from .const import PokkenConstants
+from .proto import jackal_pb2
+from .services import PokkenAdmissionFactory
class PokkenServlet(resource.Resource):
@@ -69,7 +71,7 @@ class PokkenServlet(resource.Resource):
return (
True,
- f"https://{game_cfg.server.hostname}:{game_cfg.server.port}/{game_code}/$v/",
+ f"https://{game_cfg.server.hostname}:{game_cfg.ports.game}/{game_code}/$v/",
f"{game_cfg.server.hostname}/SDAK/$v/",
)
@@ -90,8 +92,10 @@ class PokkenServlet(resource.Resource):
return (True, "PKF1")
def setup(self) -> None:
- # TODO: Setup stun, turn (UDP) and admission (WSS) servers
- pass
+ if self.game_cfg.server.enable_matching:
+ reactor.listenTCP(
+ self.game_cfg.ports.admission, PokkenAdmissionFactory(self.core_cfg, self.game_cfg)
+ )
def render_POST(
self, request: Request, version: int = 0, endpoints: str = ""
@@ -128,6 +132,9 @@ class PokkenServlet(resource.Resource):
return ret
def handle_matching(self, request: Request) -> bytes:
+ if not self.game_cfg.server.enable_matching:
+ return b""
+
content = request.content.getvalue()
client_ip = Utils.get_ip_addr(request)
diff --git a/titles/pokken/schema/item.py b/titles/pokken/schema/item.py
index 4919ea0..32bff2a 100644
--- a/titles/pokken/schema/item.py
+++ b/titles/pokken/schema/item.py
@@ -31,4 +31,16 @@ class PokkenItemData(BaseData):
Items obtained as rewards
"""
- pass
+ def add_reward(self, user_id: int, category: int, content: int, item_type: int) -> Optional[int]:
+ sql = insert(item).values(
+ user=user_id,
+ category=category,
+ content=content,
+ type=item_type,
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.warn(f"Failed to insert reward for user {user_id}: {category}-{content}-{item_type}")
+ return None
+ return result.lastrowid
diff --git a/titles/pokken/schema/profile.py b/titles/pokken/schema/profile.py
index 8e536f1..94e15e8 100644
--- a/titles/pokken/schema/profile.py
+++ b/titles/pokken/schema/profile.py
@@ -1,4 +1,4 @@
-from typing import Optional, Dict, List
+from typing import Optional, Dict, List, Union
from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, case
from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
from sqlalchemy.schema import ForeignKey
@@ -125,7 +125,7 @@ pokemon_data = Table(
Column("win_vs_lan", Integer),
Column("battle_num_vs_cpu", Integer), # 2
Column("win_cpu", Integer),
- Column("battle_all_num_tutorial", Integer),
+ Column("battle_all_num_tutorial", Integer), # ???
Column("battle_num_tutorial", Integer), # 1?
Column("bp_point_atk", Integer),
Column("bp_point_res", Integer),
@@ -147,11 +147,10 @@ class PokkenProfileData(BaseData):
return None
return result.lastrowid
- def set_profile_name(self, user_id: int, new_name: str) -> None:
- sql = (
- update(profile)
- .where(profile.c.user == user_id)
- .values(trainer_name=new_name)
+ def set_profile_name(self, user_id: int, new_name: str, gender: Union[int, None] = None) -> None:
+ sql = update(profile).where(profile.c.user == user_id).values(
+ trainer_name=new_name,
+ avatar_gender=gender if gender is not None else profile.c.avatar_gender
)
result = self.execute(sql)
if result is None:
@@ -159,8 +158,38 @@ class PokkenProfileData(BaseData):
f"Failed to update pokken profile name for user {user_id}!"
)
- def update_profile_tutorial_flags(self, user_id: int, tutorial_flags: Dict) -> None:
- pass
+ def update_profile_tutorial_flags(self, user_id: int, tutorial_flags: List) -> None:
+ sql = update(profile).where(profile.c.user == user_id).values(
+ tutorial_progress_flag=tutorial_flags,
+ )
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"Failed to update pokken profile tutorial flags for user {user_id}!"
+ )
+
+ def update_profile_achievement_flags(self, user_id: int, achievement_flags: List) -> None:
+ sql = update(profile).where(profile.c.user == user_id).values(
+ achievement_flag=achievement_flags,
+ )
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"Failed to update pokken profile achievement flags for user {user_id}!"
+ )
+
+ def update_profile_event(self, user_id: int, event_state: List, event_flags: List[int], event_param: List[int], last_evt: int = None) -> None:
+ sql = update(profile).where(profile.c.user == user_id).values(
+ event_state=event_state,
+ event_achievement_flag=event_flags,
+ event_achievement_param=event_param,
+ last_play_event_id=last_evt if last_evt is not None else profile.c.last_play_event_id,
+ )
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"Failed to update pokken profile event state for user {user_id}!"
+ )
def add_profile_points(
self, user_id: int, rank_pts: int, money: int, score_pts: int
@@ -174,18 +203,53 @@ class PokkenProfileData(BaseData):
return None
return result.fetchone()
- def put_pokemon_data(
+ def put_pokemon(
self,
user_id: int,
pokemon_id: int,
illust_no: int,
- get_exp: int,
atk: int,
res: int,
defe: int,
- sp: int,
+ sp: int
) -> Optional[int]:
- pass
+ sql = insert(pokemon_data).values(
+ user=user_id,
+ char_id=pokemon_id,
+ illustration_book_no=illust_no,
+ bp_point_atk=atk,
+ bp_point_res=res,
+ bp_point_defe=defe,
+ bp_point_sp=sp,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ illustration_book_no=illust_no,
+ bp_point_atk=atk,
+ bp_point_res=res,
+ bp_point_defe=defe,
+ bp_point_sp=sp,
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.warn(f"Failed to insert pokemon ID {pokemon_id} for user {user_id}")
+ return None
+ return result.lastrowid
+
+ def add_pokemon_xp(
+ self,
+ user_id: int,
+ pokemon_id: int,
+ xp: int
+ ) -> None:
+ sql = update(pokemon_data).where(and_(pokemon_data.c.user==user_id, pokemon_data.c.char_id==pokemon_id)).values(
+ pokemon_exp=pokemon_data.c.pokemon_exp + xp
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.warn(f"Failed to add {xp} XP to pokemon ID {pokemon_id} for user {user_id}")
def get_pokemon_data(self, user_id: int, pokemon_id: int) -> Optional[Row]:
pass
@@ -193,13 +257,29 @@ class PokkenProfileData(BaseData):
def get_all_pokemon_data(self, user_id: int) -> Optional[List[Row]]:
pass
- def put_results(
- self, user_id: int, pokemon_id: int, match_type: int, match_result: int
+ def put_pokemon_battle_result(
+ self, user_id: int, pokemon_id: int, match_type: PokkenConstants.BATTLE_TYPE, match_result: PokkenConstants.BATTLE_RESULT
) -> None:
"""
Records the match stats (type and win/loss) for the pokemon and profile
"""
- pass
+ sql = update(pokemon_data).where(and_(pokemon_data.c.user==user_id, pokemon_data.c.char_id==pokemon_id)).values(
+ battle_num_tutorial=pokemon_data.c.battle_num_tutorial + 1 if match_type==PokkenConstants.BATTLE_TYPE.TUTORIAL else pokemon_data.c.battle_num_tutorial,
+ battle_all_num_tutorial=pokemon_data.c.battle_all_num_tutorial + 1 if match_type==PokkenConstants.BATTLE_TYPE.TUTORIAL else pokemon_data.c.battle_all_num_tutorial,
+
+ battle_num_vs_cpu=pokemon_data.c.battle_num_vs_cpu + 1 if match_type==PokkenConstants.BATTLE_TYPE.AI else pokemon_data.c.battle_num_vs_cpu,
+ win_cpu=pokemon_data.c.win_cpu + 1 if match_type==PokkenConstants.BATTLE_TYPE.AI and match_result==PokkenConstants.BATTLE_RESULT.WIN else pokemon_data.c.win_cpu,
+
+ battle_num_vs_lan=pokemon_data.c.battle_num_vs_lan + 1 if match_type==PokkenConstants.BATTLE_TYPE.LAN else pokemon_data.c.battle_num_vs_lan,
+ win_vs_lan=pokemon_data.c.win_vs_lan + 1 if match_type==PokkenConstants.BATTLE_TYPE.LAN and match_result==PokkenConstants.BATTLE_RESULT.WIN else pokemon_data.c.win_vs_lan,
+
+ battle_num_vs_wan=pokemon_data.c.battle_num_vs_wan + 1 if match_type==PokkenConstants.BATTLE_TYPE.WAN else pokemon_data.c.battle_num_vs_wan,
+ win_vs_wan=pokemon_data.c.win_vs_wan + 1 if match_type==PokkenConstants.BATTLE_TYPE.WAN and match_result==PokkenConstants.BATTLE_RESULT.WIN else pokemon_data.c.win_vs_wan,
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.warn(f"Failed to record match stats for user {user_id}'s pokemon {pokemon_id} (type {match_type.name} | result {match_result.name})")
def put_stats(
self,
@@ -215,3 +295,17 @@ class PokkenProfileData(BaseData):
Records profile stats
"""
pass
+
+ def update_support_team(self, user_id: int, support_id: int, support1: int = 4294967295, support2: int = 4294967295) -> None:
+ sql = update(profile).where(profile.c.user==user_id).values(
+ support_set_1_1=support1 if support_id == 1 else profile.c.support_set_1_1,
+ support_set_1_2=support2 if support_id == 1 else profile.c.support_set_1_2,
+ support_set_2_1=support1 if support_id == 2 else profile.c.support_set_2_1,
+ support_set_2_2=support2 if support_id == 2 else profile.c.support_set_2_2,
+ support_set_3_1=support1 if support_id == 3 else profile.c.support_set_3_1,
+ support_set_3_2=support2 if support_id == 3 else profile.c.support_set_3_2,
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.warn(f"Failed to update support team {support_id} for user {user_id}")
diff --git a/titles/pokken/services.py b/titles/pokken/services.py
new file mode 100644
index 0000000..952c232
--- /dev/null
+++ b/titles/pokken/services.py
@@ -0,0 +1,66 @@
+from twisted.internet.interfaces import IAddress
+from twisted.internet.protocol import Protocol
+from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
+from autobahn.websocket.types import ConnectionRequest
+from typing import Dict
+import logging
+import json
+
+from core.config import CoreConfig
+from .config import PokkenConfig
+from .base import PokkenBase
+
+class PokkenAdmissionProtocol(WebSocketServerProtocol):
+ def __init__(self, cfg: CoreConfig, game_cfg: PokkenConfig):
+ super().__init__()
+ self.core_config = cfg
+ self.game_config = game_cfg
+ self.logger = logging.getLogger("pokken")
+
+ self.base = PokkenBase(cfg, game_cfg)
+
+ def onConnect(self, request: ConnectionRequest) -> None:
+ self.logger.debug(f"Admission: Connection from {request.peer}")
+
+ def onClose(self, wasClean: bool, code: int, reason: str) -> None:
+ self.logger.debug(f"Admission: Connection with {self.transport.getPeer().host} closed {'cleanly ' if wasClean else ''}with code {code} - {reason}")
+
+ def onMessage(self, payload, isBinary: bool) -> None:
+ msg: Dict = json.loads(payload)
+ self.logger.debug(f"Admission: Message from {self.transport.getPeer().host}:{self.transport.getPeer().port} - {msg}")
+
+ api = msg.get("api", "noop")
+ handler = getattr(self.base, f"handle_admission_{api.lower()}")
+ resp = handler(msg, self.transport.getPeer().host)
+
+ if resp is None:
+ resp = {}
+
+ if "type" not in resp:
+ resp['type'] = "res"
+ if "data" not in resp:
+ resp['data'] = {}
+ if "api" not in resp:
+ resp['api'] = api
+ if "result" not in resp:
+ resp['result'] = 'true'
+
+ self.logger.debug(f"Websocket response: {resp}")
+ self.sendMessage(json.dumps(resp).encode(), isBinary)
+
+class PokkenAdmissionFactory(WebSocketServerFactory):
+ protocol = PokkenAdmissionProtocol
+
+ def __init__(
+ self,
+ cfg: CoreConfig,
+ game_cfg: PokkenConfig
+ ) -> None:
+ self.core_config = cfg
+ self.game_config = game_cfg
+ super().__init__(f"ws://{self.game_config.server.hostname}:{self.game_config.ports.admission}")
+
+ def buildProtocol(self, addr: IAddress) -> Protocol:
+ p = self.protocol(self.core_config, self.game_config)
+ p.factory = self
+ return p
diff --git a/titles/sao/__init__.py b/titles/sao/__init__.py
new file mode 100644
index 0000000..15a46f9
--- /dev/null
+++ b/titles/sao/__init__.py
@@ -0,0 +1,10 @@
+from .index import SaoServlet
+from .const import SaoConstants
+from .database import SaoData
+from .read import SaoReader
+
+index = SaoServlet
+database = SaoData
+reader = SaoReader
+game_codes = [SaoConstants.GAME_CODE]
+current_schema_version = 1
diff --git a/titles/sao/base.py b/titles/sao/base.py
new file mode 100644
index 0000000..ece4654
--- /dev/null
+++ b/titles/sao/base.py
@@ -0,0 +1,1165 @@
+from datetime import datetime, timedelta
+import json, logging
+from typing import Any, Dict
+import random
+import struct
+from csv import *
+from random import choice
+import random as rand
+
+from core.data import Data
+from core import CoreConfig
+from .config import SaoConfig
+from .database import SaoData
+from titles.sao.handlers.base import *
+
+class SaoBase:
+ def __init__(self, core_cfg: CoreConfig, game_cfg: SaoConfig) -> None:
+ self.core_cfg = core_cfg
+ self.game_cfg = game_cfg
+ self.core_data = Data(core_cfg)
+ self.game_data = SaoData(core_cfg)
+ self.version = 0
+ self.logger = logging.getLogger("sao")
+
+ def handle_noop(self, request: Any) -> bytes:
+ sao_request = request
+
+ sao_id = int(sao_request[:4],16) + 1
+
+ ret = struct.pack("!HHIIIIIIb", sao_id, 0, 0, 5, 1, 1, 5, 0x01000000, 0).hex()
+ return bytes.fromhex(ret)
+
+ def handle_c122(self, request: Any) -> bytes:
+ #common/get_maintenance_info
+ resp = SaoGetMaintResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c12e(self, request: Any) -> bytes:
+ #common/ac_cabinet_boot_notification
+ resp = SaoCommonAcCabinetBootNotificationResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c100(self, request: Any) -> bytes:
+ #common/get_app_versions
+ resp = SaoCommonGetAppVersionsRequest(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c102(self, request: Any) -> bytes:
+ #common/master_data_version_check
+ resp = SaoMasterDataVersionCheckResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c10a(self, request: Any) -> bytes:
+ #common/paying_play_start
+ resp = SaoCommonPayingPlayStartRequest(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_ca02(self, request: Any) -> bytes:
+ #quest_multi_play_room/get_quest_scene_multi_play_photon_server
+ resp = SaoGetQuestSceneMultiPlayPhotonServerResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c11e(self, request: Any) -> bytes:
+ #common/get_auth_card_data
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "cabinet_type" / Int8ub, # cabinet_type is a byte
+ "auth_type" / Int8ub, # auth_type is a byte
+ "store_id_size" / Rebuild(Int32ub, len_(this.store_id) * 2), # calculates the length of the store_id
+ "store_id" / PaddedString(this.store_id_size, "utf_16_le"), # store_id is a (zero) padded string
+ "serial_no_size" / Rebuild(Int32ub, len_(this.serial_no) * 2), # calculates the length of the serial_no
+ "serial_no" / PaddedString(this.serial_no_size, "utf_16_le"), # serial_no is a (zero) padded string
+ "access_code_size" / Rebuild(Int32ub, len_(this.access_code) * 2), # calculates the length of the access_code
+ "access_code" / PaddedString(this.access_code_size, "utf_16_le"), # access_code is a (zero) padded string
+ "chip_id_size" / Rebuild(Int32ub, len_(this.chip_id) * 2), # calculates the length of the chip_id
+ "chip_id" / PaddedString(this.chip_id_size, "utf_16_le"), # chip_id is a (zero) padded string
+ )
+
+ req_data = req_struct.parse(req)
+ access_code = req_data.access_code
+
+ #Check authentication
+ user_id = self.core_data.card.get_user_id_from_card( access_code )
+
+ if not user_id:
+ user_id = self.core_data.user.create_user() #works
+ card_id = self.core_data.card.create_card(user_id, access_code)
+
+ if card_id is None:
+ user_id = -1
+ self.logger.error("Failed to register card!")
+
+ # Create profile with 3 basic heroes
+ profile_id = self.game_data.profile.create_profile(user_id)
+ self.game_data.item.put_hero_log(user_id, 101000010, 1, 0, 101000016, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_log(user_id, 102000010, 1, 0, 103000006, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_log(user_id, 103000010, 1, 0, 112000009, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_party(user_id, 0, 101000010, 102000010, 103000010)
+ self.game_data.item.put_equipment_data(user_id, 101000016, 1, 200, 0, 0, 0)
+ self.game_data.item.put_equipment_data(user_id, 103000006, 1, 200, 0, 0, 0)
+ self.game_data.item.put_equipment_data(user_id, 112000009, 1, 200, 0, 0, 0)
+ self.game_data.item.put_player_quest(user_id, 1001, True, 300, 0, 0, 1)
+
+ # Force the tutorial stage to be completed due to potential crash in-game
+
+
+ self.logger.info(f"User Authenticated: { access_code } | { user_id }")
+
+ #Grab values from profile
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ if user_id and not profile_data:
+ profile_id = self.game_data.profile.create_profile(user_id)
+ self.game_data.item.put_hero_log(user_id, 101000010, 1, 0, 101000016, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_log(user_id, 102000010, 1, 0, 103000006, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_log(user_id, 103000010, 1, 0, 112000009, 0, 30086, 1001, 1002, 1003, 1005)
+ self.game_data.item.put_hero_party(user_id, 0, 101000010, 102000010, 103000010)
+ self.game_data.item.put_equipment_data(user_id, 101000016, 1, 200, 0, 0, 0)
+ self.game_data.item.put_equipment_data(user_id, 103000006, 1, 200, 0, 0, 0)
+ self.game_data.item.put_equipment_data(user_id, 112000009, 1, 200, 0, 0, 0)
+ self.game_data.item.put_player_quest(user_id, 1001, True, 300, 0, 0, 1)
+
+ # Force the tutorial stage to be completed due to potential crash in-game
+
+
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ resp = SaoGetAuthCardDataResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c40c(self, request: Any) -> bytes:
+ #home/check_ac_login_bonus
+ resp = SaoHomeCheckAcLoginBonusResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c104(self, request: Any) -> bytes:
+ #common/login
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "cabinet_type" / Int8ub, # cabinet_type is a byte
+ "auth_type" / Int8ub, # auth_type is a byte
+ "store_id_size" / Rebuild(Int32ub, len_(this.store_id) * 2), # calculates the length of the store_id
+ "store_id" / PaddedString(this.store_id_size, "utf_16_le"), # store_id is a (zero) padded string
+ "store_name_size" / Rebuild(Int32ub, len_(this.store_name) * 2), # calculates the length of the store_name
+ "store_name" / PaddedString(this.store_name_size, "utf_16_le"), # store_name is a (zero) padded string
+ "serial_no_size" / Rebuild(Int32ub, len_(this.serial_no) * 2), # calculates the length of the serial_no
+ "serial_no" / PaddedString(this.serial_no_size, "utf_16_le"), # serial_no is a (zero) padded string
+ "access_code_size" / Rebuild(Int32ub, len_(this.access_code) * 2), # calculates the length of the access_code
+ "access_code" / PaddedString(this.access_code_size, "utf_16_le"), # access_code is a (zero) padded string
+ "chip_id_size" / Rebuild(Int32ub, len_(this.chip_id) * 2), # calculates the length of the chip_id
+ "chip_id" / PaddedString(this.chip_id_size, "utf_16_le"), # chip_id is a (zero) padded string
+ "free_ticket_distribution_target_flag" / Int8ub, # free_ticket_distribution_target_flag is a byte
+ )
+
+ req_data = req_struct.parse(req)
+ access_code = req_data.access_code
+
+ user_id = self.core_data.card.get_user_id_from_card( access_code )
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ resp = SaoCommonLoginResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c404(self, request: Any) -> bytes:
+ #home/check_comeback_event
+ resp = SaoCheckComebackEventRequest(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c000(self, request: Any) -> bytes:
+ #ticket/ticket
+ resp = SaoTicketResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c500(self, request: Any) -> bytes:
+ #user_info/get_user_basic_data
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ )
+
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ resp = SaoGetUserBasicDataResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c600(self, request: Any) -> bytes:
+ #have_object/get_hero_log_user_data_list
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+
+ )
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ hero_data = self.game_data.item.get_hero_logs(user_id)
+
+ resp = SaoGetHeroLogUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, hero_data)
+ return resp.make()
+
+ def handle_c602(self, request: Any) -> bytes:
+ #have_object/get_equipment_user_data_list
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+
+ )
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ equipment_data = self.game_data.item.get_user_equipments(user_id)
+
+ resp = SaoGetEquipmentUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, equipment_data)
+ return resp.make()
+
+ def handle_c604(self, request: Any) -> bytes:
+ #have_object/get_item_user_data_list
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+
+ )
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ item_data = self.game_data.item.get_user_items(user_id)
+
+ resp = SaoGetItemUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, item_data)
+ return resp.make()
+
+ def handle_c606(self, request: Any) -> bytes:
+ #have_object/get_support_log_user_data_list
+ supportIdsData = self.game_data.static.get_support_log_ids(0, True)
+
+ resp = SaoGetSupportLogUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, supportIdsData)
+ return resp.make()
+
+ def handle_c800(self, request: Any) -> bytes:
+ #custom/get_title_user_data_list
+ titleIdsData = self.game_data.static.get_title_ids(0, True)
+
+ resp = SaoGetTitleUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, titleIdsData)
+ return resp.make()
+
+ def handle_c608(self, request: Any) -> bytes:
+ #have_object/get_episode_append_data_list
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ )
+
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ resp = SaoGetEpisodeAppendDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c804(self, request: Any) -> bytes:
+ #custom/get_party_data_list
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+
+ )
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ hero_party = self.game_data.item.get_hero_party(user_id, 0)
+ hero1_data = self.game_data.item.get_hero_log(user_id, hero_party[3])
+ hero2_data = self.game_data.item.get_hero_log(user_id, hero_party[4])
+ hero3_data = self.game_data.item.get_hero_log(user_id, hero_party[5])
+
+ resp = SaoGetPartyDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, hero1_data, hero2_data, hero3_data)
+ return resp.make()
+
+ def handle_c902(self, request: Any) -> bytes: # for whatever reason, having all entries empty or filled changes nothing
+ #quest/get_quest_scene_prev_scan_profile_card
+ resp = SaoGetQuestScenePrevScanProfileCardResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c124(self, request: Any) -> bytes:
+ #common/get_resource_path_info
+ resp = SaoGetResourcePathInfoResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c900(self, request: Any) -> bytes:
+ #quest/get_quest_scene_user_data_list // QuestScene.csv
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+
+ )
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+
+ quest_data = self.game_data.item.get_quest_logs(user_id)
+
+ resp = SaoGetQuestSceneUserDataListResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, quest_data)
+ return resp.make()
+
+ def handle_c400(self, request: Any) -> bytes:
+ #home/check_yui_medal_get_condition
+ resp = SaoCheckYuiMedalGetConditionResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c402(self, request: Any) -> bytes:
+ #home/get_yui_medal_bonus_user_data
+ resp = SaoGetYuiMedalBonusUserDataResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c40a(self, request: Any) -> bytes:
+ #home/check_profile_card_used_reward
+ resp = SaoCheckProfileCardUsedRewardResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c814(self, request: Any) -> bytes:
+ #custom/synthesize_enhancement_hero_log
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "origin_user_hero_log_id_size" / Rebuild(Int32ub, len_(this.origin_user_hero_log_id) * 2), # calculates the length of the origin_user_hero_log_id
+ "origin_user_hero_log_id" / PaddedString(this.origin_user_hero_log_id_size, "utf_16_le"), # origin_user_hero_log_id is a (zero) padded string
+ Padding(3),
+ "material_common_reward_user_data_list_length" / Rebuild(Int8ub, len_(this.material_common_reward_user_data_list)), # material_common_reward_user_data_list is a byte,
+ "material_common_reward_user_data_list" / Array(this.material_common_reward_user_data_list_length, Struct(
+ "common_reward_type" / Int16ub, # team_no is a byte
+ "user_common_reward_id_size" / Rebuild(Int32ub, len_(this.user_common_reward_id) * 2), # calculates the length of the user_common_reward_id
+ "user_common_reward_id" / PaddedString(this.user_common_reward_id_size, "utf_16_le"), # user_common_reward_id is a (zero) padded string
+ )),
+ )
+
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+ synthesize_hero_log_data = self.game_data.item.get_hero_log(req_data.user_id, req_data.origin_user_hero_log_id)
+
+ for i in range(0,req_data.material_common_reward_user_data_list_length):
+
+ itemList = self.game_data.static.get_item_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ heroList = self.game_data.static.get_hero_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ equipmentList = self.game_data.static.get_equipment_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if itemList:
+ hero_exp = 2000 + int(synthesize_hero_log_data["log_exp"])
+ self.game_data.item.remove_item(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if equipmentList:
+ equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ hero_exp = int(equipment_data["enhancement_exp"]) + int(synthesize_hero_log_data["log_exp"])
+ self.game_data.item.remove_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if heroList:
+ hero_data = self.game_data.item.get_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ hero_exp = int(hero_data["log_exp"]) + int(synthesize_hero_log_data["log_exp"])
+ self.game_data.item.remove_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ self.game_data.item.put_hero_log(
+ user_id,
+ int(req_data.origin_user_hero_log_id),
+ synthesize_hero_log_data["log_level"],
+ hero_exp,
+ synthesize_hero_log_data["main_weapon"],
+ synthesize_hero_log_data["sub_equipment"],
+ synthesize_hero_log_data["skill_slot1_skill_id"],
+ synthesize_hero_log_data["skill_slot2_skill_id"],
+ synthesize_hero_log_data["skill_slot3_skill_id"],
+ synthesize_hero_log_data["skill_slot4_skill_id"],
+ synthesize_hero_log_data["skill_slot5_skill_id"]
+ )
+
+ profile = self.game_data.profile.get_profile(req_data.user_id)
+ new_col = int(profile["own_col"]) - 100
+
+ # Update profile
+
+ self.game_data.profile.put_profile(
+ req_data.user_id,
+ profile["user_type"],
+ profile["nick_name"],
+ profile["rank_num"],
+ profile["rank_exp"],
+ new_col,
+ profile["own_vp"],
+ profile["own_yui_medal"],
+ profile["setting_title_id"]
+ )
+
+ # Load the item again to push to the response handler
+ synthesize_hero_log_data = self.game_data.item.get_hero_log(req_data.user_id, req_data.origin_user_hero_log_id)
+
+ resp = SaoSynthesizeEnhancementHeroLogResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, synthesize_hero_log_data)
+ return resp.make()
+
+ def handle_c816(self, request: Any) -> bytes:
+ #custom/synthesize_enhancement_equipment
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "origin_user_equipment_id_size" / Rebuild(Int32ub, len_(this.origin_user_equipment_id) * 2), # calculates the length of the origin_user_equipment_id
+ "origin_user_equipment_id" / PaddedString(this.origin_user_equipment_id_size, "utf_16_le"), # origin_user_equipment_id is a (zero) padded string
+ Padding(3),
+ "material_common_reward_user_data_list_length" / Rebuild(Int8ub, len_(this.material_common_reward_user_data_list)), # material_common_reward_user_data_list is a byte,
+ "material_common_reward_user_data_list" / Array(this.material_common_reward_user_data_list_length, Struct(
+ "common_reward_type" / Int16ub, # team_no is a byte
+ "user_common_reward_id_size" / Rebuild(Int32ub, len_(this.user_common_reward_id) * 2), # calculates the length of the user_common_reward_id
+ "user_common_reward_id" / PaddedString(this.user_common_reward_id_size, "utf_16_le"), # user_common_reward_id is a (zero) padded string
+ )),
+ )
+
+ req_data = req_struct.parse(req)
+
+ user_id = req_data.user_id
+ synthesize_equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id)
+
+ for i in range(0,req_data.material_common_reward_user_data_list_length):
+
+ itemList = self.game_data.static.get_item_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ heroList = self.game_data.static.get_hero_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ equipmentList = self.game_data.static.get_equipment_id(req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if itemList:
+ equipment_exp = 2000 + int(synthesize_equipment_data["enhancement_exp"])
+ self.game_data.item.remove_item(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if equipmentList:
+ equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ equipment_exp = int(equipment_data["enhancement_exp"]) + int(synthesize_equipment_data["enhancement_exp"])
+ self.game_data.item.remove_equipment(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ if heroList:
+ hero_data = self.game_data.item.get_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+ equipment_exp = int(hero_data["log_exp"]) + int(synthesize_equipment_data["enhancement_exp"])
+ self.game_data.item.remove_hero_log(req_data.user_id, req_data.material_common_reward_user_data_list[i].user_common_reward_id)
+
+ self.game_data.item.put_equipment_data(req_data.user_id, int(req_data.origin_user_equipment_id), synthesize_equipment_data["enhancement_value"], equipment_exp, 0, 0, 0)
+
+ profile = self.game_data.profile.get_profile(req_data.user_id)
+ new_col = int(profile["own_col"]) - 100
+
+ # Update profile
+
+ self.game_data.profile.put_profile(
+ req_data.user_id,
+ profile["user_type"],
+ profile["nick_name"],
+ profile["rank_num"],
+ profile["rank_exp"],
+ new_col,
+ profile["own_vp"],
+ profile["own_yui_medal"],
+ profile["setting_title_id"]
+ )
+
+ # Load the item again to push to the response handler
+ synthesize_equipment_data = self.game_data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id)
+
+ resp = SaoSynthesizeEnhancementEquipmentResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, synthesize_equipment_data)
+ return resp.make()
+
+ def handle_c806(self, request: Any) -> bytes:
+ #custom/change_party
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "act_type" / Int8ub, # play_mode is a byte
+ Padding(3),
+ "party_data_list_length" / Rebuild(Int8ub, len_(this.party_data_list)), # party_data_list is a byte,
+ "party_data_list" / Array(this.party_data_list_length, Struct(
+ "user_party_id_size" / Rebuild(Int32ub, len_(this.user_party_id) * 2), # calculates the length of the user_party_id
+ "user_party_id" / PaddedString(this.user_party_id_size, "utf_16_le"), # user_party_id is a (zero) padded string
+ "team_no" / Int8ub, # team_no is a byte
+ Padding(3),
+ "party_team_data_list_length" / Rebuild(Int8ub, len_(this.party_team_data_list)), # party_team_data_list is a byte
+ "party_team_data_list" / Array(this.party_team_data_list_length, Struct(
+ "user_party_team_id_size" / Rebuild(Int32ub, len_(this.user_party_team_id) * 2), # calculates the length of the user_party_team_id
+ "user_party_team_id" / PaddedString(this.user_party_team_id_size, "utf_16_le"), # user_party_team_id is a (zero) padded string
+ "arrangement_num" / Int8ub, # arrangement_num is a byte
+ "user_hero_log_id_size" / Rebuild(Int32ub, len_(this.user_hero_log_id) * 2), # calculates the length of the user_hero_log_id
+ "user_hero_log_id" / PaddedString(this.user_hero_log_id_size, "utf_16_le"), # user_hero_log_id is a (zero) padded string
+ "main_weapon_user_equipment_id_size" / Rebuild(Int32ub, len_(this.main_weapon_user_equipment_id) * 2), # calculates the length of the main_weapon_user_equipment_id
+ "main_weapon_user_equipment_id" / PaddedString(this.main_weapon_user_equipment_id_size, "utf_16_le"), # main_weapon_user_equipment_id is a (zero) padded string
+ "sub_equipment_user_equipment_id_size" / Rebuild(Int32ub, len_(this.sub_equipment_user_equipment_id) * 2), # calculates the length of the sub_equipment_user_equipment_id
+ "sub_equipment_user_equipment_id" / PaddedString(this.sub_equipment_user_equipment_id_size, "utf_16_le"), # sub_equipment_user_equipment_id is a (zero) padded string
+ "skill_slot1_skill_id" / Int32ub, # skill_slot1_skill_id is a int,
+ "skill_slot2_skill_id" / Int32ub, # skill_slot1_skill_id is a int,
+ "skill_slot3_skill_id" / Int32ub, # skill_slot1_skill_id is a int,
+ "skill_slot4_skill_id" / Int32ub, # skill_slot1_skill_id is a int,
+ "skill_slot5_skill_id" / Int32ub, # skill_slot1_skill_id is a int,
+ )),
+ )),
+
+ )
+
+ req_data = req_struct.parse(req)
+ user_id = req_data.user_id
+ party_hero_list = []
+
+ for party_team in req_data.party_data_list[0].party_team_data_list:
+ hero_data = self.game_data.item.get_hero_log(user_id, party_team["user_hero_log_id"])
+ hero_level = 1
+ hero_exp = 0
+
+ if hero_data:
+ hero_level = hero_data["log_level"]
+ hero_exp = hero_data["log_exp"]
+
+ self.game_data.item.put_hero_log(
+ user_id,
+ party_team["user_hero_log_id"],
+ hero_level,
+ hero_exp,
+ party_team["main_weapon_user_equipment_id"],
+ party_team["sub_equipment_user_equipment_id"],
+ party_team["skill_slot1_skill_id"],
+ party_team["skill_slot2_skill_id"],
+ party_team["skill_slot3_skill_id"],
+ party_team["skill_slot4_skill_id"],
+ party_team["skill_slot5_skill_id"]
+ )
+
+ party_hero_list.append(party_team["user_hero_log_id"])
+
+ self.game_data.item.put_hero_party(user_id, req_data.party_data_list[0].party_team_data_list[0].user_party_team_id, party_hero_list[0], party_hero_list[1], party_hero_list[2])
+
+ resp = SaoNoopResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c904(self, request: Any) -> bytes:
+ #quest/episode_play_start
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "episode_id" / Int32ub, # episode_id is a int,
+ "play_mode" / Int8ub, # play_mode is a byte
+ Padding(3),
+ "play_start_request_data_length" / Rebuild(Int8ub, len_(this.play_start_request_data)), # play_start_request_data_length is a byte,
+ "play_start_request_data" / Array(this.play_start_request_data_length, Struct(
+ "user_party_id_size" / Rebuild(Int32ub, len_(this.user_party_id) * 2), # calculates the length of the user_party_id
+ "user_party_id" / PaddedString(this.user_party_id_size, "utf_16_le"), # user_party_id is a (zero) padded string
+ "appoint_leader_resource_card_code_size" / Rebuild(Int32ub, len_(this.appoint_leader_resource_card_code) * 2), # calculates the length of the total_damage
+ "appoint_leader_resource_card_code" / PaddedString(this.appoint_leader_resource_card_code_size, "utf_16_le"), # total_damage is a (zero) padded string
+ "use_profile_card_code_size" / Rebuild(Int32ub, len_(this.use_profile_card_code) * 2), # calculates the length of the total_damage
+ "use_profile_card_code" / PaddedString(this.use_profile_card_code_size, "utf_16_le"), # use_profile_card_code is a (zero) padded string
+ "quest_drop_boost_apply_flag" / Int8ub, # quest_drop_boost_apply_flag is a byte
+ )),
+
+ )
+
+ req_data = req_struct.parse(req)
+
+ user_id = req_data.user_id
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ self.game_data.item.create_session(
+ user_id,
+ int(req_data.play_start_request_data[0].user_party_id),
+ req_data.episode_id,
+ req_data.play_mode,
+ req_data.play_start_request_data[0].quest_drop_boost_apply_flag
+ )
+
+ resp = SaoEpisodePlayStartResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c908(self, request: Any) -> bytes: # Level calculation missing for the profile and heroes
+ #quest/episode_play_end
+
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ Padding(2),
+ "episode_id" / Int16ub, # episode_id is a short,
+ Padding(3),
+ "play_end_request_data" / Int8ub, # play_end_request_data is a byte
+ Padding(1),
+ "play_result_flag" / Int8ub, # play_result_flag is a byte
+ Padding(2),
+ "base_get_data_length" / Rebuild(Int8ub, len_(this.base_get_data)), # base_get_data_length is a byte,
+ "base_get_data" / Array(this.base_get_data_length, Struct(
+ "get_hero_log_exp" / Int32ub, # get_hero_log_exp is an int
+ "get_col" / Int32ub, # get_num is a short
+ )),
+ Padding(3),
+ "get_player_trace_data_list_length" / Rebuild(Int8ub, len_(this.get_player_trace_data_list)), # get_player_trace_data_list_length is a byte
+ "get_player_trace_data_list" / Array(this.get_player_trace_data_list_length, Struct(
+ "user_quest_scene_player_trace_id" / Int32ub, # user_quest_scene_player_trace_id is an int
+ )),
+ Padding(3),
+ "get_rare_drop_data_list_length" / Rebuild(Int8ub, len_(this.get_rare_drop_data_list)), # get_rare_drop_data_list_length is a byte
+ "get_rare_drop_data_list" / Array(this.get_rare_drop_data_list_length, Struct(
+ "quest_rare_drop_id" / Int32ub, # quest_rare_drop_id is an int
+ )),
+ Padding(3),
+ "get_special_rare_drop_data_list_length" / Rebuild(Int8ub, len_(this.get_special_rare_drop_data_list)), # get_special_rare_drop_data_list_length is a byte
+ "get_special_rare_drop_data_list" / Array(this.get_special_rare_drop_data_list_length, Struct(
+ "quest_special_rare_drop_id" / Int32ub, # quest_special_rare_drop_id is an int
+ )),
+ Padding(3),
+ "get_unanalyzed_log_tmp_reward_data_list_length" / Rebuild(Int8ub, len_(this.get_unanalyzed_log_tmp_reward_data_list)), # get_unanalyzed_log_tmp_reward_data_list_length is a byte
+ "get_unanalyzed_log_tmp_reward_data_list" / Array(this.get_unanalyzed_log_tmp_reward_data_list_length, Struct(
+ "unanalyzed_log_grade_id" / Int32ub, # unanalyzed_log_grade_id is an int,
+ )),
+ Padding(3),
+ "get_event_item_data_list_length" / Rebuild(Int8ub, len_(this.get_event_item_data_list)), # get_event_item_data_list_length is a byte,
+ "get_event_item_data_list" / Array(this.get_event_item_data_list_length, Struct(
+ "event_item_id" / Int32ub, # event_item_id is an int
+ "get_num" / Int16ub, # get_num is a short
+ )),
+ Padding(3),
+ "discovery_enemy_data_list_length" / Rebuild(Int8ub, len_(this.discovery_enemy_data_list)), # discovery_enemy_data_list_length is a byte
+ "discovery_enemy_data_list" / Array(this.discovery_enemy_data_list_length, Struct(
+ "enemy_kind_id" / Int32ub, # enemy_kind_id is an int
+ "destroy_num" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "destroy_boss_data_list_length" / Rebuild(Int8ub, len_(this.destroy_boss_data_list)), # destroy_boss_data_list_length is a byte
+ "destroy_boss_data_list" / Array(this.destroy_boss_data_list_length, Struct(
+ "boss_type" / Int8ub, # boss_type is a byte
+ "enemy_kind_id" / Int32ub, # enemy_kind_id is an int
+ "destroy_num" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "mission_data_list_length" / Rebuild(Int8ub, len_(this.mission_data_list)), # mission_data_list_length is a byte
+ "mission_data_list" / Array(this.mission_data_list_length, Struct(
+ "mission_id" / Int32ub, # enemy_kind_id is an int
+ "clear_flag" / Int8ub, # boss_type is a byte
+ "mission_difficulty_id" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "score_data_length" / Rebuild(Int8ub, len_(this.score_data)), # score_data_length is a byte
+ "score_data" / Array(this.score_data_length, Struct(
+ "clear_time" / Int32ub, # clear_time is an int
+ "combo_num" / Int32ub, # boss_type is a int
+ "total_damage_size" / Rebuild(Int32ub, len_(this.total_damage) * 2), # calculates the length of the total_damage
+ "total_damage" / PaddedString(this.total_damage_size, "utf_16_le"), # total_damage is a (zero) padded string
+ "concurrent_destroying_num" / Int16ub, # concurrent_destroying_num is a short
+ "reaching_skill_level" / Int16ub, # reaching_skill_level is a short
+ "ko_chara_num" / Int8ub, # ko_chara_num is a byte
+ "acceleration_invocation_num" / Int16ub, # acceleration_invocation_num is a short
+ "boss_destroying_num" / Int16ub, # boss_destroying_num is a short
+ "synchro_skill_used_flag" / Int8ub, # synchro_skill_used_flag is a byte
+ "used_friend_skill_id" / Int32ub, # used_friend_skill_id is an int
+ "friend_skill_used_flag" / Int8ub, # friend_skill_used_flag is a byte
+ "continue_cnt" / Int16ub, # continue_cnt is a short
+ "total_loss_num" / Int16ub, # total_loss_num is a short
+ )),
+
+ )
+
+ req_data = req_struct.parse(req)
+
+ # Add stage progression to database
+ user_id = req_data.user_id
+ episode_id = req_data.episode_id
+ quest_clear_flag = bool(req_data.score_data[0].boss_destroying_num)
+ clear_time = req_data.score_data[0].clear_time
+ combo_num = req_data.score_data[0].combo_num
+ total_damage = req_data.score_data[0].total_damage
+ concurrent_destroying_num = req_data.score_data[0].concurrent_destroying_num
+
+ profile = self.game_data.profile.get_profile(user_id)
+ vp = int(profile["own_vp"])
+ exp = int(profile["rank_exp"]) + 100 #always 100 extra exp for some reason
+ col = int(profile["own_col"]) + int(req_data.base_get_data[0].get_col)
+
+ if quest_clear_flag is True:
+ # Save stage progression - to be revised to avoid saving worse score
+
+ # Reference Episode.csv but Chapter 3,4 and 5 reports id 0
+ if episode_id > 10000 and episode_id < 11000:
+ episode_id = episode_id - 9000
+ elif episode_id > 20000 and episode_id < 21000:
+ episode_id = episode_id - 19000
+ elif episode_id > 30000 and episode_id < 31000:
+ episode_id = episode_id - 29000
+
+ self.game_data.item.put_player_quest(user_id, episode_id, quest_clear_flag, clear_time, combo_num, total_damage, concurrent_destroying_num)
+
+ vp = int(profile["own_vp"]) + 10 #always 10 VP per cleared stage
+
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/PlayerRank.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ for i in range(0,len(data)):
+ if exp>=int(data[i][1]) and exp=int(data[e][1]) and log_exp bytes:
+ #quest/trial_tower_play_start
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(16),
+ "ticket_id_size" / Rebuild(Int32ub, len_(this.ticket_id) * 2), # calculates the length of the ticket_id
+ "ticket_id" / PaddedString(this.ticket_id_size, "utf_16_le"), # ticket_id is a (zero) padded string
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "trial_tower_id" / Int32ub, # trial_tower_id is an int
+ "play_mode" / Int8ub, # play_mode is a byte
+ Padding(3),
+ "play_start_request_data_length" / Rebuild(Int8ub, len_(this.play_start_request_data)), # play_start_request_data_length is a byte,
+ "play_start_request_data" / Array(this.play_start_request_data_length, Struct(
+ "user_party_id_size" / Rebuild(Int32ub, len_(this.user_party_id) * 2), # calculates the length of the user_party_id
+ "user_party_id" / PaddedString(this.user_party_id_size, "utf_16_le"), # user_party_id is a (zero) padded string
+ "appoint_leader_resource_card_code_size" / Rebuild(Int32ub, len_(this.appoint_leader_resource_card_code) * 2), # calculates the length of the total_damage
+ "appoint_leader_resource_card_code" / PaddedString(this.appoint_leader_resource_card_code_size, "utf_16_le"), # total_damage is a (zero) padded string
+ "use_profile_card_code_size" / Rebuild(Int32ub, len_(this.use_profile_card_code) * 2), # calculates the length of the total_damage
+ "use_profile_card_code" / PaddedString(this.use_profile_card_code_size, "utf_16_le"), # use_profile_card_code is a (zero) padded string
+ "quest_drop_boost_apply_flag" / Int8ub, # quest_drop_boost_apply_flag is a byte
+ )),
+ )
+
+ req_data = req_struct.parse(req)
+
+ user_id = req_data.user_id
+ floor_id = req_data.trial_tower_id
+ profile_data = self.game_data.profile.get_profile(user_id)
+
+ self.game_data.item.create_session(
+ user_id,
+ int(req_data.play_start_request_data[0].user_party_id),
+ req_data.trial_tower_id,
+ req_data.play_mode,
+ req_data.play_start_request_data[0].quest_drop_boost_apply_flag
+ )
+
+ resp = SaoEpisodePlayStartResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1, profile_data)
+ return resp.make()
+
+ def handle_c918(self, request: Any) -> bytes:
+ #quest/trial_tower_play_end
+ req = bytes.fromhex(request)[24:]
+
+ req_struct = Struct(
+ Padding(20),
+ "ticket_id" / Bytes(1), # needs to be parsed as an int
+ Padding(1),
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ Padding(2),
+ "trial_tower_id" / Int16ub, # trial_tower_id is a short,
+ Padding(3),
+ "play_end_request_data" / Int8ub, # play_end_request_data is a byte
+ Padding(1),
+ "play_result_flag" / Int8ub, # play_result_flag is a byte
+ Padding(2),
+ "base_get_data_length" / Rebuild(Int8ub, len_(this.base_get_data)), # base_get_data_length is a byte,
+ "base_get_data" / Array(this.base_get_data_length, Struct(
+ "get_hero_log_exp" / Int32ub, # get_hero_log_exp is an int
+ "get_col" / Int32ub, # get_num is a short
+ )),
+ Padding(3),
+ "get_player_trace_data_list_length" / Rebuild(Int8ub, len_(this.get_player_trace_data_list)), # get_player_trace_data_list_length is a byte
+ "get_player_trace_data_list" / Array(this.get_player_trace_data_list_length, Struct(
+ "user_quest_scene_player_trace_id" / Int32ub, # user_quest_scene_player_trace_id is an int
+ )),
+ Padding(3),
+ "get_rare_drop_data_list_length" / Rebuild(Int8ub, len_(this.get_rare_drop_data_list)), # get_rare_drop_data_list_length is a byte
+ "get_rare_drop_data_list" / Array(this.get_rare_drop_data_list_length, Struct(
+ "quest_rare_drop_id" / Int32ub, # quest_rare_drop_id is an int
+ )),
+ Padding(3),
+ "get_special_rare_drop_data_list_length" / Rebuild(Int8ub, len_(this.get_special_rare_drop_data_list)), # get_special_rare_drop_data_list_length is a byte
+ "get_special_rare_drop_data_list" / Array(this.get_special_rare_drop_data_list_length, Struct(
+ "quest_special_rare_drop_id" / Int32ub, # quest_special_rare_drop_id is an int
+ )),
+ Padding(3),
+ "get_unanalyzed_log_tmp_reward_data_list_length" / Rebuild(Int8ub, len_(this.get_unanalyzed_log_tmp_reward_data_list)), # get_unanalyzed_log_tmp_reward_data_list_length is a byte
+ "get_unanalyzed_log_tmp_reward_data_list" / Array(this.get_unanalyzed_log_tmp_reward_data_list_length, Struct(
+ "unanalyzed_log_grade_id" / Int32ub, # unanalyzed_log_grade_id is an int,
+ )),
+ Padding(3),
+ "get_event_item_data_list_length" / Rebuild(Int8ub, len_(this.get_event_item_data_list)), # get_event_item_data_list_length is a byte,
+ "get_event_item_data_list" / Array(this.get_event_item_data_list_length, Struct(
+ "event_item_id" / Int32ub, # event_item_id is an int
+ "get_num" / Int16ub, # get_num is a short
+ )),
+ Padding(3),
+ "discovery_enemy_data_list_length" / Rebuild(Int8ub, len_(this.discovery_enemy_data_list)), # discovery_enemy_data_list_length is a byte
+ "discovery_enemy_data_list" / Array(this.discovery_enemy_data_list_length, Struct(
+ "enemy_kind_id" / Int32ub, # enemy_kind_id is an int
+ "destroy_num" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "destroy_boss_data_list_length" / Rebuild(Int8ub, len_(this.destroy_boss_data_list)), # destroy_boss_data_list_length is a byte
+ "destroy_boss_data_list" / Array(this.destroy_boss_data_list_length, Struct(
+ "boss_type" / Int8ub, # boss_type is a byte
+ "enemy_kind_id" / Int32ub, # enemy_kind_id is an int
+ "destroy_num" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "mission_data_list_length" / Rebuild(Int8ub, len_(this.mission_data_list)), # mission_data_list_length is a byte
+ "mission_data_list" / Array(this.mission_data_list_length, Struct(
+ "mission_id" / Int32ub, # enemy_kind_id is an int
+ "clear_flag" / Int8ub, # boss_type is a byte
+ "mission_difficulty_id" / Int16ub, # destroy_num is a short
+ )),
+ Padding(3),
+ "score_data_length" / Rebuild(Int8ub, len_(this.score_data)), # score_data_length is a byte
+ "score_data" / Array(this.score_data_length, Struct(
+ "clear_time" / Int32ub, # clear_time is an int
+ "combo_num" / Int32ub, # boss_type is a int
+ "total_damage_size" / Rebuild(Int32ub, len_(this.total_damage) * 2), # calculates the length of the total_damage
+ "total_damage" / PaddedString(this.total_damage_size, "utf_16_le"), # total_damage is a (zero) padded string
+ "concurrent_destroying_num" / Int16ub, # concurrent_destroying_num is a short
+ "reaching_skill_level" / Int16ub, # reaching_skill_level is a short
+ "ko_chara_num" / Int8ub, # ko_chara_num is a byte
+ "acceleration_invocation_num" / Int16ub, # acceleration_invocation_num is a short
+ "boss_destroying_num" / Int16ub, # boss_destroying_num is a short
+ "synchro_skill_used_flag" / Int8ub, # synchro_skill_used_flag is a byte
+ "used_friend_skill_id" / Int32ub, # used_friend_skill_id is an int
+ "friend_skill_used_flag" / Int8ub, # friend_skill_used_flag is a byte
+ "continue_cnt" / Int16ub, # continue_cnt is a short
+ "total_loss_num" / Int16ub, # total_loss_num is a short
+ )),
+
+ )
+
+ req_data = req_struct.parse(req)
+
+ # Add tower progression to database
+ user_id = req_data.user_id
+ trial_tower_id = req_data.trial_tower_id
+ next_tower_id = 0
+ quest_clear_flag = bool(req_data.score_data[0].boss_destroying_num)
+ clear_time = req_data.score_data[0].clear_time
+ combo_num = req_data.score_data[0].combo_num
+ total_damage = req_data.score_data[0].total_damage
+ concurrent_destroying_num = req_data.score_data[0].concurrent_destroying_num
+
+ if quest_clear_flag is True:
+ # Save tower progression - to be revised to avoid saving worse score
+ if trial_tower_id == 9:
+ next_tower_id = 10001
+ elif trial_tower_id == 10:
+ trial_tower_id = 10001
+ next_tower_id = 3011
+ elif trial_tower_id == 19:
+ next_tower_id = 10002
+ elif trial_tower_id == 20:
+ trial_tower_id = 10002
+ next_tower_id = 3021
+ elif trial_tower_id == 29:
+ next_tower_id = 10003
+ elif trial_tower_id == 30:
+ trial_tower_id = 10003
+ next_tower_id = 3031
+ elif trial_tower_id == 39:
+ next_tower_id = 10004
+ elif trial_tower_id == 40:
+ trial_tower_id = 10004
+ next_tower_id = 3041
+ elif trial_tower_id == 49:
+ next_tower_id = 10005
+ elif trial_tower_id == 50:
+ trial_tower_id = 10005
+ next_tower_id = 3051
+ else:
+ trial_tower_id = trial_tower_id + 3000
+ next_tower_id = trial_tower_id + 1
+
+ self.game_data.item.put_player_quest(user_id, trial_tower_id, quest_clear_flag, clear_time, combo_num, total_damage, concurrent_destroying_num)
+
+ # Check if next stage is already done
+ checkQuest = self.game_data.item.get_quest_log(user_id, next_tower_id)
+ if not checkQuest:
+ if next_tower_id != 3101:
+ self.game_data.item.put_player_quest(user_id, next_tower_id, 0, 0, 0, 0, 0)
+
+ # Update the profile
+ profile = self.game_data.profile.get_profile(user_id)
+
+ exp = int(profile["rank_exp"]) + 100 #always 100 extra exp for some reason
+ col = int(profile["own_col"]) + int(req_data.base_get_data[0].get_col)
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/PlayerRank.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ for i in range(0,len(data)):
+ if exp>=int(data[i][1]) and exp=int(data[e][1]) and log_exp bytes: #should be tweaked for proper item unlock
+ #quest/episode_play_end_unanalyzed_log_fixed
+ resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
+
+ def handle_c91a(self, request: Any) -> bytes: # handler is identical to the episode
+ #quest/trial_tower_play_end_unanalyzed_log_fixed
+ resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(int.from_bytes(bytes.fromhex(request[:4]), "big")+1)
+ return resp.make()
diff --git a/titles/sao/config.py b/titles/sao/config.py
new file mode 100644
index 0000000..7b9a2d5
--- /dev/null
+++ b/titles/sao/config.py
@@ -0,0 +1,47 @@
+from core.config import CoreConfig
+
+
+class SaoServerConfig:
+ def __init__(self, parent_config: "SaoConfig"):
+ self.__config = parent_config
+
+ @property
+ def hostname(self) -> str:
+ return CoreConfig.get_config_field(
+ self.__config, "sao", "server", "hostname", default="localhost"
+ )
+
+ @property
+ def enable(self) -> bool:
+ return CoreConfig.get_config_field(
+ self.__config, "sao", "server", "enable", default=True
+ )
+
+ @property
+ def loglevel(self) -> int:
+ return CoreConfig.str_to_loglevel(
+ CoreConfig.get_config_field(
+ self.__config, "sao", "server", "loglevel", default="info"
+ )
+ )
+
+ @property
+ def port(self) -> int:
+ return CoreConfig.get_config_field(
+ self.__config, "sao", "server", "port", default=9000
+ )
+
+ @property
+ def auto_register(self) -> bool:
+ """
+ Automatically register users in `aime_user` on first carding in with sao
+ if they don't exist already. Set to false to display an error instead.
+ """
+ return CoreConfig.get_config_field(
+ self.__config, "sao", "server", "auto_register", default=True
+ )
+
+
+class SaoConfig(dict):
+ def __init__(self) -> None:
+ self.server = SaoServerConfig(self)
diff --git a/titles/sao/const.py b/titles/sao/const.py
new file mode 100644
index 0000000..8bdea0f
--- /dev/null
+++ b/titles/sao/const.py
@@ -0,0 +1,15 @@
+from enum import Enum
+
+
+class SaoConstants:
+ GAME_CODE = "SDEW"
+
+ CONFIG_NAME = "sao.yaml"
+
+ VER_SAO = 0
+
+ VERSION_NAMES = ("Sword Art Online Arcade")
+
+ @classmethod
+ def game_ver_to_string(cls, ver: int):
+ return cls.VERSION_NAMES[ver]
diff --git a/titles/sao/data/EquipmentLevel.csv b/titles/sao/data/EquipmentLevel.csv
new file mode 100644
index 0000000..803bf7e
--- /dev/null
+++ b/titles/sao/data/EquipmentLevel.csv
@@ -0,0 +1,121 @@
+EquipmentLevelId,RequireExp
+1,200,
+2,400,
+3,600,
+4,800,
+5,1000,
+6,1200,
+7,1400,
+8,1600,
+9,1800,
+10,2000,
+11,2200,
+12,2400,
+13,2600,
+14,2800,
+15,3000,
+16,3200,
+17,3400,
+18,3600,
+19,3800,
+20,4000,
+21,4200,
+22,4400,
+23,4600,
+24,4800,
+25,5000,
+26,5200,
+27,5400,
+28,5600,
+29,5800,
+30,6000,
+31,6200,
+32,6400,
+33,6600,
+34,6800,
+35,7000,
+36,7200,
+37,7400,
+38,7600,
+39,7800,
+40,8000,
+41,8200,
+42,8400,
+43,8600,
+44,8800,
+45,9000,
+46,9200,
+47,9400,
+48,9600,
+49,9800,
+50,10000,
+51,10200,
+52,10400,
+53,10600,
+54,10800,
+55,11000,
+56,11200,
+57,11400,
+58,11600,
+59,11800,
+60,12000,
+61,12200,
+62,12400,
+63,12600,
+64,12800,
+65,13000,
+66,13200,
+67,13400,
+68,13600,
+69,13800,
+70,14000,
+71,14200,
+72,14400,
+73,14600,
+74,14800,
+75,15000,
+76,15200,
+77,15400,
+78,15600,
+79,15800,
+80,16000,
+81,16200,
+82,16400,
+83,16600,
+84,16800,
+85,17000,
+86,17200,
+87,17400,
+88,17600,
+89,17800,
+90,18000,
+91,18200,
+92,18400,
+93,18600,
+94,18800,
+95,19000,
+96,19200,
+97,19400,
+98,19600,
+99,19800,
+100,100000,
+101,150000,
+102,200000,
+103,250000,
+104,300000,
+105,350000,
+106,400000,
+107,450000,
+108,500000,
+109,550000,
+110,600000,
+111,650000,
+112,700000,
+113,750000,
+114,800000,
+115,850000,
+116,900000,
+117,950000,
+118,1000000,
+119,1000000,
+120,1000000,
diff --git a/titles/sao/data/HeroLogLevel.csv b/titles/sao/data/HeroLogLevel.csv
new file mode 100644
index 0000000..36a53b9
--- /dev/null
+++ b/titles/sao/data/HeroLogLevel.csv
@@ -0,0 +1,121 @@
+HeroLogLevelId,RequireExp
+1,0,
+2,1000,
+3,1200,
+4,1400,
+5,1600,
+6,1900,
+7,2200,
+8,2500,
+9,2800,
+10,3100,
+11,3500,
+12,3900,
+13,4300,
+14,4700,
+15,5100,
+16,5550,
+17,6000,
+18,6450,
+19,6900,
+20,7350,
+21,7850,
+22,8350,
+23,8850,
+24,9350,
+25,9850,
+26,10450,
+27,11050,
+28,11650,
+29,12250,
+30,12850,
+31,13550,
+32,14250,
+33,14950,
+34,15650,
+35,16350,
+36,17150,
+37,17950,
+38,18750,
+39,19550,
+40,20350,
+41,21250,
+42,22150,
+43,23050,
+44,23950,
+45,24850,
+46,25850,
+47,26850,
+48,27850,
+49,28850,
+50,29850,
+51,30950,
+52,32050,
+53,33150,
+54,34250,
+55,35350,
+56,36550,
+57,37750,
+58,38950,
+59,40150,
+60,41350,
+61,42650,
+62,43950,
+63,45250,
+64,46550,
+65,47850,
+66,49250,
+67,50650,
+68,52050,
+69,53450,
+70,54850,
+71,56350,
+72,57850,
+73,59350,
+74,60850,
+75,62350,
+76,63950,
+77,65550,
+78,67150,
+79,68750,
+80,70350,
+81,72050,
+82,73750,
+83,75450,
+84,77150,
+85,78850,
+86,80650,
+87,82450,
+88,84250,
+89,86050,
+90,87850,
+91,89750,
+92,91650,
+93,93550,
+94,95450,
+95,97350,
+96,99350,
+97,101350,
+98,103350,
+99,105350,
+100,107350,
+101,200000,
+102,300000,
+103,450000,
+104,600000,
+105,800000,
+106,1000000,
+107,1250000,
+108,1500000,
+109,1800000,
+110,2100000,
+111,2100000,
+112,2100000,
+113,2100000,
+114,2100000,
+115,2100000,
+116,2100000,
+117,2100000,
+118,2100000,
+119,2100000,
+120,2100000,
diff --git a/titles/sao/data/PlayerRank.csv b/titles/sao/data/PlayerRank.csv
new file mode 100644
index 0000000..9031661
--- /dev/null
+++ b/titles/sao/data/PlayerRank.csv
@@ -0,0 +1,301 @@
+PlayerRankId,TotalExp,
+1,0,
+2,100,
+3,300,
+4,500,
+5,800,
+6,1100,
+7,1400,
+8,1800,
+9,2200,
+10,2600,,
+11,3000,,
+12,3500,,
+13,4000,,
+14,4500,,
+15,5000,,
+16,5500,,
+17,6100,,
+18,6700,,
+19,7300,,
+20,7900,,
+21,8500,,
+22,9100,,
+23,9800,,
+24,10500,
+25,11200,
+26,11900,
+27,12600,
+28,13300,
+29,14000,
+30,14800,
+31,15600,
+32,16400,
+33,17200,
+34,18000,
+35,18800,
+36,19600,
+37,20400,
+38,21300,
+39,22200,
+40,23100,
+41,24000,
+42,24900,
+43,25800,
+44,26700,
+45,27600,
+46,28500,
+47,29500,
+48,30600,
+49,31800,
+50,33100,
+51,34500,
+52,36000,
+53,37600,
+54,39300,
+55,41100,
+56,43000,
+57,45000,
+58,47100,
+59,49300,
+60,51600,
+61,54000,
+62,56500,
+63,59100,
+64,61800,
+65,64600,
+66,67500,
+67,70500,
+68,73600,
+69,76800,
+70,80100,
+71,83500,
+72,87000,
+73,90600,
+74,94300,
+75,98100,
+76,102000,
+77,106000,
+78,110100,
+79,114300,
+80,118600,
+81,123000,
+82,127500,
+83,132100,
+84,136800,
+85,141600,
+86,146500,
+87,151500,
+88,156600,
+89,161800,
+90,167100,
+91,172500,
+92,178000,
+93,183600,
+94,189300,
+95,195100,
+96,201000,
+97,207000,
+98,213100,
+99,219300,
+100,225600,
+101,232000,
+102,238500,
+103,245100,
+104,251800,
+105,258600,
+106,265500,
+107,272500,
+108,279600,
+109,286800,
+110,294100,
+111,301500,
+112,309000,
+113,316600,
+114,324300,
+115,332100,
+116,340000,
+117,348000,
+118,356100,
+119,364300,
+120,372600,
+121,381000,
+122,389500,
+123,398100,
+124,406800,
+125,415600,
+126,424500,
+127,433500,
+128,442600,
+129,451800,
+130,461100,
+131,470500,
+132,480000,
+133,489600,
+134,499300,
+135,509100,
+136,519000,
+137,529000,
+138,539100,
+139,549300,
+140,559600,
+141,570000,
+142,580500,
+143,591100,
+144,601800,
+145,612600,
+146,623500,
+147,634500,
+148,645600,
+149,656800,
+150,668100,
+151,679500,
+152,691000,
+153,702600,
+154,714300,
+155,726100,
+156,738000,
+157,750000,
+158,762100,
+159,774300,
+160,786600,
+161,799000,
+162,811500,
+163,824100,
+164,836800,
+165,849600,
+166,862500,
+167,875500,
+168,888600,
+169,901800,
+170,915100,
+171,928500,
+172,942000,
+173,955600,
+174,969300,
+175,983100,
+176,997000,
+177,1011000,
+178,1025100,
+179,1039300,
+180,1053600,
+181,1068000,
+182,1082500,
+183,1097100,
+184,1111800,
+185,1126600,
+186,1141500,
+187,1156500,
+188,1171600,
+189,1186800,
+190,1202100,
+191,1217500,
+192,1233000,
+193,1248600,
+194,1264300,
+195,1280100,
+196,1296000,
+197,1312000,
+198,1328100,
+199,1344300,
+200,1360600,
+201,1377000,
+202,1393500,
+203,1410100,
+204,1426800,
+205,1443600,
+206,1460500,
+207,1477500,
+208,1494600,
+209,1511800,
+210,1529100,
+211,1546500,
+212,1564000,
+213,1581600,
+214,1599300,
+215,1617100,
+216,1635000,
+217,1653000,
+218,1671100,
+219,1689300,
+220,1707600,
+221,1726000,
+222,1744500,
+223,1763100,
+224,1781800,
+225,1800600,
+226,1819500,
+227,1838500,
+228,1857600,
+229,1876800,
+230,1896100,
+231,1915500,
+232,1935000,
+233,1954600,
+234,1974300,
+235,1994100,
+236,2014000,
+237,2034000,
+238,2054100,
+239,2074300,
+240,2094600,
+241,2115000,
+242,2135500,
+243,2156100,
+244,2176800,
+245,2197600,
+246,2218500,
+247,2239500,
+248,2260600,
+249,2281800,
+250,2303100,
+251,2324500,
+252,2346000,
+253,2367600,
+254,2389300,
+255,2411100,
+256,2433000,
+257,2455000,
+258,2477100,
+259,2499300,
+260,2521600,
+261,2544000,
+262,2566500,
+263,2589100,
+264,2611800,
+265,2634600,
+266,2657500,
+267,2680500,
+268,2703600,
+269,2726800,
+270,2750100,
+271,2773500,
+272,2797000,
+273,2820600,
+274,2844300,
+275,2868100,
+276,2892000,
+277,2916000,
+278,2940100,
+279,2964300,
+280,2988600,
+281,3013000,
+282,3037500,
+283,3062100,
+284,3086800,
+285,3111600,
+286,3136500,
+287,3161500,
+288,3186600,
+289,3211800,
+290,3237100,
+291,3262500,
+292,3288000,
+293,3313600,
+294,3339300,
+295,3365100,
+296,3391000,
+297,3417000,
+298,3443100,
+299,3469300,
+300,3495600,
diff --git a/titles/sao/data/RewardTable.csv b/titles/sao/data/RewardTable.csv
new file mode 100644
index 0000000..acce5bd
--- /dev/null
+++ b/titles/sao/data/RewardTable.csv
@@ -0,0 +1,17274 @@
+RewardTableId,UnanalyzedLogGradeId,CommonRewardId
+142,1,101000000
+143,2,101000001
+144,3,101000002
+145,4,101000008
+146,5,101000004
+147,1,102000000
+148,2,102000001
+149,3,102000002
+150,4,102000003
+151,5,102000004
+152,1,103000000
+153,2,103000001
+154,3,103000002
+155,4,103000003
+156,5,103000004
+157,1,105000000
+158,2,105000001
+159,3,105000002
+160,4,105000003
+161,5,105000004
+162,1,108000000
+163,2,108000001
+164,3,108000002
+165,4,108000003
+166,5,108000004
+167,1,109000000
+168,2,109000001
+169,3,109000002
+170,4,109000003
+171,5,109000004
+172,1,111000000
+173,2,111000001
+174,3,111000002
+175,4,111000003
+176,5,111000004
+177,1,112000000
+178,2,112000001
+179,3,112000002
+180,4,112000003
+181,5,112000004
+182,1,120000000
+183,2,120000001
+184,3,120000002
+185,4,120000003
+186,5,120000004
+187,1,101000010
+188,2,101000030
+189,3,101000040
+190,1,102000010
+191,2,102000030
+192,3,102000070
+193,1,103000010
+194,2,103000040
+195,3,103000070
+196,1,104000010
+197,2,104000030
+198,3,104000070
+199,1,105000010
+200,2,105000040
+201,3,105000070
+202,1,106000010
+203,2,106000030
+204,3,106000070
+205,1,107000010
+206,2,107000040
+207,3,107000070
+208,1,108000010
+209,2,108000030
+210,3,108000050
+212,1,101000000
+213,2,101000001
+214,3,101000002
+215,4,101000008
+216,5,101000004
+218,1,101000000
+219,2,101000001
+220,3,101000002
+221,4,101000008
+222,5,101000004
+223,1,102000000
+224,2,102000001
+225,3,102000002
+226,4,102000003
+227,5,102000004
+228,1,103000000
+229,2,103000001
+230,3,103000002
+231,4,103000003
+232,5,103000004
+233,1,105000000
+234,2,105000001
+235,3,105000002
+236,4,105000003
+237,5,105000004
+238,1,108000000
+239,2,108000001
+240,3,108000002
+241,4,108000003
+242,5,108000004
+243,1,109000000
+244,2,109000001
+245,3,109000002
+246,4,109000003
+247,5,109000004
+248,1,111000000
+249,2,111000001
+250,3,111000002
+251,4,111000003
+252,5,111000004
+253,1,112000000
+254,2,112000001
+255,3,112000002
+256,4,112000003
+257,5,112000004
+258,1,120000000
+259,2,120000001
+260,3,120000002
+261,4,120000003
+262,5,120000004
+263,1,101000010
+264,2,101000020
+265,2,101000030
+266,3,101000040
+267,3,101000050
+268,3,101000060
+269,3,101000070
+270,3,101000080
+271,1,102000010
+272,2,102000020
+273,2,102000030
+274,2,102000040
+275,3,102000050
+276,3,102000060
+277,3,102000070
+278,3,102000080
+279,1,103000010
+280,2,103000020
+281,2,103000030
+282,2,103000040
+283,3,103000050
+284,3,103000060
+285,3,103000070
+286,3,103000080
+287,1,104000010
+288,2,104000020
+289,2,104000030
+290,2,104000040
+291,3,104000050
+292,3,104000060
+293,3,104000070
+294,3,104000080
+295,1,105000010
+296,2,105000020
+297,2,105000030
+298,2,105000040
+299,3,105000050
+300,3,105000060
+301,3,105000070
+302,3,105000080
+303,1,106000010
+304,2,106000020
+305,2,106000030
+306,2,106000040
+307,3,106000050
+308,3,106000060
+309,3,106000070
+310,3,106000080
+311,1,107000010
+312,2,107000020
+313,2,107000030
+314,2,107000040
+315,3,107000050
+316,3,107000060
+317,3,107000070
+318,3,107000080
+319,1,108000010
+320,2,108000020
+321,2,108000030
+322,2,108000040
+323,3,108000050
+324,3,108000060
+325,3,108000070
+326,3,108000080
+327,2,180000
+329,1,101000000
+330,2,101000001
+331,3,101000002
+332,4,101000008
+333,5,101000004
+334,1,102000000
+335,2,102000001
+336,3,102000002
+337,4,102000003
+338,5,102000004
+339,1,103000000
+340,2,103000001
+341,3,103000002
+342,4,103000003
+343,5,103000004
+344,1,105000000
+345,2,105000001
+346,3,105000002
+347,4,105000003
+348,5,105000004
+349,1,108000000
+350,2,108000001
+351,3,108000002
+352,4,108000003
+353,5,108000004
+354,1,109000000
+355,2,109000001
+356,3,109000002
+357,4,109000003
+358,5,109000004
+359,1,111000000
+360,2,111000001
+361,3,111000002
+362,4,111000003
+363,5,111000004
+364,1,112000000
+365,2,112000001
+366,3,112000002
+367,4,112000003
+368,5,112000004
+369,1,120000000
+370,2,120000001
+371,3,120000002
+372,4,120000003
+373,5,120000004
+374,1,101000010
+375,2,101000020
+376,2,101000030
+377,3,101000040
+378,3,101000050
+379,3,101000060
+380,3,101000070
+381,3,101000080
+382,1,102000010
+383,2,102000020
+384,2,102000030
+385,2,102000040
+386,3,102000050
+387,3,102000060
+388,3,102000070
+389,3,102000080
+390,1,103000010
+391,2,103000020
+392,2,103000030
+393,2,103000040
+394,3,103000050
+395,3,103000060
+396,3,103000070
+397,3,103000080
+398,1,104000010
+399,2,104000020
+400,2,104000030
+401,2,104000040
+402,3,104000050
+403,3,104000060
+404,3,104000070
+405,3,104000080
+406,1,105000010
+407,2,105000020
+408,2,105000030
+409,2,105000040
+410,3,105000050
+411,3,105000060
+412,3,105000070
+413,3,105000080
+414,1,106000010
+415,2,106000020
+416,2,106000030
+417,2,106000040
+418,3,106000050
+419,3,106000060
+420,3,106000070
+421,3,106000080
+422,1,107000010
+423,2,107000020
+424,2,107000030
+425,2,107000040
+426,3,107000050
+427,3,107000060
+428,3,107000070
+429,3,107000080
+430,1,108000010
+431,2,108000020
+432,2,108000030
+433,2,108000040
+434,3,108000050
+435,3,108000060
+436,3,108000070
+437,3,108000080
+438,2,180000
+440,1,101000000
+441,2,101000001
+442,3,101000002
+443,4,101000008
+444,5,101000004
+446,1,102000000
+447,2,102000001
+448,3,102000002
+449,4,102000003
+450,5,102000004
+451,1,112000000
+452,2,112000001
+453,3,112000002
+454,4,112000003
+455,5,112000004
+457,1,101000000
+458,2,101000001
+459,3,101000002
+460,4,101000008
+461,5,101000004
+462,1,120000000
+463,2,120000001
+464,3,120000002
+465,4,120000003
+466,5,120000004
+468,1,111000000
+469,2,111000001
+470,3,111000002
+471,4,111000003
+472,5,111000004
+473,1,120000000
+474,2,120000001
+475,3,120000002
+476,4,120000003
+477,5,120000004
+479,1,109000000
+480,2,109000001
+481,3,109000002
+482,4,109000003
+483,5,109000004
+484,1,112000000
+485,2,112000001
+486,3,112000002
+487,4,112000003
+488,5,112000004
+490,1,103000000
+491,2,103000001
+492,3,103000002
+493,4,103000003
+494,5,103000004
+495,1,112000000
+496,2,112000001
+497,3,112000002
+498,4,112000003
+499,5,112000004
+501,1,105000000
+502,2,105000001
+503,3,105000002
+504,4,105000003
+505,5,105000004
+506,1,120000000
+507,2,120000001
+508,3,120000002
+509,4,120000003
+510,5,120000004
+512,1,108000000
+513,2,108000001
+514,3,108000002
+515,4,108000003
+516,5,108000004
+517,1,120000000
+518,2,120000001
+519,3,120000002
+520,4,120000003
+521,5,120000004
+523,1,101000010
+524,1,103000010
+525,2,103000030
+526,2,103000040
+527,2,107000020
+528,2,101000030
+529,3,101000050
+530,3,101000060
+531,3,101000080
+532,3,103000060
+533,3,103000070
+534,3,103000080
+535,3,101000040
+536,1,101000000
+537,2,101000001
+538,3,101000002
+539,4,101000008
+540,5,101000004
+541,1,112000000
+542,2,112000001
+543,3,112000002
+544,4,112000003
+545,5,112000004
+546,2,101000005
+547,2,112000005
+548,3,170000
+549,4,170001
+551,1,102000010
+552,2,102000030
+553,2,102000040
+554,2,104000020
+555,3,102000060
+556,3,102000070
+557,3,102000080
+558,3,103000050
+559,3,105000050
+560,1,102000000
+561,2,102000001
+562,3,102000002
+563,4,102000003
+564,5,102000004
+565,1,112000000
+566,2,112000001
+567,3,112000002
+568,4,112000003
+569,5,112000004
+570,3,170000
+571,4,170001
+573,1,106000010
+574,2,106000030
+575,2,106000040
+576,2,105000020
+577,3,106000060
+578,3,106000070
+579,3,106000080
+580,3,101000070
+581,1,103000000
+582,2,103000001
+583,3,103000002
+584,4,103000003
+585,5,103000004
+586,1,112000000
+587,2,112000001
+588,3,112000002
+589,4,112000003
+590,5,112000004
+591,3,170000
+592,4,170001
+594,1,104000010
+595,2,104000030
+596,2,104000040
+597,2,108000020
+598,3,104000060
+599,3,104000070
+600,3,104000080
+601,3,102000050
+602,1,111000000
+603,2,111000001
+604,3,111000002
+605,4,111000003
+606,5,111000004
+607,1,120000000
+608,2,120000001
+609,3,120000002
+610,4,120000003
+611,5,120000004
+612,1,110020
+613,1,110030
+614,1,110040
+615,1,110050
+616,3,110060
+617,3,110070
+618,3,110080
+619,3,110090
+620,3,110100
+621,3,110110
+622,3,110120
+623,3,110130
+624,3,110140
+625,3,110150
+626,3,110160
+627,3,110170
+628,3,110180
+629,3,110190
+630,3,110200
+631,3,110210
+632,3,110220
+633,3,110230
+634,3,110240
+635,3,110250
+636,3,110260
+637,3,110270
+639,1,107000010
+640,2,107000030
+641,2,107000040
+642,2,101000020
+643,3,107000060
+644,3,107000070
+645,3,107000080
+646,3,108000050
+647,1,105000000
+648,2,105000001
+649,3,105000002
+650,4,105000003
+651,5,105000004
+652,1,120000000
+653,2,120000001
+654,3,120000002
+655,4,120000003
+656,5,120000004
+657,3,180000
+658,4,180001
+660,1,105000010
+661,2,105000030
+662,2,105000040
+663,2,102000020
+664,2,103000020
+665,3,105000060
+666,3,105000070
+667,3,105000080
+668,3,104000050
+669,3,106000050
+670,1,109000000
+671,2,109000001
+672,3,109000002
+673,4,109000003
+674,5,109000004
+675,1,112000000
+676,2,112000001
+677,3,112000002
+678,4,112000003
+679,5,112000004
+680,1,120020
+681,1,120030
+682,1,120040
+683,1,120050
+684,3,120240
+685,3,120250
+686,3,120260
+687,3,120270
+688,3,120300
+689,3,120310
+690,3,120320
+691,3,120330
+692,3,120340
+693,3,120350
+694,3,120360
+695,3,120370
+696,3,120380
+697,3,120390
+698,3,120400
+699,3,120410
+700,3,120420
+701,3,120430
+702,3,120450
+703,3,120460
+705,1,108000010
+706,2,108000030
+707,2,108000040
+708,2,106000020
+709,3,108000060
+710,3,108000070
+711,3,108000080
+712,3,107000050
+713,1,108000000
+714,2,108000001
+715,3,108000002
+716,4,108000003
+717,5,108000004
+718,1,120000000
+719,2,120000001
+720,3,120000002
+721,4,120000003
+722,5,120000004
+723,1,130020
+724,1,130030
+725,1,130040
+726,1,130050
+727,3,130060
+728,3,130070
+729,3,130080
+730,3,130090
+731,3,130100
+732,3,130110
+733,3,130120
+734,3,130130
+735,3,130140
+736,3,130150
+737,3,130160
+738,3,130170
+739,3,130180
+740,3,130190
+741,3,130200
+742,3,130420
+743,3,130510
+744,3,130520
+745,3,130530
+746,3,130540
+748,1,105000010
+749,2,105000030
+750,2,105000040
+751,2,102000020
+752,2,103000020
+753,3,105000060
+754,3,105000070
+755,3,105000080
+756,3,104000050
+757,3,106000050
+758,1,109000000
+759,2,109000001
+760,3,109000002
+761,4,109000003
+762,5,109000004
+763,1,112000000
+764,2,112000001
+765,3,112000002
+766,4,112000003
+767,5,112000004
+768,3,170000
+769,4,170001
+771,1,104000010
+772,2,104000030
+773,2,104000040
+774,2,108000020
+775,3,104000060
+776,3,104000070
+777,3,104000080
+778,3,102000050
+779,1,111000000
+780,2,111000001
+781,3,111000002
+782,4,111000003
+783,5,111000004
+784,1,120000000
+785,2,120000001
+786,3,120000002
+787,4,120000003
+788,5,120000004
+789,1,110020
+790,1,110030
+791,1,110040
+792,1,110050
+793,3,110060
+794,3,110070
+795,3,110080
+796,3,110090
+797,3,110100
+798,3,110110
+799,3,110120
+800,3,110130
+801,3,110140
+802,3,110150
+803,3,110160
+804,3,110170
+805,3,110180
+806,3,110190
+807,3,110200
+808,3,110210
+809,3,110220
+810,3,110230
+811,3,110240
+812,3,110250
+813,3,110260
+814,3,110270
+816,1,102000010
+817,2,102000030
+818,2,102000040
+819,2,104000020
+820,3,102000060
+821,3,102000070
+822,3,102000080
+823,3,103000050
+824,3,105000050
+825,1,102000000
+826,2,102000001
+827,3,102000002
+828,4,102000003
+829,5,102000004
+830,1,112000000
+831,2,112000001
+832,3,112000002
+833,4,112000003
+834,5,112000004
+835,3,170001
+836,4,170002
+838,1,102000010
+839,2,102000030
+840,2,102000040
+841,2,104000020
+842,3,102000060
+843,3,102000070
+844,3,102000080
+845,3,103000050
+846,3,105000050
+847,1,102000000
+848,2,102000001
+849,3,102000002
+850,4,102000003
+851,5,102000004
+852,1,112000000
+853,2,112000001
+854,3,112000002
+855,4,112000003
+856,5,112000004
+857,1,110020
+858,1,110030
+859,1,110040
+860,1,110050
+861,2,110021
+862,2,110031
+863,2,110041
+864,2,110051
+865,3,110060
+866,3,110070
+867,3,110080
+868,3,110090
+869,3,110100
+870,3,110110
+871,3,110120
+872,3,110130
+873,3,110140
+874,3,110150
+875,3,110160
+876,3,110170
+877,3,110180
+878,3,110190
+879,3,110200
+880,3,110210
+881,3,110220
+882,3,110230
+883,3,110240
+884,3,110250
+885,3,110260
+886,3,110270
+887,4,140000
+889,1,101000010
+890,1,103000010
+891,2,103000030
+892,2,103000040
+893,2,107000020
+894,2,101000030
+895,3,101000050
+896,3,101000060
+897,3,101000080
+898,3,103000060
+899,3,103000070
+900,3,103000080
+901,3,101000040
+902,1,101000000
+903,2,101000001
+904,3,101000002
+905,4,101000008
+906,5,101000004
+907,1,112000000
+908,2,112000001
+909,3,112000002
+910,4,112000003
+911,5,112000004
+912,1,120020
+913,1,120030
+914,1,120040
+915,1,120050
+916,2,120021
+917,2,120031
+918,2,120041
+919,2,120051
+920,3,120240
+921,3,120250
+922,3,120260
+923,3,120270
+924,3,120300
+925,3,120310
+926,3,120320
+927,3,120330
+928,3,120340
+929,3,120350
+930,3,120360
+931,3,120370
+932,3,120380
+933,3,120390
+934,3,120400
+935,3,120410
+936,3,120420
+937,3,120430
+938,3,120450
+939,3,120460
+940,4,140000
+942,1,106000010
+943,2,106000030
+944,2,106000040
+945,2,105000020
+946,3,106000060
+947,3,106000070
+948,3,106000080
+949,3,101000070
+950,1,103000000
+951,2,103000001
+952,3,103000002
+953,4,103000003
+954,5,103000004
+955,1,112000000
+956,2,112000001
+957,3,112000002
+958,4,112000003
+959,5,112000004
+960,3,180001
+961,4,180002
+963,1,101000010
+964,1,103000010
+965,2,103000030
+966,2,103000040
+967,2,107000020
+968,2,101000030
+969,3,101000050
+970,3,101000060
+971,3,101000080
+972,3,103000060
+973,3,103000070
+974,3,103000080
+975,3,101000040
+976,1,101000000
+977,2,101000001
+978,3,101000002
+979,4,101000008
+980,5,101000004
+981,1,120000000
+982,2,120000001
+983,3,120000002
+984,4,120000003
+985,5,120000004
+986,3,170001
+987,4,170002
+989,1,105000010
+990,2,105000030
+991,2,105000040
+992,2,102000020
+993,2,103000020
+994,3,105000060
+995,3,105000070
+996,3,105000080
+997,3,104000050
+998,3,106000050
+999,1,109000000
+1000,2,109000001
+1001,3,109000002
+1002,4,109000003
+1003,5,109000004
+1004,1,112000000
+1005,2,112000001
+1006,3,112000002
+1007,4,112000003
+1008,5,112000004
+1009,1,130020
+1010,1,130030
+1011,1,130040
+1012,1,130050
+1013,2,130021
+1014,2,130031
+1015,2,130041
+1016,2,130051
+1017,3,130060
+1018,3,130070
+1019,3,130080
+1020,3,130090
+1021,3,130100
+1022,3,130110
+1023,3,130120
+1024,3,130130
+1025,3,130140
+1026,3,130150
+1027,3,130160
+1028,3,130170
+1029,3,130180
+1030,3,130190
+1031,3,130200
+1032,3,130420
+1033,3,130510
+1034,3,130520
+1035,3,130530
+1036,3,130540
+1037,4,140000
+1039,1,107000010
+1040,2,107000030
+1041,2,107000040
+1042,2,101000020
+1043,3,107000060
+1044,3,107000070
+1045,3,107000080
+1046,3,108000050
+1047,1,105000000
+1048,2,105000001
+1049,3,105000002
+1050,4,105000003
+1051,5,105000004
+1052,1,120000000
+1053,2,120000001
+1054,3,120000002
+1055,4,120000003
+1056,5,120000004
+1057,1,120020
+1058,1,120030
+1059,1,120040
+1060,1,120050
+1061,2,120021
+1062,2,120031
+1063,2,120041
+1064,2,120051
+1065,3,120240
+1066,3,120250
+1067,3,120260
+1068,3,120270
+1069,3,120300
+1070,3,120310
+1071,3,120320
+1072,3,120330
+1073,3,120340
+1074,3,120350
+1075,3,120360
+1076,3,120370
+1077,3,120380
+1078,3,120390
+1079,3,120400
+1080,3,120410
+1081,3,120420
+1082,3,120430
+1083,3,120450
+1084,3,120460
+1085,4,140000
+1087,1,108000010
+1088,2,108000030
+1089,2,108000040
+1090,2,106000020
+1091,3,108000060
+1092,3,108000070
+1093,3,108000080
+1094,3,107000050
+1095,1,108000000
+1096,2,108000001
+1097,3,108000002
+1098,4,108000003
+1099,5,108000004
+1100,1,120000000
+1101,2,120000001
+1102,3,120000002
+1103,4,120000003
+1104,5,120000004
+1105,3,170001
+1106,4,170002
+1108,1,101000010
+1109,1,103000010
+1110,2,103000030
+1111,2,103000040
+1112,2,107000020
+1113,2,101000030
+1114,3,101000050
+1115,3,101000060
+1116,3,101000080
+1117,3,103000060
+1118,3,103000070
+1119,3,103000080
+1120,3,101000040
+1121,1,101000000
+1122,2,101000001
+1123,3,101000002
+1124,4,101000008
+1125,5,101000004
+1126,1,112000000
+1127,2,112000001
+1128,3,112000002
+1129,4,112000003
+1130,5,112000004
+1131,2,101000005
+1132,2,112000005
+1133,3,170001
+1134,4,170002
+1136,1,102000010
+1137,2,102000030
+1138,2,102000040
+1139,2,104000020
+1140,3,102000060
+1141,3,102000070
+1142,3,102000080
+1143,3,103000050
+1144,3,105000050
+1145,1,102000000
+1146,2,102000001
+1147,3,102000002
+1148,4,102000003
+1149,5,102000004
+1150,1,112000000
+1151,2,112000001
+1152,3,112000002
+1153,4,112000003
+1154,5,112000004
+1155,1,120020
+1156,1,120030
+1157,1,120040
+1158,1,120050
+1159,2,120021
+1160,2,120031
+1161,2,120041
+1162,2,120051
+1163,3,120240
+1164,3,120250
+1165,3,120260
+1166,3,120270
+1167,3,120300
+1168,3,120310
+1169,3,120320
+1170,3,120330
+1171,3,120340
+1172,3,120350
+1173,3,120360
+1174,3,120370
+1175,3,120380
+1176,3,120390
+1177,3,120400
+1178,3,120410
+1179,3,120420
+1180,3,120430
+1181,3,120450
+1182,3,120460
+1183,4,140000
+1185,2,104000030
+1186,2,104000040
+1187,2,108000020
+1188,3,104000060
+1189,3,104000070
+1190,3,104000080
+1191,3,102000050
+1192,4,104000100
+1193,4,104000110
+1194,4,107000090
+1195,1,111000000
+1196,2,111000001
+1197,3,111000002
+1198,4,111000003
+1199,5,111000004
+1200,1,120000000
+1201,2,120000001
+1202,3,120000002
+1203,4,120000003
+1204,5,120000004
+1205,3,170002
+1206,4,170003
+1208,2,104000030
+1209,2,104000040
+1210,2,108000020
+1211,3,104000060
+1212,3,104000070
+1213,3,104000080
+1214,3,102000050
+1215,4,104000100
+1216,4,104000110
+1217,4,107000090
+1218,1,111000000
+1219,2,111000001
+1220,3,111000002
+1221,4,111000003
+1222,5,111000004
+1223,1,120000000
+1224,2,120000001
+1225,3,120000002
+1226,4,120000003
+1227,5,120000004
+1228,1,110020
+1229,1,110030
+1230,1,110040
+1231,1,110050
+1232,2,110021
+1233,2,110031
+1234,2,110041
+1235,2,110051
+1236,3,110022
+1237,3,110032
+1238,3,110042
+1239,3,110052
+1240,3,110060
+1241,3,110070
+1242,3,110080
+1243,3,110090
+1244,3,110100
+1245,3,110110
+1246,3,110120
+1247,3,110130
+1248,3,110140
+1249,3,110150
+1250,3,110160
+1251,3,110170
+1252,3,110180
+1253,3,110190
+1254,3,110200
+1255,3,110210
+1256,3,110220
+1257,3,110230
+1258,3,110240
+1259,3,110250
+1260,3,110260
+1261,3,110270
+1262,4,140000
+1264,2,105000030
+1265,2,105000040
+1266,2,102000020
+1267,2,103000020
+1268,3,105000060
+1269,3,105000070
+1270,3,105000080
+1271,3,104000050
+1272,3,106000050
+1273,4,105000100
+1274,4,105000110
+1275,4,108000090
+1276,1,109000000
+1277,2,109000001
+1278,3,109000002
+1279,4,109000003
+1280,5,109000004
+1281,1,112000000
+1282,2,112000001
+1283,3,112000002
+1284,4,112000003
+1285,5,112000004
+1286,3,170002
+1287,4,170003
+1289,2,106000030
+1290,2,106000040
+1291,2,105000020
+1292,3,106000060
+1293,3,106000070
+1294,3,106000080
+1295,3,101000070
+1296,4,106000100
+1297,4,106000110
+1298,4,104000090
+1299,1,103000000
+1300,2,103000001
+1301,3,103000002
+1302,4,103000003
+1303,5,103000004
+1304,1,112000000
+1305,2,112000001
+1306,3,112000002
+1307,4,112000003
+1308,5,112000004
+1309,1,130020
+1310,1,130030
+1311,1,130040
+1312,1,130050
+1313,2,130021
+1314,2,130031
+1315,2,130041
+1316,2,130051
+1317,3,130022
+1318,3,130032
+1319,3,130042
+1320,3,130052
+1321,3,130060
+1322,3,130070
+1323,3,130080
+1324,3,130090
+1325,3,130100
+1326,3,130110
+1327,3,130120
+1328,3,130130
+1329,3,130140
+1330,3,130150
+1331,3,130160
+1332,3,130170
+1333,3,130180
+1334,3,130190
+1335,3,130200
+1336,3,130420
+1337,3,130510
+1338,3,130520
+1339,3,130530
+1340,3,130540
+1341,4,140000
+1343,2,108000030
+1344,2,108000040
+1345,2,106000020
+1346,3,108000060
+1347,3,108000070
+1348,3,108000080
+1349,3,107000050
+1350,4,108000100
+1351,4,105000090
+1352,1,108000000
+1353,2,108000001
+1354,3,108000002
+1355,4,108000003
+1356,5,108000004
+1357,1,120000000
+1358,2,120000001
+1359,3,120000002
+1360,4,120000003
+1361,5,120000004
+1362,1,120020
+1363,1,120030
+1364,1,120040
+1365,1,120050
+1366,2,120021
+1367,2,120031
+1368,2,120041
+1369,2,120051
+1370,3,120022
+1371,3,120032
+1372,3,120042
+1373,3,120052
+1374,3,120240
+1375,3,120250
+1376,3,120260
+1377,3,120270
+1378,3,120300
+1379,3,120310
+1380,3,120320
+1381,3,120330
+1382,3,120340
+1383,3,120350
+1384,3,120360
+1385,3,120370
+1386,3,120380
+1387,3,120390
+1388,3,120400
+1389,3,120410
+1390,3,120420
+1391,3,120430
+1392,3,120450
+1393,3,120460
+1394,4,140000
+1396,2,103000030
+1397,2,103000040
+1398,2,107000020
+1399,2,101000030
+1400,3,101000050
+1401,3,101000060
+1402,3,101000080
+1403,3,103000060
+1404,3,103000070
+1405,3,103000080
+1406,3,101000040
+1407,4,101000090
+1408,4,102000090
+1409,4,103000100
+1410,4,101000100
+1411,4,101000110
+1412,1,101000000
+1413,2,101000001
+1414,3,101000002
+1415,4,101000008
+1416,5,101000004
+1417,1,120000000
+1418,2,120000001
+1419,3,120000002
+1420,4,120000003
+1421,5,120000004
+1422,3,170002
+1423,4,170003
+1425,2,105000030
+1426,2,105000040
+1427,2,102000020
+1428,2,103000020
+1429,3,105000060
+1430,3,105000070
+1431,3,105000080
+1432,3,104000050
+1433,3,106000050
+1434,4,105000100
+1435,4,105000110
+1436,4,108000090
+1437,1,109000000
+1438,2,109000001
+1439,3,109000002
+1440,4,109000003
+1441,5,109000004
+1442,1,112000000
+1443,2,112000001
+1444,3,112000002
+1445,4,112000003
+1446,5,112000004
+1447,3,180002
+1448,4,180003
+1450,2,107000030
+1451,2,107000040
+1452,2,101000020
+1453,3,107000060
+1454,3,107000070
+1455,3,107000080
+1456,3,108000050
+1457,4,107000100
+1458,4,103000090
+1459,1,105000000
+1460,2,105000001
+1461,3,105000002
+1462,4,105000003
+1463,5,105000004
+1464,1,120000000
+1465,2,120000001
+1466,3,120000002
+1467,4,120000003
+1468,5,120000004
+1469,3,170002
+1470,4,170003
+1472,2,104000030
+1473,2,104000040
+1474,2,108000020
+1475,3,104000060
+1476,3,104000070
+1477,3,104000080
+1478,3,102000050
+1479,4,104000100
+1480,4,104000110
+1481,4,107000090
+1482,1,111000000
+1483,2,111000001
+1484,3,111000002
+1485,4,111000003
+1486,5,111000004
+1487,1,120000000
+1488,2,120000001
+1489,3,120000002
+1490,4,120000003
+1491,5,120000004
+1492,1,110020
+1493,1,110030
+1494,1,110040
+1495,1,110050
+1496,2,110021
+1497,2,110031
+1498,2,110041
+1499,2,110051
+1500,3,110022
+1501,3,110032
+1502,3,110042
+1503,3,110052
+1504,3,110060
+1505,3,110070
+1506,3,110080
+1507,3,110090
+1508,3,110100
+1509,3,110110
+1510,3,110120
+1511,3,110130
+1512,3,110140
+1513,3,110150
+1514,3,110160
+1515,3,110170
+1516,3,110180
+1517,3,110190
+1518,3,110200
+1519,3,110210
+1520,3,110220
+1521,3,110230
+1522,3,110240
+1523,3,110250
+1524,3,110260
+1525,3,110270
+1526,4,140000
+1528,2,108000030
+1529,2,108000040
+1530,2,106000020
+1531,3,108000060
+1532,3,108000070
+1533,3,108000080
+1534,3,107000050
+1535,4,108000100
+1536,4,105000090
+1537,1,108000000
+1538,2,108000001
+1539,3,108000002
+1540,4,108000003
+1541,5,108000004
+1542,1,120000000
+1543,2,120000001
+1544,3,120000002
+1545,4,120000003
+1546,5,120000004
+1547,3,170002
+1548,4,170003
+1550,2,103000030
+1551,2,103000040
+1552,2,107000020
+1553,2,101000030
+1554,3,101000050
+1555,3,101000060
+1556,3,101000080
+1557,3,103000060
+1558,3,103000070
+1559,3,103000080
+1560,3,101000040
+1561,4,101000090
+1562,4,102000090
+1563,4,103000100
+1564,4,101000100
+1565,4,101000110
+1566,1,101000000
+1567,2,101000001
+1568,3,101000002
+1569,4,101000008
+1570,5,101000004
+1571,1,112000000
+1572,2,112000001
+1573,3,112000002
+1574,4,112000003
+1575,5,112000004
+1576,1,120020
+1577,1,120030
+1578,1,120040
+1579,1,120050
+1580,2,120021
+1581,2,120031
+1582,2,120041
+1583,2,120051
+1584,3,120022
+1585,3,120032
+1586,3,120042
+1587,3,120052
+1588,4,120023
+1589,4,120033
+1590,4,120043
+1591,4,120053
+1592,3,120240
+1593,3,120250
+1594,3,120260
+1595,3,120270
+1596,3,120300
+1597,3,120310
+1598,3,120320
+1599,3,120330
+1600,3,120340
+1601,3,120350
+1602,3,120360
+1603,3,120370
+1604,3,120380
+1605,3,120390
+1606,3,120400
+1607,3,120410
+1608,3,120420
+1609,3,120430
+1610,3,120450
+1611,3,120460
+1612,4,140000
+1613,4,150010
+1614,4,150020
+1615,4,150030
+1616,4,150040
+1618,2,102000030
+1619,2,102000040
+1620,2,104000020
+1621,3,102000060
+1622,3,102000070
+1623,3,102000080
+1624,3,103000050
+1625,3,105000050
+1626,4,102000100
+1627,4,102000110
+1628,4,106000090
+1629,1,102000000
+1630,2,102000001
+1631,3,102000002
+1632,4,102000003
+1633,5,102000004
+1634,1,112000000
+1635,2,112000001
+1636,3,112000002
+1637,4,112000003
+1638,5,112000004
+1639,1,110020
+1640,1,110030
+1641,1,110040
+1642,1,110050
+1643,2,110021
+1644,2,110031
+1645,2,110041
+1646,2,110051
+1647,3,110022
+1648,3,110032
+1649,3,110042
+1650,3,110052
+1651,4,110023
+1652,4,110033
+1653,4,110043
+1654,4,110053
+1655,3,110060
+1656,3,110070
+1657,3,110080
+1658,3,110090
+1659,3,110100
+1660,3,110110
+1661,3,110120
+1662,3,110130
+1663,3,110140
+1664,3,110150
+1665,3,110160
+1666,3,110170
+1667,3,110180
+1668,3,110190
+1669,3,110200
+1670,3,110210
+1671,3,110220
+1672,3,110230
+1673,3,110240
+1674,3,110250
+1675,3,110260
+1676,3,110270
+1677,4,140000
+1678,4,150010
+1679,4,150020
+1680,4,150030
+1681,4,150040
+1683,2,106000030
+1684,2,106000040
+1685,2,105000020
+1686,3,106000060
+1687,3,106000070
+1688,3,106000080
+1689,3,101000070
+1690,4,106000100
+1691,4,106000110
+1692,4,104000090
+1693,1,103000000
+1694,2,103000001
+1695,3,103000002
+1696,4,103000003
+1697,5,103000004
+1698,1,112000000
+1699,2,112000001
+1700,3,112000002
+1701,4,112000003
+1702,5,112000004
+1703,1,120020
+1704,1,120030
+1705,1,120040
+1706,1,120050
+1707,2,120021
+1708,2,120031
+1709,2,120041
+1710,2,120051
+1711,3,120022
+1712,3,120032
+1713,3,120042
+1714,3,120052
+1715,4,120023
+1716,4,120033
+1717,4,120043
+1718,4,120053
+1719,3,120240
+1720,3,120250
+1721,3,120260
+1722,3,120270
+1723,3,120300
+1724,3,120310
+1725,3,120320
+1726,3,120330
+1727,3,120340
+1728,3,120350
+1729,3,120360
+1730,3,120370
+1731,3,120380
+1732,3,120390
+1733,3,120400
+1734,3,120410
+1735,3,120420
+1736,3,120430
+1737,3,120450
+1738,3,120460
+1739,4,140000
+1740,4,150010
+1741,4,150020
+1742,4,150030
+1743,4,150040
+1745,2,103000030
+1746,2,103000040
+1747,2,107000020
+1748,2,101000030
+1749,3,101000050
+1750,3,101000060
+1751,3,101000080
+1752,3,103000060
+1753,3,103000070
+1754,3,103000080
+1755,3,101000040
+1756,4,101000090
+1757,4,102000090
+1758,4,103000100
+1759,4,101000100
+1760,4,101000110
+1761,1,101000000
+1762,2,101000001
+1763,3,101000002
+1764,4,101000008
+1765,5,101000004
+1766,1,120000000
+1767,2,120000001
+1768,3,120000002
+1769,4,120000003
+1770,5,120000004
+1771,3,170003
+1772,4,170004
+1774,2,107000030
+1775,2,107000040
+1776,2,101000020
+1777,3,107000060
+1778,3,107000070
+1779,3,107000080
+1780,3,108000050
+1781,4,107000100
+1782,4,103000090
+1783,1,105000000
+1784,2,105000001
+1785,3,105000002
+1786,4,105000003
+1787,5,105000004
+1788,1,120000000
+1789,2,120000001
+1790,3,120000002
+1791,4,120000003
+1792,5,120000004
+1793,1,130020
+1794,1,130030
+1795,1,130040
+1796,1,130050
+1797,2,130021
+1798,2,130031
+1799,2,130041
+1800,2,130051
+1801,3,130022
+1802,3,130032
+1803,3,130042
+1804,3,130052
+1805,4,130023
+1806,4,130033
+1807,4,130043
+1808,4,130053
+1809,3,130060
+1810,3,130070
+1811,3,130080
+1812,3,130090
+1813,3,130100
+1814,3,130110
+1815,3,130120
+1816,3,130130
+1817,3,130140
+1818,3,130150
+1819,3,130160
+1820,3,130170
+1821,3,130180
+1822,3,130190
+1823,3,130200
+1824,3,130420
+1825,3,130510
+1826,3,130520
+1827,3,130530
+1828,3,130540
+1829,4,140000
+1830,4,150010
+1831,4,150020
+1832,4,150030
+1833,4,150040
+1835,2,102000030
+1836,2,102000040
+1837,2,104000020
+1838,3,102000060
+1839,3,102000070
+1840,3,102000080
+1841,3,103000050
+1842,3,105000050
+1843,4,102000100
+1844,4,102000110
+1845,4,106000090
+1846,1,102000000
+1847,2,102000001
+1848,3,102000002
+1849,4,102000003
+1850,5,102000004
+1851,1,112000000
+1852,2,112000001
+1853,3,112000002
+1854,4,112000003
+1855,5,112000004
+1856,1,120020
+1857,1,120030
+1858,1,120040
+1859,1,120050
+1860,2,120021
+1861,2,120031
+1862,2,120041
+1863,2,120051
+1864,3,120022
+1865,3,120032
+1866,3,120042
+1867,3,120052
+1868,4,120023
+1869,4,120033
+1870,4,120043
+1871,4,120053
+1872,3,120240
+1873,3,120250
+1874,3,120260
+1875,3,120270
+1876,3,120300
+1877,3,120310
+1878,3,120320
+1879,3,120330
+1880,3,120340
+1881,3,120350
+1882,3,120360
+1883,3,120370
+1884,3,120380
+1885,3,120390
+1886,3,120400
+1887,3,120410
+1888,3,120420
+1889,3,120430
+1890,3,120450
+1891,3,120460
+1892,4,140000
+1893,4,150010
+1894,4,150020
+1895,4,150030
+1896,4,150040
+1898,2,108000030
+1899,2,108000040
+1900,2,106000020
+1901,3,108000060
+1902,3,108000070
+1903,3,108000080
+1904,3,107000050
+1905,4,108000100
+1906,4,105000090
+1907,1,108000000
+1908,2,108000001
+1909,3,108000002
+1910,4,108000003
+1911,5,108000004
+1912,1,120000000
+1913,2,120000001
+1914,3,120000002
+1915,4,120000003
+1916,5,120000004
+1917,3,170003
+1918,4,170004
+1920,2,103000030
+1921,2,103000040
+1922,2,107000020
+1923,2,101000030
+1924,3,101000050
+1925,3,101000060
+1926,3,101000080
+1927,3,103000060
+1928,3,103000070
+1929,3,103000080
+1930,3,101000040
+1931,4,101000090
+1932,4,102000090
+1933,4,103000100
+1934,4,101000100
+1935,4,101000110
+1936,1,101000000
+1937,2,101000001
+1938,3,101000002
+1939,4,101000008
+1940,5,101000004
+1941,1,112000000
+1942,2,112000001
+1943,3,112000002
+1944,4,112000003
+1945,5,112000004
+1946,3,170003
+1947,4,170004
+1949,2,105000030
+1950,2,105000040
+1951,2,102000020
+1952,2,103000020
+1953,3,105000060
+1954,3,105000070
+1955,3,105000080
+1956,3,104000050
+1957,3,106000050
+1958,4,105000100
+1959,4,105000110
+1960,4,108000090
+1961,1,109000000
+1962,2,109000001
+1963,3,109000002
+1964,4,109000003
+1965,5,109000004
+1966,1,112000000
+1967,2,112000001
+1968,3,112000002
+1969,4,112000003
+1970,5,112000004
+1971,3,180003
+1972,4,180004
+1974,2,104000030
+1975,2,104000040
+1976,2,108000020
+1977,3,104000060
+1978,3,104000070
+1979,3,104000080
+1980,3,102000050
+1981,4,104000100
+1982,4,104000110
+1983,4,107000090
+1984,1,111000000
+1985,2,111000001
+1986,3,111000002
+1987,4,111000003
+1988,5,111000004
+1989,1,120000000
+1990,2,120000001
+1991,3,120000002
+1992,4,120000003
+1993,5,120000004
+1994,1,110020
+1995,1,110030
+1996,1,110040
+1997,1,110050
+1998,2,110021
+1999,2,110031
+2000,2,110041
+2001,2,110051
+2002,3,110022
+2003,3,110032
+2004,3,110042
+2005,3,110052
+2006,4,110023
+2007,4,110033
+2008,4,110043
+2009,4,110053
+2010,3,110060
+2011,3,110070
+2012,3,110080
+2013,3,110090
+2014,3,110100
+2015,3,110110
+2016,3,110120
+2017,3,110130
+2018,3,110140
+2019,3,110150
+2020,3,110160
+2021,3,110170
+2022,3,110180
+2023,3,110190
+2024,3,110200
+2025,3,110210
+2026,3,110220
+2027,3,110230
+2028,3,110240
+2029,3,110250
+2030,3,110260
+2031,3,110270
+2032,4,140000
+2033,4,150010
+2034,4,150020
+2035,4,150030
+2036,4,150040
+2038,3,105000060
+2039,3,105000070
+2040,3,105000080
+2041,3,104000050
+2042,3,106000050
+2043,4,105000100
+2044,4,105000110
+2045,4,108000090
+2046,5,105000120
+2047,1,109000000
+2048,2,109000001
+2049,3,109000002
+2050,4,109000003
+2051,5,109000004
+2052,1,112000000
+2053,2,112000001
+2054,3,112000002
+2055,4,112000003
+2056,5,112000004
+2057,3,170004
+2059,3,101000050
+2060,3,101000060
+2061,3,101000080
+2062,3,103000060
+2063,3,103000070
+2064,3,103000080
+2065,3,101000040
+2066,4,101000090
+2067,4,102000090
+2068,4,103000100
+2069,4,101000100
+2070,4,101000110
+2071,5,101000120
+2072,5,103000120
+2073,1,101000000
+2074,2,101000001
+2075,3,101000002
+2076,4,101000008
+2077,5,101000004
+2078,1,120000000
+2079,2,120000001
+2080,3,120000002
+2081,4,120000003
+2082,5,120000004
+2083,3,170004
+2085,3,107000060
+2086,3,107000070
+2087,3,107000080
+2088,3,108000050
+2089,4,107000100
+2090,4,103000090
+2091,5,107000110
+2092,1,105000000
+2093,2,105000001
+2094,3,105000002
+2095,4,105000003
+2096,5,105000004
+2097,1,120000000
+2098,2,120000001
+2099,3,120000002
+2100,4,120000003
+2101,5,120000004
+2102,3,170004
+2104,3,101000050
+2105,3,101000060
+2106,3,101000080
+2107,3,103000060
+2108,3,103000070
+2109,3,103000080
+2110,3,101000040
+2111,4,101000090
+2112,4,102000090
+2113,4,103000100
+2114,4,101000100
+2115,4,101000110
+2116,5,101000120
+2117,5,103000120
+2118,1,101000000
+2119,2,101000001
+2120,3,101000002
+2121,4,101000008
+2122,5,101000004
+2123,1,112000000
+2124,2,112000001
+2125,3,112000002
+2126,4,112000003
+2127,5,112000004
+2128,1,130020
+2129,1,130030
+2130,1,130040
+2131,1,130050
+2132,2,130021
+2133,2,130031
+2134,2,130041
+2135,2,130051
+2136,3,130022
+2137,3,130032
+2138,3,130042
+2139,3,130052
+2140,4,130023
+2141,4,130033
+2142,4,130043
+2143,4,130053
+2144,5,130024
+2145,5,130034
+2146,5,130044
+2147,5,130054
+2148,3,130060
+2149,3,130070
+2150,3,130080
+2151,3,130090
+2152,3,130100
+2153,3,130110
+2154,3,130120
+2155,3,130130
+2156,3,130140
+2157,3,130150
+2158,3,130160
+2159,3,130170
+2160,3,130180
+2161,3,130190
+2162,3,130200
+2163,3,130420
+2164,3,130510
+2165,3,130520
+2166,3,130530
+2167,3,130540
+2168,4,140000
+2169,4,150010
+2170,4,150020
+2171,4,150030
+2172,4,150040
+2174,3,102000060
+2175,3,102000070
+2176,3,102000080
+2177,3,103000050
+2178,3,105000050
+2179,4,102000100
+2180,4,102000110
+2181,4,106000090
+2182,5,102000120
+2183,1,102000000
+2184,2,102000001
+2185,3,102000002
+2186,4,102000003
+2187,5,102000004
+2188,1,112000000
+2189,2,112000001
+2190,3,112000002
+2191,4,112000003
+2192,5,112000004
+2193,3,170004
+2195,3,101000050
+2196,3,101000060
+2197,3,101000080
+2198,3,103000060
+2199,3,103000070
+2200,3,103000080
+2201,3,101000040
+2202,4,101000090
+2203,4,102000090
+2204,4,103000100
+2205,4,101000100
+2206,4,101000110
+2207,5,101000120
+2208,5,103000120
+2209,1,101000000
+2210,2,101000001
+2211,3,101000002
+2212,4,101000008
+2213,5,101000004
+2214,1,120000000
+2215,2,120000001
+2216,3,120000002
+2217,4,120000003
+2218,5,120000004
+2219,3,170004
+2221,3,106000060
+2222,3,106000070
+2223,3,106000080
+2224,3,101000070
+2225,4,106000100
+2226,4,106000110
+2227,4,104000090
+2228,5,106000120
+2229,1,103000000
+2230,2,103000001
+2231,3,103000002
+2232,4,103000003
+2233,5,103000004
+2234,1,112000000
+2235,2,112000001
+2236,3,112000002
+2237,4,112000003
+2238,5,112000004
+2239,1,130020
+2240,1,130030
+2241,1,130040
+2242,1,130050
+2243,2,130021
+2244,2,130031
+2245,2,130041
+2246,2,130051
+2247,3,130022
+2248,3,130032
+2249,3,130042
+2250,3,130052
+2251,4,130023
+2252,4,130033
+2253,4,130043
+2254,4,130053
+2255,5,130024
+2256,5,130034
+2257,5,130044
+2258,5,130054
+2259,3,130060
+2260,3,130070
+2261,3,130080
+2262,3,130090
+2263,3,130100
+2264,3,130110
+2265,3,130120
+2266,3,130130
+2267,3,130140
+2268,3,130150
+2269,3,130160
+2270,3,130170
+2271,3,130180
+2272,3,130190
+2273,3,130200
+2274,3,130420
+2275,3,130510
+2276,3,130520
+2277,3,130530
+2278,3,130540
+2279,4,140000
+2280,4,150010
+2281,4,150020
+2282,4,150030
+2283,4,150040
+2285,3,108000060
+2286,3,108000070
+2287,3,108000080
+2288,3,107000050
+2289,4,108000100
+2290,4,105000090
+2291,5,108000110
+2292,1,108000000
+2293,2,108000001
+2294,3,108000002
+2295,4,108000003
+2296,5,108000004
+2297,1,120000000
+2298,2,120000001
+2299,3,120000002
+2300,4,120000003
+2301,5,120000004
+2302,1,120020
+2303,1,120030
+2304,1,120040
+2305,1,120050
+2306,2,120021
+2307,2,120031
+2308,2,120041
+2309,2,120051
+2310,3,120022
+2311,3,120032
+2312,3,120042
+2313,3,120052
+2314,4,120023
+2315,4,120033
+2316,4,120043
+2317,4,120053
+2318,5,120024
+2319,5,120034
+2320,5,120044
+2321,5,120054
+2322,3,120240
+2323,3,120250
+2324,3,120260
+2325,3,120270
+2326,3,120300
+2327,3,120310
+2328,3,120320
+2329,3,120330
+2330,3,120340
+2331,3,120350
+2332,3,120360
+2333,3,120370
+2334,3,120380
+2335,3,120390
+2336,3,120400
+2337,3,120410
+2338,3,120420
+2339,3,120430
+2340,3,120450
+2341,3,120460
+2342,4,140000
+2343,4,150010
+2344,4,150020
+2345,4,150030
+2346,4,150040
+2348,3,104000060
+2349,3,104000070
+2350,3,104000080
+2351,3,102000050
+2352,4,104000100
+2353,4,104000110
+2354,4,107000090
+2355,5,104000120
+2356,1,111000000
+2357,2,111000001
+2358,3,111000002
+2359,4,111000003
+2360,5,111000004
+2361,1,120000000
+2362,2,120000001
+2363,3,120000002
+2364,4,120000003
+2365,5,120000004
+2366,1,110020
+2367,1,110030
+2368,1,110040
+2369,1,110050
+2370,2,110021
+2371,2,110031
+2372,2,110041
+2373,2,110051
+2374,3,110022
+2375,3,110032
+2376,3,110042
+2377,3,110052
+2378,4,110023
+2379,4,110033
+2380,4,110043
+2381,4,110053
+2382,5,110024
+2383,5,110034
+2384,5,110044
+2385,5,110054
+2386,3,110060
+2387,3,110070
+2388,3,110080
+2389,3,110090
+2390,3,110100
+2391,3,110110
+2392,3,110120
+2393,3,110130
+2394,3,110140
+2395,3,110150
+2396,3,110160
+2397,3,110170
+2398,3,110180
+2399,3,110190
+2400,3,110200
+2401,3,110210
+2402,3,110220
+2403,3,110230
+2404,3,110240
+2405,3,110250
+2406,3,110260
+2407,3,110270
+2408,4,140000
+2409,4,150010
+2410,4,150020
+2411,4,150030
+2412,4,150040
+2414,3,105000060
+2415,3,105000070
+2416,3,105000080
+2417,3,104000050
+2418,3,106000050
+2419,4,105000100
+2420,4,105000110
+2421,4,108000090
+2422,5,105000120
+2423,1,109000000
+2424,2,109000001
+2425,3,109000002
+2426,4,109000003
+2427,5,109000004
+2428,1,112000000
+2429,2,112000001
+2430,3,112000002
+2431,4,112000003
+2432,5,112000004
+2433,3,170004
+2435,3,104000060
+2436,3,104000070
+2437,3,104000080
+2438,3,102000050
+2439,4,104000100
+2440,4,104000110
+2441,4,107000090
+2442,5,104000120
+2443,1,111000000
+2444,2,111000001
+2445,3,111000002
+2446,4,111000003
+2447,5,111000004
+2448,1,120000000
+2449,2,120000001
+2450,3,120000002
+2451,4,120000003
+2452,5,120000004
+2453,1,130020
+2454,1,130030
+2455,1,130040
+2456,1,130050
+2457,2,130021
+2458,2,130031
+2459,2,130041
+2460,2,130051
+2461,3,130022
+2462,3,130032
+2463,3,130042
+2464,3,130052
+2465,4,130023
+2466,4,130033
+2467,4,130043
+2468,4,130053
+2469,5,130024
+2470,5,130034
+2471,5,130044
+2472,5,130054
+2473,3,130060
+2474,3,130070
+2475,3,130080
+2476,3,130090
+2477,3,130100
+2478,3,130110
+2479,3,130120
+2480,3,130130
+2481,3,130140
+2482,3,130150
+2483,3,130160
+2484,3,130170
+2485,3,130180
+2486,3,130190
+2487,3,130200
+2488,3,130420
+2489,3,130510
+2490,3,130520
+2491,3,130530
+2492,3,130540
+2493,4,140000
+2494,4,150010
+2495,4,150020
+2496,4,150030
+2497,4,150040
+2500,1,101000000
+2501,2,101000001
+2502,3,101000002
+2503,4,101000008
+2504,5,101000004
+2505,1,102000000
+2506,2,102000001
+2507,3,102000002
+2508,4,102000003
+2509,5,102000004
+2510,1,103000000
+2511,2,103000001
+2512,3,103000002
+2513,4,103000003
+2514,5,103000004
+2515,1,105000000
+2516,2,105000001
+2517,3,105000002
+2518,4,105000003
+2519,5,105000004
+2520,1,108000000
+2521,2,108000001
+2522,3,108000002
+2523,4,108000003
+2524,5,108000004
+2525,1,109000000
+2526,2,109000001
+2527,3,109000002
+2528,4,109000003
+2529,5,109000004
+2530,1,111000000
+2531,2,111000001
+2532,3,111000002
+2533,4,111000003
+2534,5,111000004
+2535,1,112000000
+2536,2,112000001
+2537,3,112000002
+2538,4,112000003
+2539,5,112000004
+2540,1,120000000
+2541,2,120000001
+2542,3,120000002
+2543,4,120000003
+2544,5,120000004
+2545,1,101000010
+2546,2,101000020
+2547,2,101000030
+2548,3,101000040
+2549,3,101000050
+2550,3,101000060
+2551,3,101000070
+2552,3,101000080
+2553,1,102000010
+2554,2,102000020
+2555,2,102000030
+2556,2,102000040
+2557,3,102000050
+2558,3,102000060
+2559,3,102000070
+2560,3,102000080
+2561,1,103000010
+2562,2,103000020
+2563,2,103000030
+2564,2,103000040
+2565,3,103000050
+2566,3,103000060
+2567,3,103000070
+2568,3,103000080
+2569,1,104000010
+2570,2,104000020
+2571,2,104000030
+2572,2,104000040
+2573,3,104000050
+2574,3,104000060
+2575,3,104000070
+2576,3,104000080
+2577,1,105000010
+2578,2,105000020
+2579,2,105000030
+2580,2,105000040
+2581,3,105000050
+2582,3,105000060
+2583,3,105000070
+2584,3,105000080
+2585,1,106000010
+2586,2,106000020
+2587,2,106000030
+2588,2,106000040
+2589,3,106000050
+2590,3,106000060
+2591,3,106000070
+2592,3,106000080
+2593,1,107000010
+2594,2,107000020
+2595,2,107000030
+2596,2,107000040
+2597,3,107000050
+2598,3,107000060
+2599,3,107000070
+2600,3,107000080
+2601,1,108000010
+2602,2,108000020
+2603,2,108000030
+2604,2,108000040
+2605,3,108000050
+2606,3,108000060
+2607,3,108000070
+2608,3,108000080
+2609,2,180001
+2611,1,101000000
+2612,2,101000001
+2613,3,101000002
+2614,4,101000008
+2615,5,101000004
+2616,1,102000000
+2617,2,102000001
+2618,3,102000002
+2619,4,102000003
+2620,5,102000004
+2621,1,103000000
+2622,2,103000001
+2623,3,103000002
+2624,4,103000003
+2625,5,103000004
+2626,1,105000000
+2627,2,105000001
+2628,3,105000002
+2629,4,105000003
+2630,5,105000004
+2631,1,108000000
+2632,2,108000001
+2633,3,108000002
+2634,4,108000003
+2635,5,108000004
+2636,1,109000000
+2637,2,109000001
+2638,3,109000002
+2639,4,109000003
+2640,5,109000004
+2641,1,111000000
+2642,2,111000001
+2643,3,111000002
+2644,4,111000003
+2645,5,111000004
+2646,1,112000000
+2647,2,112000001
+2648,3,112000002
+2649,4,112000003
+2650,5,112000004
+2651,1,120000000
+2652,2,120000001
+2653,3,120000002
+2654,4,120000003
+2655,5,120000004
+2656,1,101000010
+2657,2,101000020
+2658,2,101000030
+2659,3,101000040
+2660,3,101000050
+2661,3,101000060
+2662,3,101000070
+2663,3,101000080
+2664,1,102000010
+2665,2,102000020
+2666,2,102000030
+2667,2,102000040
+2668,3,102000050
+2669,3,102000060
+2670,3,102000070
+2671,3,102000080
+2672,1,103000010
+2673,2,103000020
+2674,2,103000030
+2675,2,103000040
+2676,3,103000050
+2677,3,103000060
+2678,3,103000070
+2679,3,103000080
+2680,1,104000010
+2681,2,104000020
+2682,2,104000030
+2683,2,104000040
+2684,3,104000050
+2685,3,104000060
+2686,3,104000070
+2687,3,104000080
+2688,1,105000010
+2689,2,105000020
+2690,2,105000030
+2691,2,105000040
+2692,3,105000050
+2693,3,105000060
+2694,3,105000070
+2695,3,105000080
+2696,1,106000010
+2697,2,106000020
+2698,2,106000030
+2699,2,106000040
+2700,3,106000050
+2701,3,106000060
+2702,3,106000070
+2703,3,106000080
+2704,1,107000010
+2705,2,107000020
+2706,2,107000030
+2707,2,107000040
+2708,3,107000050
+2709,3,107000060
+2710,3,107000070
+2711,3,107000080
+2712,1,108000010
+2713,2,108000020
+2714,2,108000030
+2715,2,108000040
+2716,3,108000050
+2717,3,108000060
+2718,3,108000070
+2719,3,108000080
+2720,1,109000010
+2721,2,109000020
+2722,2,109000030
+2723,2,109000040
+2724,3,109000050
+2725,3,109000060
+2726,3,109000070
+2727,3,109000080
+2728,2,180001
+2731,1,101000000
+2732,2,101000001
+2733,3,101000002
+2734,4,101000008
+2735,5,101000004
+2736,1,102000000
+2737,2,102000001
+2738,3,102000002
+2739,4,102000003
+2740,5,102000004
+2741,1,103000000
+2742,2,103000001
+2743,3,103000002
+2744,4,103000003
+2745,5,103000004
+2746,1,105000000
+2747,2,105000001
+2748,3,105000002
+2749,4,105000003
+2750,5,105000004
+2751,1,107000000
+2752,2,107000001
+2753,3,107000002
+2754,4,107000003
+2755,5,107000004
+2756,1,108000000
+2757,2,108000001
+2758,3,108000002
+2759,4,108000003
+2760,5,108000004
+2761,1,109000000
+2762,2,109000001
+2763,3,109000002
+2764,4,109000003
+2765,5,109000004
+2766,1,111000000
+2767,2,111000001
+2768,3,111000002
+2769,4,111000003
+2770,5,111000004
+2771,1,112000000
+2772,2,112000001
+2773,3,112000002
+2774,4,112000003
+2775,5,112000004
+2776,1,120000000
+2777,2,120000001
+2778,3,120000002
+2779,4,120000003
+2780,5,120000004
+2781,1,101000010
+2782,2,101000020
+2783,2,101000030
+2784,3,101000040
+2785,3,101000050
+2786,3,101000060
+2787,3,101000070
+2788,3,101000080
+2789,1,102000010
+2790,2,102000020
+2791,2,102000030
+2792,2,102000040
+2793,3,102000050
+2794,3,102000060
+2795,3,102000070
+2796,3,102000080
+2797,1,103000010
+2798,2,103000020
+2799,2,103000030
+2800,2,103000040
+2801,3,103000050
+2802,3,103000060
+2803,3,103000070
+2804,3,103000080
+2805,1,104000010
+2806,2,104000020
+2807,2,104000030
+2808,2,104000040
+2809,3,104000050
+2810,3,104000060
+2811,3,104000070
+2812,3,104000080
+2813,1,105000010
+2814,2,105000020
+2815,2,105000030
+2816,2,105000040
+2817,3,105000050
+2818,3,105000060
+2819,3,105000070
+2820,3,105000080
+2821,1,106000010
+2822,2,106000020
+2823,2,106000030
+2824,2,106000040
+2825,3,106000050
+2826,3,106000060
+2827,3,106000070
+2828,3,106000080
+2829,1,107000010
+2830,2,107000020
+2831,2,107000030
+2832,2,107000040
+2833,3,107000050
+2834,3,107000060
+2835,3,107000070
+2836,3,107000080
+2837,1,108000010
+2838,2,108000020
+2839,2,108000030
+2840,2,108000040
+2841,3,108000050
+2842,3,108000060
+2843,3,108000070
+2844,3,108000080
+2845,1,109000010
+2846,2,109000020
+2847,2,109000030
+2848,2,109000040
+2849,3,109000050
+2850,3,109000060
+2851,3,109000070
+2852,3,109000080
+2853,1,110000010
+2854,2,110000020
+2855,2,110000030
+2856,2,110000040
+2857,3,110000050
+2858,3,110000060
+2859,3,110000070
+2860,3,110000080
+2861,2,180001
+2863,1,107000000
+2864,2,107000001
+2865,3,107000002
+2866,4,107000003
+2867,5,107000004
+2868,1,120000000
+2869,2,120000001
+2870,3,120000002
+2871,4,120000003
+2872,5,120000004
+2874,3,110000070
+2875,3,110000080
+2876,4,110000100
+2877,5,110000110
+2878,1,107000000
+2879,2,107000001
+2880,3,107000002
+2881,4,107000003
+2882,5,107000004
+2883,1,120000000
+2884,2,120000001
+2885,3,120000002
+2886,4,120000003
+2887,5,120000004
+2888,3,120023
+2889,3,120033
+2890,3,120043
+2891,3,120053
+2892,4,120024
+2893,4,120034
+2894,4,120044
+2895,4,120054
+2896,3,120240
+2897,3,120250
+2898,3,120260
+2899,3,120270
+2900,3,120300
+2901,3,120310
+2902,3,120320
+2903,3,120330
+2904,3,120340
+2905,3,120350
+2906,3,120360
+2907,3,120370
+2908,3,120380
+2909,3,120390
+2910,3,120400
+2911,3,120410
+2912,3,120420
+2913,3,120430
+2914,3,120450
+2915,3,120460
+2916,3,120550
+2917,3,120560
+2918,3,120570
+2919,3,120990
+2920,3,121000
+2921,3,121010
+2922,3,121020
+2923,4,140000
+2924,4,150010
+2925,4,150020
+2926,4,150030
+2927,4,150040
+2929,3,108000060
+2930,3,108000070
+2931,3,108000080
+2932,3,107000050
+2933,4,108000100
+2934,4,105000090
+2935,5,108000110
+2936,1,108000000
+2937,2,108000001
+2938,3,108000002
+2939,4,108000003
+2940,5,108000004
+2941,1,120000000
+2942,2,120000001
+2943,3,120000002
+2944,4,120000003
+2945,5,120000004
+2946,3,170004
+2948,3,102000060
+2949,3,102000070
+2950,3,102000080
+2951,3,103000050
+2952,3,105000050
+2953,4,102000100
+2954,4,102000110
+2955,4,106000090
+2956,4,109000090
+2957,5,102000120
+2958,1,102000000
+2959,2,102000001
+2960,3,102000002
+2961,4,102000003
+2962,5,102000004
+2963,1,112000000
+2964,2,112000001
+2965,3,112000002
+2966,4,112000003
+2967,5,112000004
+2968,3,170004
+2970,3,101000050
+2971,3,101000060
+2972,3,101000080
+2973,3,103000060
+2974,3,103000070
+2975,3,103000080
+2976,3,101000040
+2977,3,109000060
+2978,3,109000070
+2979,3,109000080
+2980,3,110000050
+2981,4,101000090
+2982,4,102000090
+2983,4,103000100
+2984,4,101000100
+2985,4,101000110
+2986,4,109000100
+2987,5,101000120
+2988,5,103000120
+2989,5,109000110
+2990,1,101000000
+2991,2,101000001
+2992,3,101000002
+2993,4,101000008
+2994,5,101000004
+2995,1,112000000
+2996,2,112000001
+2997,3,112000002
+2998,4,112000003
+2999,5,112000004
+3000,3,120023
+3001,3,120033
+3002,3,120043
+3003,3,120053
+3004,4,120024
+3005,4,120034
+3006,4,120044
+3007,4,120054
+3008,3,120240
+3009,3,120250
+3010,3,120260
+3011,3,120270
+3012,3,120300
+3013,3,120310
+3014,3,120320
+3015,3,120330
+3016,3,120340
+3017,3,120350
+3018,3,120360
+3019,3,120370
+3020,3,120380
+3021,3,120390
+3022,3,120400
+3023,3,120410
+3024,3,120420
+3025,3,120430
+3026,3,120450
+3027,3,120460
+3028,3,120550
+3029,3,120560
+3030,3,120570
+3031,3,120990
+3032,3,121000
+3033,3,121010
+3034,3,121020
+3035,4,140000
+3036,4,150010
+3037,4,150020
+3038,4,150030
+3039,4,150040
+3041,3,105000060
+3042,3,105000070
+3043,3,105000080
+3044,3,104000050
+3045,3,106000050
+3046,4,105000100
+3047,4,105000110
+3048,4,108000090
+3049,4,110000090
+3050,5,105000120
+3051,1,109000000
+3052,2,109000001
+3053,3,109000002
+3054,4,109000003
+3055,5,109000004
+3056,1,112000000
+3057,2,112000001
+3058,3,112000002
+3059,4,112000003
+3060,5,112000004
+3061,3,170004
+3063,3,107000060
+3064,3,107000070
+3065,3,107000080
+3066,3,108000050
+3067,3,109000050
+3068,4,107000100
+3069,4,103000090
+3070,5,107000110
+3071,1,105000000
+3072,2,105000001
+3073,3,105000002
+3074,4,105000003
+3075,5,105000004
+3076,1,120000000
+3077,2,120000001
+3078,3,120000002
+3079,4,120000003
+3080,5,120000004
+3081,3,130023
+3082,3,130033
+3083,3,130043
+3084,3,130053
+3085,4,130024
+3086,4,130034
+3087,4,130044
+3088,4,130054
+3089,3,130060
+3090,3,130070
+3091,3,130080
+3092,3,130090
+3093,3,130100
+3094,3,130110
+3095,3,130120
+3096,3,130130
+3097,3,130140
+3098,3,130150
+3099,3,130160
+3100,3,130170
+3101,3,130180
+3102,3,130190
+3103,3,130200
+3104,3,130420
+3105,3,130510
+3106,3,130520
+3107,3,130530
+3108,3,130540
+3109,3,130660
+3110,4,140000
+3111,4,150010
+3112,4,150020
+3113,4,150030
+3114,4,150040
+3116,3,106000060
+3117,3,106000070
+3118,3,106000080
+3119,3,101000070
+3120,3,110000060
+3121,4,106000100
+3122,4,106000110
+3123,4,104000090
+3124,5,106000120
+3125,1,103000000
+3126,2,103000001
+3127,3,103000002
+3128,4,103000003
+3129,5,103000004
+3130,1,112000000
+3131,2,112000001
+3132,3,112000002
+3133,4,112000003
+3134,5,112000004
+3135,3,170004
+3137,3,104000060
+3138,3,104000070
+3139,3,104000080
+3140,3,102000050
+3141,4,104000100
+3142,4,104000110
+3143,4,107000090
+3144,5,104000120
+3145,1,111000000
+3146,2,111000001
+3147,3,111000002
+3148,4,111000003
+3149,5,111000004
+3150,1,120000000
+3151,2,120000001
+3152,3,120000002
+3153,4,120000003
+3154,5,120000004
+3155,3,110023
+3156,3,110033
+3157,3,110043
+3158,3,110053
+3159,4,110024
+3160,4,110034
+3161,4,110044
+3162,4,110054
+3163,3,110060
+3164,3,110070
+3165,3,110080
+3166,3,110090
+3167,3,110100
+3168,3,110110
+3169,3,110120
+3170,3,110130
+3171,3,110140
+3172,3,110150
+3173,3,110160
+3174,3,110170
+3175,3,110180
+3176,3,110190
+3177,3,110200
+3178,3,110210
+3179,3,110220
+3180,3,110230
+3181,3,110240
+3182,3,110250
+3183,3,110260
+3184,3,110270
+3185,3,110620
+3186,3,110670
+3187,4,140000
+3188,4,150010
+3189,4,150020
+3190,4,150030
+3191,4,150040
+3193,3,101000050
+3194,3,101000060
+3195,3,101000080
+3196,3,103000060
+3197,3,103000070
+3198,3,103000080
+3199,3,101000040
+3200,3,109000060
+3201,3,109000070
+3202,3,109000080
+3203,3,110000050
+3204,4,101000090
+3205,4,102000090
+3206,4,103000100
+3207,4,101000100
+3208,4,101000110
+3209,4,109000100
+3210,5,101000120
+3211,5,103000120
+3212,5,109000110
+3213,1,101000000
+3214,2,101000001
+3215,3,101000002
+3216,4,101000008
+3217,5,101000004
+3218,1,120000000
+3219,2,120000001
+3220,3,120000002
+3221,4,120000003
+3222,5,120000004
+3223,3,170004
+3225,3,110000070
+3226,3,110000080
+3227,4,110000100
+3228,5,110000110
+3229,1,107000000
+3230,2,107000001
+3231,3,107000002
+3232,4,107000003
+3233,5,107000004
+3234,1,120000000
+3235,2,120000001
+3236,3,120000002
+3237,4,120000003
+3238,5,120000004
+3239,3,180004
+3241,3,105000060
+3242,3,105000070
+3243,3,105000080
+3244,3,104000050
+3245,3,106000050
+3246,4,105000100
+3247,4,105000110
+3248,4,108000090
+3249,4,110000090
+3250,5,105000120
+3251,1,109000000
+3252,2,109000001
+3253,3,109000002
+3254,4,109000003
+3255,5,109000004
+3256,1,112000000
+3257,2,112000001
+3258,3,112000002
+3259,4,112000003
+3260,5,112000004
+3261,3,170004
+3263,3,108000060
+3264,3,108000070
+3265,3,108000080
+3266,3,107000050
+3267,4,108000100
+3268,4,105000090
+3269,5,108000110
+3270,1,108000000
+3271,2,108000001
+3272,3,108000002
+3273,4,108000003
+3274,5,108000004
+3275,1,120000000
+3276,2,120000001
+3277,3,120000002
+3278,4,120000003
+3279,5,120000004
+3280,4,120024
+3281,4,120034
+3282,4,120044
+3283,4,120054
+3284,3,120240
+3285,3,120250
+3286,3,120260
+3287,3,120270
+3288,3,120300
+3289,3,120310
+3290,3,120320
+3291,3,120330
+3292,3,120340
+3293,3,120350
+3294,3,120360
+3295,3,120370
+3296,3,120380
+3297,3,120390
+3298,3,120400
+3299,3,120410
+3300,3,120420
+3301,3,120430
+3302,3,120450
+3303,3,120460
+3304,3,120550
+3305,3,120560
+3306,3,120570
+3307,3,120990
+3308,3,121000
+3309,3,121010
+3310,3,121020
+3311,4,140000
+3312,4,150010
+3313,4,150020
+3314,4,150030
+3315,4,150040
+3317,3,104000060
+3318,3,104000070
+3319,3,104000080
+3320,3,102000050
+3321,4,104000100
+3322,4,104000110
+3323,4,107000090
+3324,5,104000120
+3325,1,111000000
+3326,2,111000001
+3327,3,111000002
+3328,4,111000003
+3329,5,111000004
+3330,1,120000000
+3331,2,120000001
+3332,3,120000002
+3333,4,120000003
+3334,5,120000004
+3335,4,110024
+3336,4,110034
+3337,4,110044
+3338,4,110054
+3339,3,110060
+3340,3,110070
+3341,3,110080
+3342,3,110090
+3343,3,110100
+3344,3,110110
+3345,3,110120
+3346,3,110130
+3347,3,110140
+3348,3,110150
+3349,3,110160
+3350,3,110170
+3351,3,110180
+3352,3,110190
+3353,3,110200
+3354,3,110210
+3355,3,110220
+3356,3,110230
+3357,3,110240
+3358,3,110250
+3359,3,110260
+3360,3,110270
+3361,3,110620
+3362,3,110670
+3363,4,140000
+3364,4,150010
+3365,4,150020
+3366,4,150030
+3367,4,150040
+3369,3,101000050
+3370,3,101000060
+3371,3,101000080
+3372,3,103000060
+3373,3,103000070
+3374,3,103000080
+3375,3,101000040
+3376,3,109000060
+3377,3,109000070
+3378,3,109000080
+3379,3,110000050
+3380,4,101000090
+3381,4,102000090
+3382,4,103000100
+3383,4,101000100
+3384,4,101000110
+3385,4,109000100
+3386,5,101000120
+3387,5,103000120
+3388,5,109000110
+3389,1,101000000
+3390,2,101000001
+3391,3,101000002
+3392,4,101000008
+3393,5,101000004
+3394,1,112000000
+3395,2,112000001
+3396,3,112000002
+3397,4,112000003
+3398,5,112000004
+3399,3,170004
+3401,3,107000060
+3402,3,107000070
+3403,3,107000080
+3404,3,108000050
+3405,3,109000050
+3406,4,107000100
+3407,4,103000090
+3408,5,107000110
+3409,1,105000000
+3410,2,105000001
+3411,3,105000002
+3412,4,105000003
+3413,5,105000004
+3414,1,120000000
+3415,2,120000001
+3416,3,120000002
+3417,4,120000003
+3418,5,120000004
+3419,4,120024
+3420,4,120034
+3421,4,120044
+3422,4,120054
+3423,3,120240
+3424,3,120250
+3425,3,120260
+3426,3,120270
+3427,3,120300
+3428,3,120310
+3429,3,120320
+3430,3,120330
+3431,3,120340
+3432,3,120350
+3433,3,120360
+3434,3,120370
+3435,3,120380
+3436,3,120390
+3437,3,120400
+3438,3,120410
+3439,3,120420
+3440,3,120430
+3441,3,120450
+3442,3,120460
+3443,3,120550
+3444,3,120560
+3445,3,120570
+3446,3,120990
+3447,3,121000
+3448,3,121010
+3449,3,121020
+3450,4,140000
+3451,4,150010
+3452,4,150020
+3453,4,150030
+3454,4,150040
+3456,3,108000060
+3457,3,108000070
+3458,3,108000080
+3459,3,107000050
+3460,4,108000100
+3461,4,105000090
+3462,5,108000110
+3463,1,108000000
+3464,2,108000001
+3465,3,108000002
+3466,4,108000003
+3467,5,108000004
+3468,1,120000000
+3469,2,120000001
+3470,3,120000002
+3471,4,120000003
+3472,5,120000004
+3473,3,170004
+3475,3,102000060
+3476,3,102000070
+3477,3,102000080
+3478,3,103000050
+3479,3,105000050
+3480,4,102000100
+3481,4,102000110
+3482,4,106000090
+3483,4,109000090
+3484,5,102000120
+3485,1,102000000
+3486,2,102000001
+3487,3,102000002
+3488,4,102000003
+3489,5,102000004
+3490,1,112000000
+3491,2,112000001
+3492,3,112000002
+3493,4,112000003
+3494,5,112000004
+3495,3,180004
+3497,3,106000060
+3498,3,106000070
+3499,3,106000080
+3500,3,101000070
+3501,3,110000060
+3502,4,106000100
+3503,4,106000110
+3504,4,104000090
+3505,5,106000120
+3506,1,103000000
+3507,2,103000001
+3508,3,103000002
+3509,4,103000003
+3510,5,103000004
+3511,1,112000000
+3512,2,112000001
+3513,3,112000002
+3514,4,112000003
+3515,5,112000004
+3516,4,130024
+3517,4,130034
+3518,4,130044
+3519,4,130054
+3520,3,130060
+3521,3,130070
+3522,3,130080
+3523,3,130090
+3524,3,130100
+3525,3,130110
+3526,3,130120
+3527,3,130130
+3528,3,130140
+3529,3,130150
+3530,3,130160
+3531,3,130170
+3532,3,130180
+3533,3,130190
+3534,3,130200
+3535,3,130420
+3536,3,130510
+3537,3,130520
+3538,3,130530
+3539,3,130540
+3540,3,130660
+3541,4,140000
+3542,4,150010
+3543,4,150020
+3544,4,150030
+3545,4,150040
+3547,3,110000070
+3548,3,110000080
+3549,4,110000100
+3550,5,110000110
+3551,1,107000000
+3552,2,107000001
+3553,3,107000002
+3554,4,107000003
+3555,5,107000004
+3556,1,120000000
+3557,2,120000001
+3558,3,120000002
+3559,4,120000003
+3560,5,120000004
+3561,3,170004
+3563,3,105000060
+3564,3,105000070
+3565,3,105000080
+3566,3,104000050
+3567,3,106000050
+3568,4,105000100
+3569,4,105000110
+3570,4,108000090
+3571,4,110000090
+3572,5,105000120
+3573,1,109000000
+3574,2,109000001
+3575,3,109000002
+3576,4,109000003
+3577,5,109000004
+3578,1,112000000
+3579,2,112000001
+3580,3,112000002
+3581,4,112000003
+3582,5,112000004
+3583,4,120024
+3584,4,120034
+3585,4,120044
+3586,4,120054
+3587,3,120240
+3588,3,120250
+3589,3,120260
+3590,3,120270
+3591,3,120300
+3592,3,120310
+3593,3,120320
+3594,3,120330
+3595,3,120340
+3596,3,120350
+3597,3,120360
+3598,3,120370
+3599,3,120380
+3600,3,120390
+3601,3,120400
+3602,3,120410
+3603,3,120420
+3604,3,120430
+3605,3,120450
+3606,3,120460
+3607,3,120550
+3608,3,120560
+3609,3,120570
+3610,3,120990
+3611,3,121000
+3612,3,121010
+3613,3,121020
+3614,4,140000
+3615,4,150010
+3616,4,150020
+3617,4,150030
+3618,4,150040
+3620,1,170000
+3621,2,170001
+3622,3,170002
+3623,4,170003
+3624,5,170004
+3625,1,180000
+3626,2,180001
+3627,3,180002
+3628,4,180003
+3629,5,180004
+3630,4,140000
+3631,1,201000010
+3632,1,292000010
+3633,1,299000040
+3634,1,299000070
+3635,1,299000110
+3636,1,299000120
+3637,1,299000140
+3638,2,202000010
+3639,2,290000010
+3640,2,299000010
+3641,2,299000150
+3642,2,299000190
+3643,2,299000200
+3644,2,299000210
+3645,3,298000050
+3646,3,298000060
+3647,3,299000060
+3648,3,299000170
+3649,5,150010
+3650,5,150020
+3651,5,150030
+3652,5,150040
+3654,3,105000060
+3655,3,105000070
+3656,3,105000080
+3657,3,104000050
+3658,3,106000050
+3659,4,105000100
+3660,4,105000110
+3661,4,108000090
+3662,4,110000090
+3663,5,105000120
+3664,1,109000000
+3665,2,109000001
+3666,3,109000002
+3667,4,109000003
+3668,5,109000004
+3669,1,112000000
+3670,2,112000001
+3671,3,112000002
+3672,4,112000003
+3673,5,112000004
+3674,3,170004
+3676,3,108000060
+3677,3,108000070
+3678,3,108000080
+3679,3,107000050
+3680,4,108000100
+3681,4,105000090
+3682,5,108000110
+3683,1,108000000
+3684,2,108000001
+3685,3,108000002
+3686,4,108000003
+3687,5,108000004
+3688,1,120000000
+3689,2,120000001
+3690,3,120000002
+3691,4,120000003
+3692,5,120000004
+3693,3,180004
+3695,3,106000060
+3696,3,106000070
+3697,3,106000080
+3698,3,101000070
+3699,3,110000060
+3700,4,106000100
+3701,4,106000110
+3702,4,104000090
+3703,5,106000120
+3704,1,103000000
+3705,2,103000001
+3706,3,103000002
+3707,4,103000003
+3708,5,103000004
+3709,1,112000000
+3710,2,112000001
+3711,3,112000002
+3712,4,112000003
+3713,5,112000004
+3714,3,170004
+3716,3,104000170
+3717,1,115000000
+3718,2,115000001
+3719,3,115000002
+3720,4,115000003
+3721,5,115000004
+3722,1,120000000
+3723,2,120000001
+3724,3,120000002
+3725,4,120000003
+3726,5,120000004
+3727,4,120024
+3728,4,120034
+3729,4,120044
+3730,4,120054
+3731,3,120241
+3732,3,120251
+3733,3,120261
+3734,3,120271
+3735,3,120300
+3736,3,120310
+3737,3,120320
+3738,3,120330
+3739,3,120340
+3740,3,120350
+3741,3,120360
+3742,3,120370
+3743,3,120380
+3744,3,120390
+3745,3,120400
+3746,3,120410
+3747,3,120420
+3748,3,120430
+3749,3,120450
+3750,3,120460
+3751,3,120550
+3752,3,120560
+3753,3,120570
+3754,3,120990
+3755,3,121000
+3756,3,121010
+3757,3,121020
+3758,4,140000
+3759,4,150010
+3760,4,150020
+3761,4,150030
+3762,4,150040
+3764,3,102000060
+3765,3,102000070
+3766,3,102000080
+3767,3,103000050
+3768,3,105000050
+3769,4,102000100
+3770,4,102000110
+3771,4,106000090
+3772,4,109000090
+3773,5,102000120
+3774,1,102000000
+3775,2,102000001
+3776,3,102000002
+3777,4,102000003
+3778,5,102000004
+3779,1,112000000
+3780,2,112000001
+3781,3,112000002
+3782,4,112000003
+3783,5,112000004
+3784,4,110024
+3785,4,110034
+3786,4,110044
+3787,4,110054
+3788,3,110060
+3789,3,110070
+3790,3,110080
+3791,3,110090
+3792,3,110100
+3793,3,110110
+3794,3,110120
+3795,3,110130
+3796,3,110140
+3797,3,110150
+3798,3,110160
+3799,3,110170
+3800,3,110180
+3801,3,110190
+3802,3,110200
+3803,3,110210
+3804,3,110220
+3805,3,110230
+3806,3,110240
+3807,3,110250
+3808,3,110260
+3809,3,110270
+3810,3,110620
+3811,3,110670
+3812,4,140000
+3813,4,150010
+3814,4,150020
+3815,4,150030
+3816,4,150040
+3818,3,104000060
+3819,3,104000070
+3820,3,104000080
+3821,3,102000050
+3822,4,104000100
+3823,4,104000110
+3824,4,107000090
+3825,5,104000120
+3826,1,111000000
+3827,2,111000001
+3828,3,111000002
+3829,4,111000003
+3830,5,111000004
+3831,1,120000000
+3832,2,120000001
+3833,3,120000002
+3834,4,120000003
+3835,5,120000004
+3836,4,110024
+3837,4,110034
+3838,4,110044
+3839,4,110054
+3840,3,110060
+3841,3,110070
+3842,3,110080
+3843,3,110090
+3844,3,110100
+3845,3,110110
+3846,3,110120
+3847,3,110130
+3848,3,110140
+3849,3,110150
+3850,3,110160
+3851,3,110170
+3852,3,110180
+3853,3,110190
+3854,3,110200
+3855,3,110210
+3856,3,110220
+3857,3,110230
+3858,3,110240
+3859,3,110250
+3860,3,110260
+3861,3,110270
+3862,3,110620
+3863,3,110670
+3864,4,140000
+3865,4,150010
+3866,4,150020
+3867,4,150030
+3868,4,150040
+3870,3,110000070
+3871,3,110000080
+3872,4,110000100
+3873,5,110000110
+3874,1,107000000
+3875,2,107000001
+3876,3,107000002
+3877,4,107000003
+3878,5,107000004
+3879,1,120000000
+3880,2,120000001
+3881,3,120000002
+3882,4,120000003
+3883,5,120000004
+3884,4,130024
+3885,4,130034
+3886,4,130044
+3887,4,130054
+3888,3,130060
+3889,3,130070
+3890,3,130080
+3891,3,130090
+3892,3,130100
+3893,3,130110
+3894,3,130120
+3895,3,130130
+3896,3,130140
+3897,3,130150
+3898,3,130160
+3899,3,130170
+3900,3,130180
+3901,3,130190
+3902,3,130200
+3903,3,130420
+3904,3,130510
+3905,3,130520
+3906,3,130530
+3907,3,130540
+3908,3,130660
+3909,4,140000
+3910,4,150010
+3911,4,150020
+3912,4,150030
+3913,4,150040
+3915,3,101000050
+3916,3,101000060
+3917,3,101000080
+3918,3,103000060
+3919,3,103000070
+3920,3,103000080
+3921,3,101000040
+3922,3,109000060
+3923,3,109000070
+3924,3,109000080
+3925,3,110000050
+3926,4,101000090
+3927,4,102000090
+3928,4,103000100
+3929,4,101000100
+3930,4,101000110
+3931,4,109000100
+3932,5,101000120
+3933,5,101000160
+3934,5,103000120
+3935,5,109000110
+3936,1,101000000
+3937,2,101000001
+3938,3,101000002
+3939,4,101000008
+3940,5,101000004
+3941,1,120000000
+3942,2,120000001
+3943,3,120000002
+3944,4,120000003
+3945,5,120000004
+3946,3,170004
+3948,3,107000060
+3949,3,107000070
+3950,3,107000080
+3951,3,108000050
+3952,3,109000050
+3953,4,107000100
+3954,4,103000090
+3955,5,107000110
+3956,1,105000000
+3957,2,105000001
+3958,3,105000002
+3959,4,105000003
+3960,5,105000004
+3961,1,120000000
+3962,2,120000001
+3963,3,120000002
+3964,4,120000003
+3965,5,120000004
+3966,3,170004
+3968,3,104000170
+3969,1,115000000
+3970,2,115000001
+3971,3,115000002
+3972,4,115000003
+3973,5,115000004
+3974,1,120000000
+3975,2,120000001
+3976,3,120000002
+3977,4,120000003
+3978,5,120000004
+3979,4,120024
+3980,4,120034
+3981,4,120044
+3982,4,120054
+3983,3,120241
+3984,3,120251
+3985,3,120261
+3986,3,120271
+3987,3,120300
+3988,3,120310
+3989,3,120320
+3990,3,120330
+3991,3,120340
+3992,3,120350
+3993,3,120360
+3994,3,120370
+3995,3,120380
+3996,3,120390
+3997,3,120400
+3998,3,120410
+3999,3,120420
+4000,3,120430
+4001,3,120450
+4002,3,120460
+4003,3,120550
+4004,3,120560
+4005,3,120570
+4006,3,120990
+4007,3,121000
+4008,3,121010
+4009,3,121020
+4010,4,140000
+4011,4,150010
+4012,4,150020
+4013,4,150030
+4014,4,150040
+4016,1,101000000
+4017,2,101000001
+4018,3,101000002
+4019,4,101000008
+4020,5,101000012
+4021,1,120000000
+4022,2,120000001
+4023,3,120000002
+4024,4,120000003
+4025,5,120000004
+4027,1,101000000
+4028,2,101000001
+4029,3,101000002
+4030,4,101000008
+4031,5,101000011
+4032,1,120000000
+4033,2,120000001
+4034,3,120000002
+4035,4,120000003
+4036,5,120000004
+4038,3,101000050
+4039,3,101000060
+4040,3,101000080
+4041,3,103000060
+4042,3,103000070
+4043,3,103000080
+4044,3,101000040
+4045,3,109000060
+4046,3,109000070
+4047,3,109000080
+4048,3,110000050
+4049,4,101000090
+4050,4,102000090
+4051,4,103000100
+4052,4,101000100
+4053,4,101000110
+4054,4,109000100
+4055,5,101000120
+4056,5,101000160
+4057,5,103000120
+4058,5,109000110
+4059,1,101000000
+4060,2,101000001
+4061,3,101000002
+4062,4,101000008
+4063,5,101000004
+4064,1,120000000
+4065,2,120000001
+4066,3,120000002
+4067,4,120000003
+4068,5,120000004
+4069,4,120024
+4070,4,120034
+4071,4,120044
+4072,4,120054
+4073,3,120241
+4074,3,120251
+4075,3,120261
+4076,3,120271
+4077,3,120300
+4078,3,120310
+4079,3,120320
+4080,3,120330
+4081,3,120340
+4082,3,120350
+4083,3,120360
+4084,3,120370
+4085,3,120380
+4086,3,120390
+4087,3,120400
+4088,3,120410
+4089,3,120420
+4090,3,120430
+4091,3,120450
+4092,3,120460
+4093,3,120550
+4094,3,120560
+4095,3,120570
+4096,3,120990
+4097,3,121000
+4098,3,121010
+4099,3,121020
+4100,4,140000
+4101,4,150010
+4102,4,150020
+4103,4,150030
+4104,4,150040
+4106,3,108000060
+4107,3,108000070
+4108,3,108000080
+4109,3,107000050
+4110,4,108000100
+4111,4,105000090
+4112,5,108000110
+4113,1,108000000
+4114,2,108000001
+4115,3,108000002
+4116,4,108000003
+4117,5,108000004
+4118,1,120000000
+4119,2,120000001
+4120,3,120000002
+4121,4,120000003
+4122,5,120000004
+4123,3,170004
+4125,3,102000060
+4126,3,102000070
+4127,3,102000080
+4128,3,103000050
+4129,3,105000050
+4130,4,102000100
+4131,4,102000110
+4132,4,106000090
+4133,4,109000090
+4134,5,102000120
+4135,1,102000000
+4136,2,102000001
+4137,3,102000002
+4138,4,102000003
+4139,5,102000004
+4140,1,112000000
+4141,2,112000001
+4142,3,112000002
+4143,4,112000003
+4144,5,112000004
+4145,4,110024
+4146,4,110034
+4147,4,110044
+4148,4,110054
+4149,3,110060
+4150,3,110070
+4151,3,110080
+4152,3,110090
+4153,3,110100
+4154,3,110110
+4155,3,110120
+4156,3,110130
+4157,3,110140
+4158,3,110150
+4159,3,110160
+4160,3,110170
+4161,3,110180
+4162,3,110190
+4163,3,110200
+4164,3,110210
+4165,3,110220
+4166,3,110230
+4167,3,110240
+4168,3,110250
+4169,3,110260
+4170,3,110270
+4171,3,110620
+4172,3,110670
+4173,4,140000
+4174,4,150010
+4175,4,150020
+4176,4,150030
+4177,4,150040
+4179,3,104000170
+4180,4,104000180
+4181,5,104000190
+4182,1,115000000
+4183,2,115000001
+4184,3,115000002
+4185,4,115000003
+4186,5,115000004
+4187,1,120000000
+4188,2,120000001
+4189,3,120000002
+4190,4,120000003
+4191,5,120000004
+4192,4,120024
+4193,4,120034
+4194,4,120044
+4195,4,120054
+4196,3,120241
+4197,3,120251
+4198,3,120261
+4199,3,120271
+4200,3,120300
+4201,3,120310
+4202,3,120320
+4203,3,120330
+4204,3,120340
+4205,3,120350
+4206,3,120360
+4207,3,120370
+4208,3,120380
+4209,3,120390
+4210,3,120400
+4211,3,120410
+4212,3,120420
+4213,3,120430
+4214,3,120450
+4215,3,120460
+4216,3,120550
+4217,3,120560
+4218,3,120570
+4219,3,120990
+4220,3,121000
+4221,3,121010
+4222,3,121020
+4223,4,140000
+4224,4,150010
+4225,4,150020
+4226,4,150030
+4227,4,150040
+4229,3,110000070
+4230,3,110000080
+4231,4,110000100
+4232,5,110000110
+4233,1,107000000
+4234,2,107000001
+4235,3,107000002
+4236,4,107000003
+4237,5,107000004
+4238,1,120000000
+4239,2,120000001
+4240,3,120000002
+4241,4,120000003
+4242,5,120000004
+4243,4,120024
+4244,4,120034
+4245,4,120044
+4246,4,120054
+4247,3,120241
+4248,3,120251
+4249,3,120261
+4250,3,120271
+4251,3,120300
+4252,3,120310
+4253,3,120320
+4254,3,120330
+4255,3,120340
+4256,3,120350
+4257,3,120360
+4258,3,120370
+4259,3,120380
+4260,3,120390
+4261,3,120400
+4262,3,120410
+4263,3,120420
+4264,3,120430
+4265,3,120450
+4266,3,120460
+4267,3,120550
+4268,3,120560
+4269,3,120570
+4270,3,120990
+4271,3,121000
+4272,3,121010
+4273,3,121020
+4274,4,140000
+4275,4,150010
+4276,4,150020
+4277,4,150030
+4278,4,150040
+4280,3,106000060
+4281,3,106000070
+4282,3,106000080
+4283,3,101000070
+4284,3,110000060
+4285,4,106000100
+4286,4,106000110
+4287,4,104000090
+4288,5,106000120
+4289,1,103000000
+4290,2,103000001
+4291,3,103000002
+4292,4,103000003
+4293,5,103000004
+4294,1,112000000
+4295,2,112000001
+4296,3,112000002
+4297,4,112000003
+4298,5,112000004
+4299,3,170004
+4301,3,105000060
+4302,3,105000070
+4303,3,105000080
+4304,3,104000050
+4305,3,106000050
+4306,4,105000100
+4307,4,105000110
+4308,4,108000090
+4309,4,110000090
+4310,5,105000120
+4311,1,109000000
+4312,2,109000001
+4313,3,109000002
+4314,4,109000003
+4315,5,109000004
+4316,1,112000000
+4317,2,112000001
+4318,3,112000002
+4319,4,112000003
+4320,5,112000004
+4321,4,130024
+4322,4,130034
+4323,4,130044
+4324,4,130054
+4325,3,130060
+4326,3,130070
+4327,3,130080
+4328,3,130090
+4329,3,130100
+4330,3,130110
+4331,3,130120
+4332,3,130130
+4333,3,130140
+4334,3,130150
+4335,3,130160
+4336,3,130170
+4337,3,130180
+4338,3,130190
+4339,3,130200
+4340,3,130420
+4341,3,130510
+4342,3,130520
+4343,3,130530
+4344,3,130540
+4345,3,130660
+4346,4,140000
+4347,4,150010
+4348,4,150020
+4349,4,150030
+4350,4,150040
+4352,3,101000050
+4353,3,101000060
+4354,3,101000080
+4355,3,103000060
+4356,3,103000070
+4357,3,103000080
+4358,3,101000040
+4359,3,109000060
+4360,3,109000070
+4361,3,109000080
+4362,3,110000050
+4363,4,101000090
+4364,4,102000090
+4365,4,103000100
+4366,4,101000100
+4367,4,101000110
+4368,4,109000100
+4369,5,101000120
+4370,5,103000120
+4371,5,109000110
+4372,1,101000000
+4373,2,101000001
+4374,3,101000002
+4375,4,101000008
+4376,5,101000004
+4377,1,112000000
+4378,2,112000001
+4379,3,112000002
+4380,4,112000003
+4381,5,112000004
+4382,3,180004
+4384,3,104000060
+4385,3,104000070
+4386,3,104000080
+4387,3,102000050
+4388,4,104000100
+4389,4,104000110
+4390,4,107000090
+4391,5,104000120
+4392,1,111000000
+4393,2,111000001
+4394,3,111000002
+4395,4,111000003
+4396,5,111000004
+4397,1,120000000
+4398,2,120000001
+4399,3,120000002
+4400,4,120000003
+4401,5,120000004
+4402,4,110024
+4403,4,110034
+4404,4,110044
+4405,4,110054
+4406,3,110060
+4407,3,110070
+4408,3,110080
+4409,3,110090
+4410,3,110100
+4411,3,110110
+4412,3,110120
+4413,3,110130
+4414,3,110140
+4415,3,110150
+4416,3,110160
+4417,3,110170
+4418,3,110180
+4419,3,110190
+4420,3,110200
+4421,3,110210
+4422,3,110220
+4423,3,110230
+4424,3,110240
+4425,3,110250
+4426,3,110260
+4427,3,110270
+4428,3,110620
+4429,3,110670
+4430,4,140000
+4431,4,150010
+4432,4,150020
+4433,4,150030
+4434,4,150040
+4436,3,107000060
+4437,3,107000070
+4438,3,107000080
+4439,3,108000050
+4440,3,109000050
+4441,4,107000100
+4442,4,103000090
+4443,5,107000110
+4444,1,105000000
+4445,2,105000001
+4446,3,105000002
+4447,4,105000003
+4448,5,105000004
+4449,1,120000000
+4450,2,120000001
+4451,3,120000002
+4452,4,120000003
+4453,5,120000004
+4454,4,130024
+4455,4,130034
+4456,4,130044
+4457,4,130054
+4458,3,130060
+4459,3,130070
+4460,3,130080
+4461,3,130090
+4462,3,130100
+4463,3,130110
+4464,3,130120
+4465,3,130130
+4466,3,130140
+4467,3,130150
+4468,3,130160
+4469,3,130170
+4470,3,130180
+4471,3,130190
+4472,3,130200
+4473,3,130420
+4474,3,130510
+4475,3,130520
+4476,3,130530
+4477,3,130540
+4478,3,130660
+4479,4,140000
+4480,4,150010
+4481,4,150020
+4482,4,150030
+4483,4,150040
+4485,1,109000010
+4486,2,109000020
+4487,2,109000030
+4488,2,109000040
+4489,3,109000050
+4490,3,109000060
+4491,3,109000070
+4492,3,109000080
+4493,4,109000090
+4494,4,109000100
+4495,5,109000110
+4496,1,170000
+4497,2,170001
+4498,3,170002
+4499,4,170003
+4500,5,170004
+4501,1,180000
+4502,2,180001
+4503,3,180002
+4504,4,180003
+4505,5,180004
+4506,1,201000010
+4507,1,292000010
+4508,1,299000040
+4509,1,299000070
+4510,1,299000110
+4511,1,299000120
+4512,1,299000140
+4513,2,202000010
+4514,2,290000010
+4515,2,299000010
+4516,2,299000150
+4517,2,299000190
+4518,2,299000200
+4519,2,299000210
+4520,3,298000050
+4521,3,298000060
+4522,3,299000060
+4523,3,299000170
+4524,4,140000
+4525,5,150010
+4526,5,150020
+4527,5,150030
+4528,5,150040
+4530,1,109000010
+4531,2,109000020
+4532,2,109000030
+4533,2,109000040
+4534,3,109000050
+4535,3,109000060
+4536,3,109000070
+4537,3,109000080
+4538,4,109000090
+4539,4,109000100
+4540,5,109000110
+4541,1,170000
+4542,2,170001
+4543,3,170002
+4544,4,170003
+4545,5,170004
+4546,1,180000
+4547,2,180001
+4548,3,180002
+4549,4,180003
+4550,5,180004
+4551,1,201000010
+4552,1,292000010
+4553,1,299000040
+4554,1,299000070
+4555,1,299000110
+4556,1,299000120
+4557,1,299000140
+4558,2,202000010
+4559,2,290000010
+4560,2,299000010
+4561,2,299000150
+4562,2,299000190
+4563,2,299000200
+4564,2,299000210
+4565,3,298000050
+4566,3,298000060
+4567,3,299000060
+4568,3,299000170
+4569,4,140000
+4570,5,150010
+4571,5,150020
+4572,5,150030
+4573,5,150040
+4575,3,109000050
+4576,3,109000060
+4577,3,109000070
+4578,3,109000080
+4579,4,109000090
+4580,4,109000100
+4581,5,109000110
+4582,1,170000
+4583,2,170001
+4584,3,170002
+4585,4,170003
+4586,5,170004
+4587,1,180000
+4588,2,180001
+4589,3,180002
+4590,4,180003
+4591,5,180004
+4592,1,201000010
+4593,1,292000010
+4594,1,299000040
+4595,1,299000070
+4596,1,299000110
+4597,1,299000120
+4598,1,299000140
+4599,2,202000010
+4600,2,290000010
+4601,2,299000010
+4602,2,299000150
+4603,2,299000190
+4604,2,299000200
+4605,2,299000210
+4606,3,298000050
+4607,3,298000060
+4608,3,299000060
+4609,3,299000170
+4610,4,140000
+4611,5,150010
+4612,5,150020
+4613,5,150030
+4614,5,150040
+4616,3,109000050
+4617,3,109000060
+4618,3,109000070
+4619,3,109000080
+4620,4,109000090
+4621,4,109000100
+4622,5,109000110
+4623,1,170000
+4624,2,170001
+4625,3,170002
+4626,4,170003
+4627,5,170004
+4628,1,180000
+4629,2,180001
+4630,3,180002
+4631,4,180003
+4632,5,180004
+4633,1,201000010
+4634,1,292000010
+4635,1,299000040
+4636,1,299000070
+4637,1,299000110
+4638,1,299000120
+4639,1,299000140
+4640,2,202000010
+4641,2,290000010
+4642,2,299000010
+4643,2,299000150
+4644,2,299000190
+4645,2,299000200
+4646,2,299000210
+4647,3,298000050
+4648,3,298000060
+4649,3,299000060
+4650,3,299000170
+4651,4,140000
+4652,5,150010
+4653,5,150020
+4654,5,150030
+4655,5,150040
+4657,3,109000050
+4658,3,109000060
+4659,3,109000070
+4660,3,109000080
+4661,4,109000090
+4662,4,109000100
+4663,5,109000110
+4664,1,170000
+4665,2,170001
+4666,3,170002
+4667,4,170003
+4668,5,170004
+4669,1,180000
+4670,2,180001
+4671,3,180002
+4672,4,180003
+4673,5,180004
+4674,1,201000010
+4675,1,292000010
+4676,1,299000040
+4677,1,299000070
+4678,1,299000110
+4679,1,299000120
+4680,1,299000140
+4681,2,202000010
+4682,2,290000010
+4683,2,299000010
+4684,2,299000150
+4685,2,299000190
+4686,2,299000200
+4687,2,299000210
+4688,3,298000050
+4689,3,298000060
+4690,3,299000060
+4691,3,299000170
+4692,4,140000
+4693,5,150010
+4694,5,150020
+4695,5,150030
+4696,5,150040
+4697,5,190000
+4698,5,200000
+4699,5,210000
+4701,3,102000060
+4702,3,102000070
+4703,3,102000080
+4704,3,103000050
+4705,3,105000050
+4706,4,102000100
+4707,4,102000110
+4708,4,106000090
+4709,4,109000090
+4710,5,102000120
+4711,1,102000000
+4712,2,102000001
+4713,3,102000002
+4714,4,102000003
+4715,5,102000004
+4716,1,112000000
+4717,2,112000001
+4718,3,112000002
+4719,4,112000003
+4720,5,112000004
+4721,3,170004
+4722,4,170005
+4724,3,110000070
+4725,3,110000080
+4726,4,110000100
+4727,5,110000110
+4728,1,107000000
+4729,2,107000001
+4730,3,107000002
+4731,4,107000003
+4732,5,107000004
+4733,1,120000000
+4734,2,120000001
+4735,3,120000002
+4736,4,120000003
+4737,5,120000004
+4738,4,120024
+4739,4,120034
+4740,4,120044
+4741,4,120054
+4742,3,120241
+4743,3,120251
+4744,3,120261
+4745,3,120271
+4746,3,120300
+4747,3,120310
+4748,3,120320
+4749,3,120330
+4750,3,120340
+4751,3,120350
+4752,3,120360
+4753,3,120370
+4754,3,120380
+4755,3,120390
+4756,3,120400
+4757,3,120410
+4758,3,120420
+4759,3,120430
+4760,3,120450
+4761,3,120460
+4762,3,120550
+4763,3,120560
+4764,3,120570
+4765,3,120990
+4766,3,121000
+4767,3,121010
+4768,3,121020
+4769,4,140000
+4770,4,150010
+4771,4,150020
+4772,4,150030
+4773,4,150040
+4775,3,105000060
+4776,3,105000070
+4777,3,105000080
+4778,3,104000050
+4779,3,106000050
+4780,4,105000100
+4781,4,105000110
+4782,4,108000090
+4783,4,110000090
+4784,5,105000120
+4785,1,109000000
+4786,2,109000001
+4787,3,109000002
+4788,4,109000003
+4789,5,109000004
+4790,1,112000000
+4791,2,112000001
+4792,3,112000002
+4793,4,112000003
+4794,5,112000004
+4795,4,130024
+4796,4,130034
+4797,4,130044
+4798,4,130054
+4799,3,130060
+4800,3,130070
+4801,3,130080
+4802,3,130090
+4803,3,130100
+4804,3,130110
+4805,3,130120
+4806,3,130130
+4807,3,130140
+4808,3,130150
+4809,3,130160
+4810,3,130170
+4811,3,130180
+4812,3,130190
+4813,3,130200
+4814,3,130420
+4815,3,130510
+4816,3,130520
+4817,3,130530
+4818,3,130540
+4819,3,130660
+4820,4,140000
+4821,4,150010
+4822,4,150020
+4823,4,150030
+4824,4,150040
+4826,3,104000060
+4827,3,104000070
+4828,3,104000080
+4829,3,102000050
+4830,4,104000100
+4831,4,104000110
+4832,4,107000090
+4833,5,104000120
+4834,1,111000000
+4835,2,111000001
+4836,3,111000002
+4837,4,111000003
+4838,5,111000004
+4839,1,120000000
+4840,2,120000001
+4841,3,120000002
+4842,4,120000003
+4843,5,120000004
+4844,4,110024
+4845,4,110034
+4846,4,110044
+4847,4,110054
+4848,3,110060
+4849,3,110070
+4850,3,110080
+4851,3,110090
+4852,3,110100
+4853,3,110110
+4854,3,110120
+4855,3,110130
+4856,3,110140
+4857,3,110150
+4858,3,110160
+4859,3,110170
+4860,3,110180
+4861,3,110190
+4862,3,110200
+4863,3,110210
+4864,3,110220
+4865,3,110230
+4866,3,110240
+4867,3,110250
+4868,3,110260
+4869,3,110270
+4870,3,110620
+4871,3,110670
+4872,4,140000
+4873,4,150010
+4874,4,150020
+4875,4,150030
+4876,4,150040
+4878,3,107000060
+4879,3,107000070
+4880,3,107000080
+4881,3,108000050
+4882,3,109000050
+4883,4,107000100
+4884,4,103000090
+4885,5,107000110
+4886,1,105000000
+4887,2,105000001
+4888,3,105000002
+4889,4,105000003
+4890,5,105000004
+4891,1,120000000
+4892,2,120000001
+4893,3,120000002
+4894,4,120000003
+4895,5,120000004
+4896,3,180004
+4897,4,180005
+4899,3,106000060
+4900,3,106000070
+4901,3,106000080
+4902,3,101000070
+4903,3,110000060
+4904,4,106000100
+4905,4,106000110
+4906,4,104000090
+4907,5,106000120
+4908,1,103000000
+4909,2,103000001
+4910,3,103000002
+4911,4,103000003
+4912,5,103000004
+4913,1,112000000
+4914,2,112000001
+4915,3,112000002
+4916,4,112000003
+4917,5,112000004
+4918,3,170004
+4919,4,170005
+4921,3,112000020
+4922,3,112000030
+4923,4,112000040
+4924,5,112000060
+4925,1,101000000
+4926,2,101000001
+4927,3,101000002
+4928,4,101000008
+4929,5,101000004
+4930,1,112000000
+4931,2,112000001
+4932,3,112000002
+4933,4,112000003
+4934,5,112000004
+4935,3,170004
+4936,4,170005
+4938,3,104000170
+4939,4,104000180
+4940,5,104000190
+4941,1,115000000
+4942,2,115000001
+4943,3,115000002
+4944,4,115000003
+4945,5,115000004
+4946,1,120000000
+4947,2,120000001
+4948,3,120000002
+4949,4,120000003
+4950,5,120000004
+4951,4,120024
+4952,4,120034
+4953,4,120044
+4954,4,120054
+4955,3,120241
+4956,3,120251
+4957,3,120261
+4958,3,120271
+4959,3,120300
+4960,3,120310
+4961,3,120320
+4962,3,120330
+4963,3,120340
+4964,3,120350
+4965,3,120360
+4966,3,120370
+4967,3,120380
+4968,3,120390
+4969,3,120400
+4970,3,120410
+4971,3,120420
+4972,3,120430
+4973,3,120450
+4974,3,120460
+4975,3,120550
+4976,3,120560
+4977,3,120570
+4978,3,120990
+4979,3,121000
+4980,3,121010
+4981,3,121020
+4982,4,140000
+4983,4,150010
+4984,4,150020
+4985,4,150030
+4986,4,150040
+4988,3,111000010
+4989,3,111000020
+4990,3,111000030
+4991,4,111000040
+4992,5,111000060
+4993,1,101000000
+4994,2,101000001
+4995,3,101000002
+4996,4,101000008
+4997,5,101000004
+4998,1,120000000
+4999,2,120000001
+5000,3,120000002
+5001,4,120000003
+5002,5,120000004
+5003,4,110024
+5004,4,110034
+5005,4,110044
+5006,4,110054
+5007,3,110060
+5008,3,110070
+5009,3,110080
+5010,3,110090
+5011,3,110100
+5012,3,110110
+5013,3,110120
+5014,3,110130
+5015,3,110140
+5016,3,110150
+5017,3,110160
+5018,3,110170
+5019,3,110180
+5020,3,110190
+5021,3,110200
+5022,3,110210
+5023,3,110220
+5024,3,110230
+5025,3,110240
+5026,3,110250
+5027,3,110260
+5028,3,110270
+5029,3,110620
+5030,3,110670
+5031,4,140000
+5032,4,150010
+5033,4,150020
+5034,4,150030
+5035,4,150040
+5037,3,108000060
+5038,3,108000070
+5039,3,108000080
+5040,3,107000050
+5041,3,112000010
+5042,4,108000100
+5043,4,105000090
+5044,5,108000110
+5045,1,108000000
+5046,2,108000001
+5047,3,108000002
+5048,4,108000003
+5049,5,108000004
+5050,1,120000000
+5051,2,120000001
+5052,3,120000002
+5053,4,120000003
+5054,5,120000004
+5055,4,130024
+5056,4,130034
+5057,4,130044
+5058,4,130054
+5059,3,130060
+5060,3,130070
+5061,3,130080
+5062,3,130090
+5063,3,130100
+5064,3,130110
+5065,3,130120
+5066,3,130130
+5067,3,130140
+5068,3,130150
+5069,3,130160
+5070,3,130170
+5071,3,130180
+5072,3,130190
+5073,3,130200
+5074,3,130420
+5075,3,130510
+5076,3,130520
+5077,3,130530
+5078,3,130540
+5079,3,130660
+5080,4,140000
+5081,4,150010
+5082,4,150020
+5083,4,150030
+5084,4,150040
+5086,3,111000010
+5087,3,111000020
+5088,3,111000030
+5089,4,111000040
+5090,5,111000060
+5091,1,170002
+5092,2,170003
+5093,3,170004
+5094,1,180002
+5095,2,180003
+5096,3,180004
+5097,1,201000010
+5098,1,292000010
+5099,1,299000040
+5100,1,299000070
+5101,1,299000110
+5102,1,299000120
+5103,1,299000140
+5104,2,202000010
+5105,2,290000010
+5106,2,299000010
+5107,2,299000150
+5108,2,299000190
+5109,2,299000200
+5110,2,299000210
+5111,3,298000050
+5112,3,298000060
+5113,3,299000060
+5114,3,299000170
+5115,4,140000
+5116,5,150010
+5117,5,150020
+5118,5,150030
+5119,5,150040
+5121,3,111000010
+5122,3,111000020
+5123,3,111000030
+5124,4,111000040
+5125,5,111000060
+5126,2,170003
+5127,3,170004
+5128,2,180003
+5129,3,180004
+5130,1,201000010
+5131,1,292000010
+5132,1,299000040
+5133,1,299000070
+5134,1,299000110
+5135,1,299000120
+5136,1,299000140
+5137,2,202000010
+5138,2,290000010
+5139,2,299000010
+5140,2,299000150
+5141,2,299000190
+5142,2,299000200
+5143,2,299000210
+5144,3,298000050
+5145,3,298000060
+5146,3,299000060
+5147,3,299000170
+5148,4,140000
+5149,5,150010
+5150,5,150020
+5151,5,150030
+5152,5,150040
+5154,3,111000010
+5155,3,111000020
+5156,3,111000030
+5157,4,111000040
+5158,5,111000060
+5159,3,170004
+5160,3,180004
+5161,1,201000010
+5162,1,292000010
+5163,1,299000040
+5164,1,299000070
+5165,1,299000110
+5166,1,299000120
+5167,1,299000140
+5168,2,202000010
+5169,2,290000010
+5170,2,299000010
+5171,2,299000150
+5172,2,299000190
+5173,2,299000200
+5174,2,299000210
+5175,3,298000050
+5176,3,298000060
+5177,3,299000060
+5178,3,299000170
+5179,4,140000
+5180,5,150010
+5181,5,150020
+5182,5,150030
+5183,5,150040
+5185,3,111000010
+5186,3,111000020
+5187,3,111000030
+5188,4,111000040
+5189,5,111000060
+5190,3,170004
+5191,3,180004
+5192,1,201000010
+5193,1,292000010
+5194,1,299000040
+5195,1,299000070
+5196,1,299000110
+5197,1,299000120
+5198,1,299000140
+5199,2,202000010
+5200,2,290000010
+5201,2,299000010
+5202,2,299000150
+5203,2,299000190
+5204,2,299000200
+5205,2,299000210
+5206,3,298000050
+5207,3,298000060
+5208,3,299000060
+5209,3,299000170
+5210,4,140000
+5211,5,150010
+5212,5,150020
+5213,5,150030
+5214,5,150040
+5216,3,111000010
+5217,3,111000020
+5218,3,111000030
+5219,4,111000040
+5220,5,111000060
+5221,3,170004
+5222,3,180004
+5223,1,201000010
+5224,1,292000010
+5225,1,299000040
+5226,1,299000070
+5227,1,299000110
+5228,1,299000120
+5229,1,299000140
+5230,2,202000010
+5231,2,290000010
+5232,2,299000010
+5233,2,299000150
+5234,2,299000190
+5235,2,299000200
+5236,2,299000210
+5237,3,298000050
+5238,3,298000060
+5239,3,299000060
+5240,3,299000170
+5241,4,140000
+5242,5,150010
+5243,5,150020
+5244,5,150030
+5245,5,150040
+5246,5,190000
+5247,5,200000
+5248,5,210000
+5250,3,101000050
+5251,3,101000060
+5252,3,101000080
+5253,3,101000040
+5254,3,109000060
+5255,3,109000070
+5256,3,109000080
+5257,3,105000060
+5258,3,105000070
+5259,3,105000080
+5260,3,104000050
+5261,3,106000050
+5262,4,101000090
+5263,4,101000100
+5264,4,101000110
+5265,4,109000100
+5266,4,105000100
+5267,4,105000110
+5268,4,108000090
+5269,4,110000090
+5270,5,101000120
+5271,5,109000110
+5272,5,105000120
+5273,1,101000000
+5274,2,101000001
+5275,3,101000002
+5276,4,101000008
+5277,5,101000004
+5278,1,109000000
+5279,2,109000001
+5280,3,109000002
+5281,4,109000003
+5282,5,109000004
+5283,3,170004
+5284,4,170005
+5285,3,180004
+5286,4,180005
+5287,4,140000
+5288,4,150010
+5289,4,150020
+5290,4,150030
+5291,4,150040
+5293,3,102000060
+5294,3,102000070
+5295,3,102000080
+5296,3,103000050
+5297,3,105000050
+5298,3,107000060
+5299,3,107000070
+5300,3,107000080
+5301,3,108000050
+5302,3,109000050
+5303,3,103000060
+5304,3,103000070
+5305,3,103000080
+5306,3,110000050
+5307,4,102000100
+5308,4,102000110
+5309,4,106000090
+5310,4,109000090
+5311,4,107000100
+5312,4,103000090
+5313,4,102000090
+5314,4,103000100
+5315,5,102000120
+5316,5,107000110
+5317,5,103000120
+5318,1,102000000
+5319,2,102000001
+5320,3,102000002
+5321,4,102000003
+5322,5,102000004
+5323,1,105000000
+5324,2,105000001
+5325,3,105000002
+5326,4,105000003
+5327,5,105000004
+5328,1,112000000
+5329,2,112000001
+5330,3,112000002
+5331,4,112000003
+5332,5,112000004
+5333,4,110024
+5334,4,110034
+5335,4,110044
+5336,4,110054
+5337,3,110060
+5338,3,110070
+5339,3,110080
+5340,3,110090
+5341,3,110100
+5342,3,110110
+5343,3,110120
+5344,3,110130
+5345,3,110140
+5346,3,110150
+5347,3,110160
+5348,3,110170
+5349,3,110180
+5350,3,110190
+5351,3,110200
+5352,3,110210
+5353,3,110220
+5354,3,110230
+5355,3,110240
+5356,3,110250
+5357,3,110260
+5358,3,110270
+5359,3,110620
+5360,3,110670
+5361,4,140000
+5362,4,150010
+5363,4,150020
+5364,4,150030
+5365,4,150040
+5367,3,106000060
+5368,3,106000070
+5369,3,106000080
+5370,3,101000070
+5371,3,110000060
+5372,3,104000060
+5373,3,104000070
+5374,3,104000080
+5375,3,102000050
+5376,3,104000170
+5377,3,104000260
+5378,4,106000100
+5379,4,106000110
+5380,4,104000090
+5381,4,104000100
+5382,4,104000110
+5383,4,107000090
+5384,4,104000180
+5385,4,104000270
+5386,5,106000120
+5387,5,104000120
+5388,5,104000190
+5389,1,103000000
+5390,2,103000001
+5391,3,103000002
+5392,4,103000003
+5393,5,103000004
+5394,1,111000000
+5395,2,111000001
+5396,3,111000002
+5397,4,111000003
+5398,5,111000004
+5399,1,115000000
+5400,2,115000001
+5401,3,115000002
+5402,4,115000003
+5403,5,115000004
+5404,4,120024
+5405,4,120034
+5406,4,120044
+5407,4,120054
+5408,3,120241
+5409,3,120251
+5410,3,120261
+5411,3,120271
+5412,3,120300
+5413,3,120310
+5414,3,120320
+5415,3,120330
+5416,3,120340
+5417,3,120350
+5418,3,120360
+5419,3,120370
+5420,3,120380
+5421,3,120390
+5422,3,120400
+5423,3,120410
+5424,3,120420
+5425,3,120430
+5426,3,120450
+5427,3,120460
+5428,3,120550
+5429,3,120560
+5430,3,120570
+5431,3,120990
+5432,3,121000
+5433,3,121010
+5434,3,121020
+5435,4,140000
+5436,4,150010
+5437,4,150020
+5438,4,150030
+5439,4,150040
+5441,3,111000010
+5442,3,111000020
+5443,3,111000030
+5444,3,112000020
+5445,3,112000030
+5446,3,108000060
+5447,3,108000070
+5448,3,108000080
+5449,3,107000050
+5450,3,112000010
+5451,3,110000070
+5452,3,110000080
+5453,4,111000040
+5454,4,112000040
+5455,4,108000100
+5456,4,105000090
+5457,4,110000100
+5458,5,111000060
+5459,5,112000060
+5460,5,108000110
+5461,5,110000110
+5462,1,108000000
+5463,2,108000001
+5464,3,108000002
+5465,4,108000003
+5466,5,108000004
+5467,1,107000000
+5468,2,107000001
+5469,3,107000002
+5470,4,107000003
+5471,5,107000004
+5472,1,120000000
+5473,2,120000001
+5474,3,120000002
+5475,4,120000003
+5476,5,120000004
+5477,4,130024
+5478,4,130034
+5479,4,130044
+5480,4,130054
+5481,3,130060
+5482,3,130070
+5483,3,130080
+5484,3,130090
+5485,3,130100
+5486,3,130110
+5487,3,130120
+5488,3,130130
+5489,3,130140
+5490,3,130150
+5491,3,130160
+5492,3,130170
+5493,3,130180
+5494,3,130190
+5495,3,130200
+5496,3,130420
+5497,3,130510
+5498,3,130520
+5499,3,130530
+5500,3,130540
+5501,3,130660
+5502,4,140000
+5503,4,150010
+5504,4,150020
+5505,4,150030
+5506,4,150040
+5508,1,101000000
+5509,2,101000001
+5510,3,101000002
+5511,4,101000008
+5512,5,101000004
+5513,1,120000000
+5514,2,120000001
+5515,3,120000002
+5516,4,120000003
+5517,5,120000004
+5519,1,101000010
+5520,1,102000010
+5521,1,103000010
+5522,1,104000010
+5523,1,105000010
+5524,1,106000010
+5525,1,107000010
+5526,1,108000010
+5527,1,109000010
+5528,1,110000010
+5529,2,101000020
+5530,2,101000030
+5531,2,102000020
+5532,2,102000030
+5533,2,102000040
+5534,2,103000020
+5535,2,103000030
+5536,2,103000040
+5537,2,104000020
+5538,2,104000030
+5539,2,104000040
+5540,2,105000020
+5541,2,105000030
+5542,2,105000040
+5543,2,106000020
+5544,2,106000030
+5545,2,106000040
+5546,2,107000020
+5547,2,107000030
+5548,2,107000040
+5549,2,108000020
+5550,2,108000030
+5551,2,108000040
+5552,2,109000020
+5553,2,109000030
+5554,2,109000040
+5555,2,110000020
+5556,2,110000030
+5557,2,110000040
+5558,3,101000050
+5559,3,101000060
+5560,3,101000080
+5561,3,101000040
+5562,3,109000060
+5563,3,109000070
+5564,3,109000080
+5565,3,105000060
+5566,3,105000070
+5567,3,105000080
+5568,3,104000050
+5569,3,106000050
+5570,3,102000060
+5571,3,102000070
+5572,3,102000080
+5573,3,103000050
+5574,3,105000050
+5575,3,107000060
+5576,3,107000070
+5577,3,107000080
+5578,3,108000050
+5579,3,109000050
+5580,3,103000060
+5581,3,103000070
+5582,3,103000080
+5583,3,110000050
+5584,3,106000060
+5585,3,106000070
+5586,3,106000080
+5587,3,101000070
+5588,3,110000060
+5589,3,104000060
+5590,3,104000070
+5591,3,104000080
+5592,3,102000050
+5593,3,104000170
+5594,3,104000260
+5595,3,111000010
+5596,3,111000020
+5597,3,111000030
+5598,3,112000020
+5599,3,112000030
+5600,3,108000060
+5601,3,108000070
+5602,3,108000080
+5603,3,107000050
+5604,3,112000010
+5605,3,110000070
+5606,3,110000080
+5607,4,101000090
+5608,4,101000100
+5609,4,101000110
+5610,4,109000100
+5611,4,105000100
+5612,4,105000110
+5613,4,108000090
+5614,4,110000090
+5615,4,102000100
+5616,4,102000110
+5617,4,106000090
+5618,4,109000090
+5619,4,107000100
+5620,4,103000090
+5621,4,102000090
+5622,4,103000100
+5623,4,106000100
+5624,4,106000110
+5625,4,104000090
+5626,4,104000100
+5627,4,104000110
+5628,4,107000090
+5629,4,104000180
+5630,4,111000040
+5631,4,112000040
+5632,4,108000100
+5633,4,105000090
+5634,4,110000100
+5635,5,101000120
+5636,5,109000110
+5637,5,105000120
+5638,5,102000120
+5639,5,107000110
+5640,5,103000120
+5641,5,106000120
+5642,5,104000120
+5643,5,104000190
+5644,5,111000060
+5645,5,112000060
+5646,5,108000110
+5647,5,110000110
+5648,1,170002
+5649,2,170003
+5650,3,170004
+5651,1,180002
+5652,2,180003
+5653,3,180004
+5654,1,201000010
+5655,1,292000010
+5656,1,299000040
+5657,1,299000070
+5658,1,299000110
+5659,1,299000120
+5660,1,299000140
+5661,2,202000010
+5662,2,290000010
+5663,2,299000010
+5664,2,299000150
+5665,2,299000190
+5666,2,299000200
+5667,2,299000210
+5668,3,298000050
+5669,3,298000060
+5670,3,299000060
+5671,3,299000170
+5672,5,297000100
+5673,5,291000020
+5674,4,140000
+5675,5,150010
+5676,5,150020
+5677,5,150030
+5678,5,150040
+5680,1,101000010
+5681,1,102000010
+5682,1,103000010
+5683,1,104000010
+5684,1,105000010
+5685,1,106000010
+5686,1,107000010
+5687,1,108000010
+5688,1,109000010
+5689,1,110000010
+5690,2,101000020
+5691,2,101000030
+5692,2,102000020
+5693,2,102000030
+5694,2,102000040
+5695,2,103000020
+5696,2,103000030
+5697,2,103000040
+5698,2,104000020
+5699,2,104000030
+5700,2,104000040
+5701,2,105000020
+5702,2,105000030
+5703,2,105000040
+5704,2,106000020
+5705,2,106000030
+5706,2,106000040
+5707,2,107000020
+5708,2,107000030
+5709,2,107000040
+5710,2,108000020
+5711,2,108000030
+5712,2,108000040
+5713,2,109000020
+5714,2,109000030
+5715,2,109000040
+5716,2,110000020
+5717,2,110000030
+5718,2,110000040
+5719,3,101000050
+5720,3,101000060
+5721,3,101000080
+5722,3,101000040
+5723,3,109000060
+5724,3,109000070
+5725,3,109000080
+5726,3,105000060
+5727,3,105000070
+5728,3,105000080
+5729,3,104000050
+5730,3,106000050
+5731,3,102000060
+5732,3,102000070
+5733,3,102000080
+5734,3,103000050
+5735,3,105000050
+5736,3,107000060
+5737,3,107000070
+5738,3,107000080
+5739,3,108000050
+5740,3,109000050
+5741,3,103000060
+5742,3,103000070
+5743,3,103000080
+5744,3,110000050
+5745,3,106000060
+5746,3,106000070
+5747,3,106000080
+5748,3,101000070
+5749,3,110000060
+5750,3,104000060
+5751,3,104000070
+5752,3,104000080
+5753,3,102000050
+5754,3,104000170
+5755,3,104000260
+5756,3,111000010
+5757,3,111000020
+5758,3,111000030
+5759,3,112000020
+5760,3,112000030
+5761,3,108000060
+5762,3,108000070
+5763,3,108000080
+5764,3,107000050
+5765,3,112000010
+5766,3,110000070
+5767,3,110000080
+5768,4,101000090
+5769,4,101000100
+5770,4,101000110
+5771,4,109000100
+5772,4,105000100
+5773,4,105000110
+5774,4,108000090
+5775,4,110000090
+5776,4,102000100
+5777,4,102000110
+5778,4,106000090
+5779,4,109000090
+5780,4,107000100
+5781,4,103000090
+5782,4,102000090
+5783,4,103000100
+5784,4,106000100
+5785,4,106000110
+5786,4,104000090
+5787,4,104000100
+5788,4,104000110
+5789,4,107000090
+5790,4,104000180
+5791,4,111000040
+5792,4,112000040
+5793,4,108000100
+5794,4,105000090
+5795,4,110000100
+5796,5,101000120
+5797,5,109000110
+5798,5,105000120
+5799,5,102000120
+5800,5,107000110
+5801,5,103000120
+5802,5,106000120
+5803,5,104000120
+5804,5,104000190
+5805,5,111000060
+5806,5,112000060
+5807,5,108000110
+5808,5,110000110
+5809,2,170003
+5810,3,170004
+5811,2,180003
+5812,3,180004
+5813,1,201000010
+5814,1,292000010
+5815,1,299000040
+5816,1,299000070
+5817,1,299000110
+5818,1,299000120
+5819,1,299000140
+5820,2,202000010
+5821,2,290000010
+5822,2,299000010
+5823,2,299000150
+5824,2,299000190
+5825,2,299000200
+5826,2,299000210
+5827,3,298000050
+5828,3,298000060
+5829,3,299000060
+5830,3,299000170
+5831,5,297000100
+5832,5,291000020
+5833,4,140000
+5834,5,150010
+5835,5,150020
+5836,5,150030
+5837,5,150040
+5839,3,101000050
+5840,3,101000060
+5841,3,101000080
+5842,3,101000040
+5843,3,109000060
+5844,3,109000070
+5845,3,109000080
+5846,3,105000060
+5847,3,105000070
+5848,3,105000080
+5849,3,104000050
+5850,3,106000050
+5851,3,102000060
+5852,3,102000070
+5853,3,102000080
+5854,3,103000050
+5855,3,105000050
+5856,3,107000060
+5857,3,107000070
+5858,3,107000080
+5859,3,108000050
+5860,3,109000050
+5861,3,103000060
+5862,3,103000070
+5863,3,103000080
+5864,3,110000050
+5865,3,106000060
+5866,3,106000070
+5867,3,106000080
+5868,3,101000070
+5869,3,110000060
+5870,3,104000060
+5871,3,104000070
+5872,3,104000080
+5873,3,102000050
+5874,3,104000170
+5875,3,104000260
+5876,3,111000010
+5877,3,111000020
+5878,3,111000030
+5879,3,112000020
+5880,3,112000030
+5881,3,108000060
+5882,3,108000070
+5883,3,108000080
+5884,3,107000050
+5885,3,112000010
+5886,3,110000070
+5887,3,110000080
+5888,4,101000090
+5889,4,101000100
+5890,4,101000110
+5891,4,109000100
+5892,4,105000100
+5893,4,105000110
+5894,4,108000090
+5895,4,110000090
+5896,4,102000100
+5897,4,102000110
+5898,4,106000090
+5899,4,109000090
+5900,4,107000100
+5901,4,103000090
+5902,4,102000090
+5903,4,103000100
+5904,4,106000100
+5905,4,106000110
+5906,4,104000090
+5907,4,104000100
+5908,4,104000110
+5909,4,107000090
+5910,4,104000180
+5911,4,111000040
+5912,4,112000040
+5913,4,108000100
+5914,4,105000090
+5915,4,110000100
+5916,5,101000120
+5917,5,109000110
+5918,5,105000120
+5919,5,102000120
+5920,5,107000110
+5921,5,103000120
+5922,5,106000120
+5923,5,104000120
+5924,5,104000190
+5925,5,111000060
+5926,5,112000060
+5927,5,108000110
+5928,5,110000110
+5929,3,170004
+5930,3,180004
+5931,1,201000010
+5932,1,292000010
+5933,1,299000040
+5934,1,299000070
+5935,1,299000110
+5936,1,299000120
+5937,1,299000140
+5938,2,202000010
+5939,2,290000010
+5940,2,299000010
+5941,2,299000150
+5942,2,299000190
+5943,2,299000200
+5944,2,299000210
+5945,3,298000050
+5946,3,298000060
+5947,3,299000060
+5948,3,299000170
+5949,5,297000100
+5950,5,291000020
+5951,4,140000
+5952,5,150010
+5953,5,150020
+5954,5,150030
+5955,5,150040
+5957,3,101000050
+5958,3,101000060
+5959,3,101000080
+5960,3,101000040
+5961,3,109000060
+5962,3,109000070
+5963,3,109000080
+5964,3,105000060
+5965,3,105000070
+5966,3,105000080
+5967,3,104000050
+5968,3,106000050
+5969,3,102000060
+5970,3,102000070
+5971,3,102000080
+5972,3,103000050
+5973,3,105000050
+5974,3,107000060
+5975,3,107000070
+5976,3,107000080
+5977,3,108000050
+5978,3,109000050
+5979,3,103000060
+5980,3,103000070
+5981,3,103000080
+5982,3,110000050
+5983,3,106000060
+5984,3,106000070
+5985,3,106000080
+5986,3,101000070
+5987,3,110000060
+5988,3,104000060
+5989,3,104000070
+5990,3,104000080
+5991,3,102000050
+5992,3,104000170
+5993,3,104000260
+5994,3,111000010
+5995,3,111000020
+5996,3,111000030
+5997,3,112000020
+5998,3,112000030
+5999,3,108000060
+6000,3,108000070
+6001,3,108000080
+6002,3,107000050
+6003,3,112000010
+6004,3,110000070
+6005,3,110000080
+6006,4,101000090
+6007,4,101000100
+6008,4,101000110
+6009,4,109000100
+6010,4,105000100
+6011,4,105000110
+6012,4,108000090
+6013,4,110000090
+6014,4,102000100
+6015,4,102000110
+6016,4,106000090
+6017,4,109000090
+6018,4,107000100
+6019,4,103000090
+6020,4,102000090
+6021,4,103000100
+6022,4,106000100
+6023,4,106000110
+6024,4,104000090
+6025,4,104000100
+6026,4,104000110
+6027,4,107000090
+6028,4,104000180
+6029,4,111000040
+6030,4,112000040
+6031,4,108000100
+6032,4,105000090
+6033,4,110000100
+6034,5,101000120
+6035,5,109000110
+6036,5,105000120
+6037,5,102000120
+6038,5,107000110
+6039,5,103000120
+6040,5,106000120
+6041,5,104000120
+6042,5,104000190
+6043,5,111000060
+6044,5,112000060
+6045,5,108000110
+6046,5,110000110
+6047,3,170004
+6048,3,180004
+6049,1,201000010
+6050,1,292000010
+6051,1,299000040
+6052,1,299000070
+6053,1,299000110
+6054,1,299000120
+6055,1,299000140
+6056,2,202000010
+6057,2,290000010
+6058,2,299000010
+6059,2,299000150
+6060,2,299000190
+6061,2,299000200
+6062,2,299000210
+6063,3,298000050
+6064,3,298000060
+6065,3,299000060
+6066,3,299000170
+6067,5,297000100
+6068,5,291000020
+6069,4,140000
+6070,5,150010
+6071,5,150020
+6072,5,150030
+6073,5,150040
+6075,3,101000050
+6076,3,101000060
+6077,3,101000080
+6078,3,101000040
+6079,3,109000060
+6080,3,109000070
+6081,3,109000080
+6082,3,105000060
+6083,3,105000070
+6084,3,105000080
+6085,3,104000050
+6086,3,106000050
+6087,3,102000060
+6088,3,102000070
+6089,3,102000080
+6090,3,103000050
+6091,3,105000050
+6092,3,107000060
+6093,3,107000070
+6094,3,107000080
+6095,3,108000050
+6096,3,109000050
+6097,3,103000060
+6098,3,103000070
+6099,3,103000080
+6100,3,110000050
+6101,3,106000060
+6102,3,106000070
+6103,3,106000080
+6104,3,101000070
+6105,3,110000060
+6106,3,104000060
+6107,3,104000070
+6108,3,104000080
+6109,3,102000050
+6110,3,104000170
+6111,3,104000260
+6112,3,111000010
+6113,3,111000020
+6114,3,111000030
+6115,3,112000020
+6116,3,112000030
+6117,3,108000060
+6118,3,108000070
+6119,3,108000080
+6120,3,107000050
+6121,3,112000010
+6122,3,110000070
+6123,3,110000080
+6124,4,101000090
+6125,4,101000100
+6126,4,101000110
+6127,4,109000100
+6128,4,105000100
+6129,4,105000110
+6130,4,108000090
+6131,4,110000090
+6132,4,102000100
+6133,4,102000110
+6134,4,106000090
+6135,4,109000090
+6136,4,107000100
+6137,4,103000090
+6138,4,102000090
+6139,4,103000100
+6140,4,106000100
+6141,4,106000110
+6142,4,104000090
+6143,4,104000100
+6144,4,104000110
+6145,4,107000090
+6146,4,104000180
+6147,4,111000040
+6148,4,112000040
+6149,4,108000100
+6150,4,105000090
+6151,4,110000100
+6152,5,101000120
+6153,5,109000110
+6154,5,105000120
+6155,5,102000120
+6156,5,107000110
+6157,5,103000120
+6158,5,106000120
+6159,5,104000120
+6160,5,104000190
+6161,5,111000060
+6162,5,112000060
+6163,5,108000110
+6164,5,110000110
+6165,3,170004
+6166,3,180004
+6167,1,201000010
+6168,1,292000010
+6169,1,299000040
+6170,1,299000070
+6171,1,299000110
+6172,1,299000120
+6173,1,299000140
+6174,2,202000010
+6175,2,290000010
+6176,2,299000010
+6177,2,299000150
+6178,2,299000190
+6179,2,299000200
+6180,2,299000210
+6181,3,298000050
+6182,3,298000060
+6183,3,299000060
+6184,3,299000170
+6185,5,297000100
+6186,5,291000020
+6187,4,140000
+6188,5,150010
+6189,5,150020
+6190,5,150030
+6191,5,150040
+6192,5,190000
+6193,5,200000
+6194,5,210000
+6196,3,111000010
+6197,3,111000020
+6198,3,111000030
+6199,3,112000020
+6200,3,112000030
+6201,3,108000060
+6202,3,108000070
+6203,3,108000080
+6204,3,107000050
+6205,3,112000010
+6206,3,110000070
+6207,3,110000080
+6208,4,111000040
+6209,4,112000040
+6210,4,108000100
+6211,4,105000090
+6212,4,110000100
+6213,5,111000060
+6214,5,112000060
+6215,5,108000110
+6216,5,110000110
+6217,1,108000000
+6218,2,108000001
+6219,3,108000002
+6220,4,108000003
+6221,5,108000004
+6222,1,107000000
+6223,2,107000001
+6224,3,107000002
+6225,4,107000003
+6226,5,107000004
+6227,1,120000000
+6228,2,120000001
+6229,3,120000002
+6230,4,120000003
+6231,5,120000004
+6232,3,170004
+6233,4,170005
+6234,3,180004
+6235,4,180005
+6236,4,140000
+6237,4,150010
+6238,4,150020
+6239,4,150030
+6240,4,150040
+6242,3,101000050
+6243,3,101000060
+6244,3,101000080
+6245,3,101000040
+6246,3,109000060
+6247,3,109000070
+6248,3,109000080
+6249,3,105000060
+6250,3,105000070
+6251,3,105000080
+6252,3,104000050
+6253,3,106000050
+6254,4,101000090
+6255,4,101000100
+6256,4,101000110
+6257,4,109000100
+6258,4,105000100
+6259,4,105000110
+6260,4,108000090
+6261,4,110000090
+6262,5,101000120
+6263,5,109000110
+6264,5,105000120
+6265,1,101000000
+6266,2,101000001
+6267,3,101000002
+6268,4,101000008
+6269,5,101000004
+6270,1,109000000
+6271,2,109000001
+6272,3,109000002
+6273,4,109000003
+6274,5,109000004
+6275,4,110024
+6276,4,110034
+6277,4,110044
+6278,4,110054
+6279,3,110060
+6280,3,110070
+6281,3,110080
+6282,3,110090
+6283,3,110100
+6284,3,110110
+6285,3,110120
+6286,3,110130
+6287,3,110140
+6288,3,110150
+6289,3,110160
+6290,3,110170
+6291,3,110180
+6292,3,110190
+6293,3,110200
+6294,3,110210
+6295,3,110220
+6296,3,110230
+6297,3,110240
+6298,3,110250
+6299,3,110260
+6300,3,110270
+6301,3,110620
+6302,3,110670
+6303,4,140000
+6304,4,150010
+6305,4,150020
+6306,4,150030
+6307,4,150040
+6309,3,102000060
+6310,3,102000070
+6311,3,102000080
+6312,3,103000050
+6313,3,105000050
+6314,3,107000060
+6315,3,107000070
+6316,3,107000080
+6317,3,108000050
+6318,3,109000050
+6319,3,103000060
+6320,3,103000070
+6321,3,103000080
+6322,3,110000050
+6323,4,102000100
+6324,4,102000110
+6325,4,106000090
+6326,4,109000090
+6327,4,107000100
+6328,4,103000090
+6329,4,102000090
+6330,4,103000100
+6331,5,102000120
+6332,5,107000110
+6333,5,103000120
+6334,1,102000000
+6335,2,102000001
+6336,3,102000002
+6337,4,102000003
+6338,5,102000004
+6339,1,105000000
+6340,2,105000001
+6341,3,105000002
+6342,4,105000003
+6343,5,105000004
+6344,1,112000000
+6345,2,112000001
+6346,3,112000002
+6347,4,112000003
+6348,5,112000004
+6349,4,120024
+6350,4,120034
+6351,4,120044
+6352,4,120054
+6353,3,120241
+6354,3,120251
+6355,3,120261
+6356,3,120271
+6357,3,120300
+6358,3,120310
+6359,3,120320
+6360,3,120330
+6361,3,120340
+6362,3,120350
+6363,3,120360
+6364,3,120370
+6365,3,120380
+6366,3,120390
+6367,3,120400
+6368,3,120410
+6369,3,120420
+6370,3,120430
+6371,3,120450
+6372,3,120460
+6373,3,120550
+6374,3,120560
+6375,3,120570
+6376,3,120990
+6377,3,121000
+6378,3,121010
+6379,3,121020
+6380,4,140000
+6381,4,150010
+6382,4,150020
+6383,4,150030
+6384,4,150040
+6386,3,106000060
+6387,3,106000070
+6388,3,106000080
+6389,3,101000070
+6390,3,110000060
+6391,3,104000060
+6392,3,104000070
+6393,3,104000080
+6394,3,102000050
+6395,3,104000170
+6396,3,104000260
+6397,4,106000100
+6398,4,106000110
+6399,4,104000090
+6400,4,104000100
+6401,4,104000110
+6402,4,107000090
+6403,4,104000180
+6404,5,106000120
+6405,5,104000120
+6406,5,104000190
+6407,1,103000000
+6408,2,103000001
+6409,3,103000002
+6410,4,103000003
+6411,5,103000004
+6412,1,111000000
+6413,2,111000001
+6414,3,111000002
+6415,4,111000003
+6416,5,111000004
+6417,1,115000000
+6418,2,115000001
+6419,3,115000002
+6420,4,115000003
+6421,5,115000004
+6422,4,130024
+6423,4,130034
+6424,4,130044
+6425,4,130054
+6426,3,130060
+6427,3,130070
+6428,3,130080
+6429,3,130090
+6430,3,130100
+6431,3,130110
+6432,3,130120
+6433,3,130130
+6434,3,130140
+6435,3,130150
+6436,3,130160
+6437,3,130170
+6438,3,130180
+6439,3,130190
+6440,3,130200
+6441,3,130420
+6442,3,130510
+6443,3,130520
+6444,3,130530
+6445,3,130540
+6446,3,130660
+6447,3,130790
+6448,3,130800
+6449,4,140000
+6450,4,150010
+6451,4,150020
+6452,4,150030
+6453,4,150040
+6455,1,101000010
+6456,1,102000010
+6457,1,103000010
+6458,1,104000010
+6459,1,105000010
+6460,1,106000010
+6461,1,107000010
+6462,1,108000010
+6463,1,109000010
+6464,1,110000010
+6465,2,101000020
+6466,2,101000030
+6467,2,102000020
+6468,2,102000030
+6469,2,102000040
+6470,2,103000020
+6471,2,103000030
+6472,2,103000040
+6473,2,104000020
+6474,2,104000030
+6475,2,104000040
+6476,2,105000020
+6477,2,105000030
+6478,2,105000040
+6479,2,106000020
+6480,2,106000030
+6481,2,106000040
+6482,2,107000020
+6483,2,107000030
+6484,2,107000040
+6485,2,108000020
+6486,2,108000030
+6487,2,108000040
+6488,2,109000020
+6489,2,109000030
+6490,2,109000040
+6491,2,110000020
+6492,2,110000030
+6493,2,110000040
+6494,2,118000010
+6495,3,101000050
+6496,3,101000060
+6497,3,101000080
+6498,3,101000040
+6499,3,109000060
+6500,3,109000070
+6501,3,109000080
+6502,3,105000060
+6503,3,105000070
+6504,3,105000080
+6505,3,104000050
+6506,3,106000050
+6507,3,102000060
+6508,3,102000070
+6509,3,102000080
+6510,3,103000050
+6511,3,105000050
+6512,3,107000060
+6513,3,107000070
+6514,3,107000080
+6515,3,108000050
+6516,3,109000050
+6517,3,103000060
+6518,3,103000070
+6519,3,103000080
+6520,3,110000050
+6521,3,106000060
+6522,3,106000070
+6523,3,106000080
+6524,3,101000070
+6525,3,110000060
+6526,3,104000060
+6527,3,104000070
+6528,3,104000080
+6529,3,102000050
+6530,3,104000170
+6531,3,104000260
+6532,3,111000010
+6533,3,111000020
+6534,3,111000030
+6535,3,112000020
+6536,3,112000030
+6537,3,108000060
+6538,3,108000070
+6539,3,108000080
+6540,3,107000050
+6541,3,112000010
+6542,3,110000070
+6543,3,110000080
+6544,3,118000020
+6545,3,118000030
+6546,3,118000040
+6547,4,101000090
+6548,4,101000100
+6549,4,101000110
+6550,4,109000100
+6551,4,105000100
+6552,4,105000110
+6553,4,108000090
+6554,4,110000090
+6555,4,102000100
+6556,4,102000110
+6557,4,106000090
+6558,4,109000090
+6559,4,107000100
+6560,4,103000090
+6561,4,102000090
+6562,4,103000100
+6563,4,106000100
+6564,4,106000110
+6565,4,104000090
+6566,4,104000100
+6567,4,104000110
+6568,4,107000090
+6569,4,104000180
+6570,4,111000040
+6571,4,112000040
+6572,4,108000100
+6573,4,105000090
+6574,4,110000100
+6575,4,118000050
+6576,4,118000060
+6577,5,101000120
+6578,5,109000110
+6579,5,105000120
+6580,5,102000120
+6581,5,107000110
+6582,5,103000120
+6583,5,106000120
+6584,5,104000120
+6585,5,104000190
+6586,5,111000060
+6587,5,112000060
+6588,5,108000110
+6589,5,110000110
+6590,5,118000070
+6591,1,170002
+6592,2,170003
+6593,3,170004
+6594,1,180002
+6595,2,180003
+6596,3,180004
+6597,1,201000010
+6598,1,292000010
+6599,1,299000040
+6600,1,299000070
+6601,1,299000110
+6602,1,299000120
+6603,1,299000140
+6604,2,202000010
+6605,2,290000010
+6606,2,299000010
+6607,2,299000150
+6608,2,299000190
+6609,2,299000200
+6610,2,299000210
+6611,3,298000050
+6612,3,298000060
+6613,3,299000060
+6614,3,299000170
+6615,5,297000100
+6616,5,291000020
+6617,4,140000
+6618,5,150010
+6619,5,150020
+6620,5,150030
+6621,5,150040
+6623,1,101000010
+6624,1,102000010
+6625,1,103000010
+6626,1,104000010
+6627,1,105000010
+6628,1,106000010
+6629,1,107000010
+6630,1,108000010
+6631,1,109000010
+6632,1,110000010
+6633,2,101000020
+6634,2,101000030
+6635,2,102000020
+6636,2,102000030
+6637,2,102000040
+6638,2,103000020
+6639,2,103000030
+6640,2,103000040
+6641,2,104000020
+6642,2,104000030
+6643,2,104000040
+6644,2,105000020
+6645,2,105000030
+6646,2,105000040
+6647,2,106000020
+6648,2,106000030
+6649,2,106000040
+6650,2,107000020
+6651,2,107000030
+6652,2,107000040
+6653,2,108000020
+6654,2,108000030
+6655,2,108000040
+6656,2,109000020
+6657,2,109000030
+6658,2,109000040
+6659,2,110000020
+6660,2,110000030
+6661,2,110000040
+6662,2,118000010
+6663,3,101000050
+6664,3,101000060
+6665,3,101000080
+6666,3,101000040
+6667,3,109000060
+6668,3,109000070
+6669,3,109000080
+6670,3,105000060
+6671,3,105000070
+6672,3,105000080
+6673,3,104000050
+6674,3,106000050
+6675,3,102000060
+6676,3,102000070
+6677,3,102000080
+6678,3,103000050
+6679,3,105000050
+6680,3,107000060
+6681,3,107000070
+6682,3,107000080
+6683,3,108000050
+6684,3,109000050
+6685,3,103000060
+6686,3,103000070
+6687,3,103000080
+6688,3,110000050
+6689,3,106000060
+6690,3,106000070
+6691,3,106000080
+6692,3,101000070
+6693,3,110000060
+6694,3,104000060
+6695,3,104000070
+6696,3,104000080
+6697,3,102000050
+6698,3,104000170
+6699,3,104000260
+6700,3,111000010
+6701,3,111000020
+6702,3,111000030
+6703,3,112000020
+6704,3,112000030
+6705,3,108000060
+6706,3,108000070
+6707,3,108000080
+6708,3,107000050
+6709,3,112000010
+6710,3,110000070
+6711,3,110000080
+6712,3,118000020
+6713,3,118000030
+6714,3,118000040
+6715,4,101000090
+6716,4,101000100
+6717,4,101000110
+6718,4,109000100
+6719,4,105000100
+6720,4,105000110
+6721,4,108000090
+6722,4,110000090
+6723,4,102000100
+6724,4,102000110
+6725,4,106000090
+6726,4,109000090
+6727,4,107000100
+6728,4,103000090
+6729,4,102000090
+6730,4,103000100
+6731,4,106000100
+6732,4,106000110
+6733,4,104000090
+6734,4,104000100
+6735,4,104000110
+6736,4,107000090
+6737,4,104000180
+6738,4,111000040
+6739,4,112000040
+6740,4,108000100
+6741,4,105000090
+6742,4,110000100
+6743,4,118000050
+6744,4,118000060
+6745,5,101000120
+6746,5,109000110
+6747,5,105000120
+6748,5,102000120
+6749,5,107000110
+6750,5,103000120
+6751,5,106000120
+6752,5,104000120
+6753,5,104000190
+6754,5,111000060
+6755,5,112000060
+6756,5,108000110
+6757,5,110000110
+6758,5,118000070
+6759,2,170003
+6760,3,170004
+6761,2,180003
+6762,3,180004
+6763,1,201000010
+6764,1,292000010
+6765,1,299000040
+6766,1,299000070
+6767,1,299000110
+6768,1,299000120
+6769,1,299000140
+6770,2,202000010
+6771,2,290000010
+6772,2,299000010
+6773,2,299000150
+6774,2,299000190
+6775,2,299000200
+6776,2,299000210
+6777,3,298000050
+6778,3,298000060
+6779,3,299000060
+6780,3,299000170
+6781,5,297000100
+6782,5,291000020
+6783,4,140000
+6784,5,150010
+6785,5,150020
+6786,5,150030
+6787,5,150040
+6789,3,101000050
+6790,3,101000060
+6791,3,101000080
+6792,3,101000040
+6793,3,109000060
+6794,3,109000070
+6795,3,109000080
+6796,3,105000060
+6797,3,105000070
+6798,3,105000080
+6799,3,104000050
+6800,3,106000050
+6801,3,102000060
+6802,3,102000070
+6803,3,102000080
+6804,3,103000050
+6805,3,105000050
+6806,3,107000060
+6807,3,107000070
+6808,3,107000080
+6809,3,108000050
+6810,3,109000050
+6811,3,103000060
+6812,3,103000070
+6813,3,103000080
+6814,3,110000050
+6815,3,106000060
+6816,3,106000070
+6817,3,106000080
+6818,3,101000070
+6819,3,110000060
+6820,3,104000060
+6821,3,104000070
+6822,3,104000080
+6823,3,102000050
+6824,3,104000170
+6825,3,104000260
+6826,3,111000010
+6827,3,111000020
+6828,3,111000030
+6829,3,112000020
+6830,3,112000030
+6831,3,108000060
+6832,3,108000070
+6833,3,108000080
+6834,3,107000050
+6835,3,112000010
+6836,3,110000070
+6837,3,110000080
+6838,3,118000020
+6839,3,118000030
+6840,3,118000040
+6841,4,101000090
+6842,4,101000100
+6843,4,101000110
+6844,4,109000100
+6845,4,105000100
+6846,4,105000110
+6847,4,108000090
+6848,4,110000090
+6849,4,102000100
+6850,4,102000110
+6851,4,106000090
+6852,4,109000090
+6853,4,107000100
+6854,4,103000090
+6855,4,102000090
+6856,4,103000100
+6857,4,106000100
+6858,4,106000110
+6859,4,104000090
+6860,4,104000100
+6861,4,104000110
+6862,4,107000090
+6863,4,104000180
+6864,4,111000040
+6865,4,112000040
+6866,4,108000100
+6867,4,105000090
+6868,4,110000100
+6869,4,118000050
+6870,4,118000060
+6871,5,101000120
+6872,5,109000110
+6873,5,105000120
+6874,5,102000120
+6875,5,107000110
+6876,5,103000120
+6877,5,106000120
+6878,5,104000120
+6879,5,104000190
+6880,5,111000060
+6881,5,112000060
+6882,5,108000110
+6883,5,110000110
+6884,5,118000070
+6885,3,170004
+6886,3,180004
+6887,1,201000010
+6888,1,292000010
+6889,1,299000040
+6890,1,299000070
+6891,1,299000110
+6892,1,299000120
+6893,1,299000140
+6894,2,202000010
+6895,2,290000010
+6896,2,299000010
+6897,2,299000150
+6898,2,299000190
+6899,2,299000200
+6900,2,299000210
+6901,3,298000050
+6902,3,298000060
+6903,3,299000060
+6904,3,299000170
+6905,5,297000100
+6906,5,291000020
+6907,4,140000
+6908,5,150010
+6909,5,150020
+6910,5,150030
+6911,5,150040
+6913,3,101000050
+6914,3,101000060
+6915,3,101000080
+6916,3,101000040
+6917,3,109000060
+6918,3,109000070
+6919,3,109000080
+6920,3,105000060
+6921,3,105000070
+6922,3,105000080
+6923,3,104000050
+6924,3,106000050
+6925,3,102000060
+6926,3,102000070
+6927,3,102000080
+6928,3,103000050
+6929,3,105000050
+6930,3,107000060
+6931,3,107000070
+6932,3,107000080
+6933,3,108000050
+6934,3,109000050
+6935,3,103000060
+6936,3,103000070
+6937,3,103000080
+6938,3,110000050
+6939,3,106000060
+6940,3,106000070
+6941,3,106000080
+6942,3,101000070
+6943,3,110000060
+6944,3,104000060
+6945,3,104000070
+6946,3,104000080
+6947,3,102000050
+6948,3,104000170
+6949,3,104000260
+6950,3,111000010
+6951,3,111000020
+6952,3,111000030
+6953,3,112000020
+6954,3,112000030
+6955,3,108000060
+6956,3,108000070
+6957,3,108000080
+6958,3,107000050
+6959,3,112000010
+6960,3,110000070
+6961,3,110000080
+6962,3,118000020
+6963,3,118000030
+6964,3,118000040
+6965,4,101000090
+6966,4,101000100
+6967,4,101000110
+6968,4,109000100
+6969,4,105000100
+6970,4,105000110
+6971,4,108000090
+6972,4,110000090
+6973,4,102000100
+6974,4,102000110
+6975,4,106000090
+6976,4,109000090
+6977,4,107000100
+6978,4,103000090
+6979,4,102000090
+6980,4,103000100
+6981,4,106000100
+6982,4,106000110
+6983,4,104000090
+6984,4,104000100
+6985,4,104000110
+6986,4,107000090
+6987,4,104000180
+6988,4,111000040
+6989,4,112000040
+6990,4,108000100
+6991,4,105000090
+6992,4,110000100
+6993,4,118000050
+6994,4,118000060
+6995,5,101000120
+6996,5,109000110
+6997,5,105000120
+6998,5,102000120
+6999,5,107000110
+7000,5,103000120
+7001,5,106000120
+7002,5,104000120
+7003,5,104000190
+7004,5,111000060
+7005,5,112000060
+7006,5,108000110
+7007,5,110000110
+7008,5,118000070
+7009,3,170004
+7010,3,180004
+7011,1,201000010
+7012,1,292000010
+7013,1,299000040
+7014,1,299000070
+7015,1,299000110
+7016,1,299000120
+7017,1,299000140
+7018,2,202000010
+7019,2,290000010
+7020,2,299000010
+7021,2,299000150
+7022,2,299000190
+7023,2,299000200
+7024,2,299000210
+7025,3,298000050
+7026,3,298000060
+7027,3,299000060
+7028,3,299000170
+7029,5,297000100
+7030,5,291000020
+7031,4,140000
+7032,5,150010
+7033,5,150020
+7034,5,150030
+7035,5,150040
+7037,3,101000050
+7038,3,101000060
+7039,3,101000080
+7040,3,101000040
+7041,3,109000060
+7042,3,109000070
+7043,3,109000080
+7044,3,105000060
+7045,3,105000070
+7046,3,105000080
+7047,3,104000050
+7048,3,106000050
+7049,3,102000060
+7050,3,102000070
+7051,3,102000080
+7052,3,103000050
+7053,3,105000050
+7054,3,107000060
+7055,3,107000070
+7056,3,107000080
+7057,3,108000050
+7058,3,109000050
+7059,3,103000060
+7060,3,103000070
+7061,3,103000080
+7062,3,110000050
+7063,3,106000060
+7064,3,106000070
+7065,3,106000080
+7066,3,101000070
+7067,3,110000060
+7068,3,104000060
+7069,3,104000070
+7070,3,104000080
+7071,3,102000050
+7072,3,104000170
+7073,3,104000260
+7074,3,111000010
+7075,3,111000020
+7076,3,111000030
+7077,3,112000020
+7078,3,112000030
+7079,3,108000060
+7080,3,108000070
+7081,3,108000080
+7082,3,107000050
+7083,3,112000010
+7084,3,110000070
+7085,3,110000080
+7086,3,118000020
+7087,3,118000030
+7088,3,118000040
+7089,4,101000090
+7090,4,101000100
+7091,4,101000110
+7092,4,109000100
+7093,4,105000100
+7094,4,105000110
+7095,4,108000090
+7096,4,110000090
+7097,4,102000100
+7098,4,102000110
+7099,4,106000090
+7100,4,109000090
+7101,4,107000100
+7102,4,103000090
+7103,4,102000090
+7104,4,103000100
+7105,4,106000100
+7106,4,106000110
+7107,4,104000090
+7108,4,104000100
+7109,4,104000110
+7110,4,107000090
+7111,4,104000180
+7112,4,111000040
+7113,4,112000040
+7114,4,108000100
+7115,4,105000090
+7116,4,110000100
+7117,4,118000050
+7118,4,118000060
+7119,5,101000120
+7120,5,109000110
+7121,5,105000120
+7122,5,102000120
+7123,5,107000110
+7124,5,103000120
+7125,5,106000120
+7126,5,104000120
+7127,5,104000190
+7128,5,111000060
+7129,5,112000060
+7130,5,108000110
+7131,5,110000110
+7132,5,118000070
+7133,3,170004
+7134,3,180004
+7135,1,201000010
+7136,1,292000010
+7137,1,299000040
+7138,1,299000070
+7139,1,299000110
+7140,1,299000120
+7141,1,299000140
+7142,2,202000010
+7143,2,290000010
+7144,2,299000010
+7145,2,299000150
+7146,2,299000190
+7147,2,299000200
+7148,2,299000210
+7149,3,298000050
+7150,3,298000060
+7151,3,299000060
+7152,3,299000170
+7153,5,297000100
+7154,5,291000020
+7155,4,140000
+7156,5,150010
+7157,5,150020
+7158,5,150030
+7159,5,150040
+7160,5,190000
+7161,5,200000
+7162,5,210000
+7164,3,118000020
+7165,3,118000030
+7166,3,118000040
+7167,3,106000060
+7168,3,106000070
+7169,3,106000080
+7170,3,101000070
+7171,3,110000060
+7172,3,104000060
+7173,3,104000070
+7174,3,104000080
+7175,3,102000050
+7176,3,104000170
+7177,3,104000260
+7178,4,118000050
+7179,4,118000060
+7180,4,106000100
+7181,4,106000110
+7182,4,104000090
+7183,4,104000100
+7184,4,104000110
+7185,4,104000270
+7186,4,107000090
+7187,4,104000180
+7188,5,118000070
+7189,5,106000120
+7190,5,104000120
+7191,5,104000190
+7192,1,103000000
+7193,2,103000001
+7194,3,103000002
+7195,4,103000003
+7196,5,103000004
+7197,1,111000000
+7198,2,111000001
+7199,3,111000002
+7200,4,111000003
+7201,5,111000004
+7202,1,115000000
+7203,2,115000001
+7204,3,115000002
+7205,4,115000003
+7206,5,115000004
+7207,3,170004
+7208,4,170005
+7209,3,180004
+7210,4,180005
+7211,4,140000
+7212,4,150010
+7213,4,150020
+7214,4,150030
+7215,4,150040
+7217,3,111000010
+7218,3,111000020
+7219,3,111000030
+7220,3,112000020
+7221,3,112000030
+7222,3,108000060
+7223,3,108000070
+7224,3,108000080
+7225,3,107000050
+7226,3,112000010
+7227,3,110000070
+7228,3,110000080
+7229,4,111000040
+7230,4,112000040
+7231,4,108000100
+7232,4,105000090
+7233,4,110000100
+7234,5,111000060
+7235,5,112000060
+7236,5,108000110
+7237,5,110000110
+7238,1,108000000
+7239,2,108000001
+7240,3,108000002
+7241,4,108000003
+7242,5,108000004
+7243,1,107000000
+7244,2,107000001
+7245,3,107000002
+7246,4,107000003
+7247,5,107000004
+7248,1,120000000
+7249,2,120000001
+7250,3,120000002
+7251,4,120000003
+7252,5,120000004
+7253,4,110024
+7254,4,110034
+7255,4,110044
+7256,4,110054
+7257,3,110060
+7258,3,110070
+7259,3,110080
+7260,3,110090
+7261,3,110100
+7262,3,110110
+7263,3,110120
+7264,3,110130
+7265,3,110140
+7266,3,110150
+7267,3,110160
+7268,3,110170
+7269,3,110180
+7270,3,110190
+7271,3,110200
+7272,3,110210
+7273,3,110220
+7274,3,110230
+7275,3,110240
+7276,3,110250
+7277,3,110260
+7278,3,110270
+7279,3,110620
+7280,3,110670
+7281,4,140000
+7282,4,150010
+7283,4,150020
+7284,4,150030
+7285,4,150040
+7287,3,101000050
+7288,3,101000060
+7289,3,101000080
+7290,3,101000040
+7291,3,109000060
+7292,3,109000070
+7293,3,109000080
+7294,3,105000060
+7295,3,105000070
+7296,3,105000080
+7297,3,104000050
+7298,3,106000050
+7299,4,101000090
+7300,4,101000100
+7301,4,101000110
+7302,4,109000100
+7303,4,105000100
+7304,4,105000110
+7305,4,108000090
+7306,4,110000090
+7307,5,101000120
+7308,5,109000110
+7309,5,105000120
+7310,1,101000000
+7311,2,101000001
+7312,3,101000002
+7313,4,101000008
+7314,5,101000004
+7315,1,109000000
+7316,2,109000001
+7317,3,109000002
+7318,4,109000003
+7319,5,109000004
+7320,4,120024
+7321,4,120034
+7322,4,120044
+7323,4,120054
+7324,3,120241
+7325,3,120251
+7326,3,120261
+7327,3,120271
+7328,3,120300
+7329,3,120310
+7330,3,120320
+7331,3,120330
+7332,3,120340
+7333,3,120350
+7334,3,120360
+7335,3,120370
+7336,3,120380
+7337,3,120390
+7338,3,120400
+7339,3,120410
+7340,3,120420
+7341,3,120430
+7342,3,120450
+7343,3,120460
+7344,3,120550
+7345,3,120560
+7346,3,120570
+7347,3,120990
+7348,3,121000
+7349,3,121010
+7350,3,121020
+7351,4,140000
+7352,4,150010
+7353,4,150020
+7354,4,150030
+7355,4,150040
+7357,3,102000060
+7358,3,102000070
+7359,3,102000080
+7360,3,103000050
+7361,3,105000050
+7362,3,107000060
+7363,3,107000070
+7364,3,107000080
+7365,3,108000050
+7366,3,109000050
+7367,3,103000060
+7368,3,103000070
+7369,3,103000080
+7370,3,110000050
+7371,4,102000100
+7372,4,102000110
+7373,4,106000090
+7374,4,109000090
+7375,4,107000100
+7376,4,103000090
+7377,4,102000090
+7378,4,103000100
+7379,5,102000120
+7380,5,107000110
+7381,5,103000120
+7382,1,102000000
+7383,2,102000001
+7384,3,102000002
+7385,4,102000003
+7386,5,102000004
+7387,1,105000000
+7388,2,105000001
+7389,3,105000002
+7390,4,105000003
+7391,5,105000004
+7392,1,112000000
+7393,2,112000001
+7394,3,112000002
+7395,4,112000003
+7396,5,112000004
+7397,4,130024
+7398,4,130034
+7399,4,130044
+7400,4,130054
+7401,3,130060
+7402,3,130070
+7403,3,130080
+7404,3,130090
+7405,3,130100
+7406,3,130110
+7407,3,130120
+7408,3,130130
+7409,3,130140
+7410,3,130150
+7411,3,130160
+7412,3,130170
+7413,3,130180
+7414,3,130190
+7415,3,130200
+7416,3,130420
+7417,3,130510
+7418,3,130520
+7419,3,130530
+7420,3,130540
+7421,3,130660
+7422,3,130790
+7423,3,130800
+7424,4,140000
+7425,4,150010
+7426,4,150020
+7427,4,150030
+7428,4,150040
+7430,1,101000010
+7431,1,102000010
+7432,1,103000010
+7433,1,104000010
+7434,1,105000010
+7435,1,106000010
+7436,1,107000010
+7437,1,108000010
+7438,1,109000010
+7439,1,110000010
+7440,2,101000020
+7441,2,101000030
+7442,2,102000020
+7443,2,102000030
+7444,2,102000040
+7445,2,103000020
+7446,2,103000030
+7447,2,103000040
+7448,2,104000020
+7449,2,104000030
+7450,2,104000040
+7451,2,105000020
+7452,2,105000030
+7453,2,105000040
+7454,2,106000020
+7455,2,106000030
+7456,2,106000040
+7457,2,107000020
+7458,2,107000030
+7459,2,107000040
+7460,2,108000020
+7461,2,108000030
+7462,2,108000040
+7463,2,109000020
+7464,2,109000030
+7465,2,109000040
+7466,2,110000020
+7467,2,110000030
+7468,2,110000040
+7469,2,118000010
+7470,3,101000050
+7471,3,101000060
+7472,3,101000080
+7473,3,101000040
+7474,3,109000060
+7475,3,109000070
+7476,3,109000080
+7477,3,105000060
+7478,3,105000070
+7479,3,105000080
+7480,3,104000050
+7481,3,106000050
+7482,3,102000060
+7483,3,102000070
+7484,3,102000080
+7485,3,103000050
+7486,3,105000050
+7487,3,107000060
+7488,3,107000070
+7489,3,107000080
+7490,3,108000050
+7491,3,109000050
+7492,3,103000060
+7493,3,103000070
+7494,3,103000080
+7495,3,110000050
+7496,3,106000060
+7497,3,106000070
+7498,3,106000080
+7499,3,101000070
+7500,3,110000060
+7501,3,104000060
+7502,3,104000070
+7503,3,104000080
+7504,3,102000050
+7505,3,104000170
+7506,3,104000260
+7507,3,111000010
+7508,3,111000020
+7509,3,111000030
+7510,3,112000020
+7511,3,112000030
+7512,3,108000060
+7513,3,108000070
+7514,3,108000080
+7515,3,107000050
+7516,3,112000010
+7517,3,110000070
+7518,3,110000080
+7519,3,118000020
+7520,3,118000030
+7521,3,118000040
+7522,4,101000090
+7523,4,101000100
+7524,4,101000110
+7525,4,109000100
+7526,4,105000100
+7527,4,105000110
+7528,4,108000090
+7529,4,110000090
+7530,4,102000100
+7531,4,102000110
+7532,4,106000090
+7533,4,109000090
+7534,4,107000100
+7535,4,103000090
+7536,4,102000090
+7537,4,103000100
+7538,4,106000100
+7539,4,106000110
+7540,4,104000090
+7541,4,104000100
+7542,4,104000110
+7543,4,107000090
+7544,4,104000180
+7545,4,111000040
+7546,4,112000040
+7547,4,108000100
+7548,4,105000090
+7549,4,110000100
+7550,4,118000050
+7551,4,118000060
+7552,5,101000120
+7553,5,109000110
+7554,5,105000120
+7555,5,102000120
+7556,5,107000110
+7557,5,103000120
+7558,5,106000120
+7559,5,104000120
+7560,5,104000190
+7561,5,111000060
+7562,5,112000060
+7563,5,108000110
+7564,5,110000110
+7565,5,118000070
+7566,1,170002
+7567,2,170003
+7568,3,170004
+7569,1,180002
+7570,2,180003
+7571,3,180004
+7572,1,201000010
+7573,1,292000010
+7574,1,299000040
+7575,1,299000070
+7576,1,299000110
+7577,1,299000120
+7578,1,299000140
+7579,2,202000010
+7580,2,290000010
+7581,2,299000010
+7582,2,299000150
+7583,2,299000190
+7584,2,299000200
+7585,2,299000210
+7586,3,298000050
+7587,3,298000060
+7588,3,299000060
+7589,3,299000170
+7590,3,290000120
+7591,3,291000050
+7592,3,292000020
+7593,4,299000670
+7594,4,299000680
+7595,4,204000010
+7596,5,297000100
+7597,5,291000020
+7598,5,297000130
+7599,5,297000140
+7600,5,203000010
+7601,4,140000
+7602,5,150010
+7603,5,150020
+7604,5,150030
+7605,5,150040
+7607,1,101000010
+7608,1,102000010
+7609,1,103000010
+7610,1,104000010
+7611,1,105000010
+7612,1,106000010
+7613,1,107000010
+7614,1,108000010
+7615,1,109000010
+7616,1,110000010
+7617,2,101000020
+7618,2,101000030
+7619,2,102000020
+7620,2,102000030
+7621,2,102000040
+7622,2,103000020
+7623,2,103000030
+7624,2,103000040
+7625,2,104000020
+7626,2,104000030
+7627,2,104000040
+7628,2,105000020
+7629,2,105000030
+7630,2,105000040
+7631,2,106000020
+7632,2,106000030
+7633,2,106000040
+7634,2,107000020
+7635,2,107000030
+7636,2,107000040
+7637,2,108000020
+7638,2,108000030
+7639,2,108000040
+7640,2,109000020
+7641,2,109000030
+7642,2,109000040
+7643,2,110000020
+7644,2,110000030
+7645,2,110000040
+7646,2,118000010
+7647,3,101000050
+7648,3,101000060
+7649,3,101000080
+7650,3,101000040
+7651,3,109000060
+7652,3,109000070
+7653,3,109000080
+7654,3,105000060
+7655,3,105000070
+7656,3,105000080
+7657,3,104000050
+7658,3,106000050
+7659,3,102000060
+7660,3,102000070
+7661,3,102000080
+7662,3,103000050
+7663,3,105000050
+7664,3,107000060
+7665,3,107000070
+7666,3,107000080
+7667,3,108000050
+7668,3,109000050
+7669,3,103000060
+7670,3,103000070
+7671,3,103000080
+7672,3,110000050
+7673,3,106000060
+7674,3,106000070
+7675,3,106000080
+7676,3,101000070
+7677,3,110000060
+7678,3,104000060
+7679,3,104000070
+7680,3,104000080
+7681,3,102000050
+7682,3,104000170
+7683,3,104000260
+7684,3,111000010
+7685,3,111000020
+7686,3,111000030
+7687,3,112000020
+7688,3,112000030
+7689,3,108000060
+7690,3,108000070
+7691,3,108000080
+7692,3,107000050
+7693,3,112000010
+7694,3,110000070
+7695,3,110000080
+7696,3,118000020
+7697,3,118000030
+7698,3,118000040
+7699,4,101000090
+7700,4,101000100
+7701,4,101000110
+7702,4,109000100
+7703,4,105000100
+7704,4,105000110
+7705,4,108000090
+7706,4,110000090
+7707,4,102000100
+7708,4,102000110
+7709,4,106000090
+7710,4,109000090
+7711,4,107000100
+7712,4,103000090
+7713,4,102000090
+7714,4,103000100
+7715,4,106000100
+7716,4,106000110
+7717,4,104000090
+7718,4,104000100
+7719,4,104000110
+7720,4,107000090
+7721,4,104000180
+7722,4,111000040
+7723,4,112000040
+7724,4,108000100
+7725,4,105000090
+7726,4,110000100
+7727,4,118000050
+7728,4,118000060
+7729,5,101000120
+7730,5,109000110
+7731,5,105000120
+7732,5,102000120
+7733,5,107000110
+7734,5,103000120
+7735,5,106000120
+7736,5,104000120
+7737,5,104000190
+7738,5,111000060
+7739,5,112000060
+7740,5,108000110
+7741,5,110000110
+7742,5,118000070
+7743,2,170003
+7744,3,170004
+7745,2,180003
+7746,3,180004
+7747,1,201000010
+7748,1,292000010
+7749,1,299000040
+7750,1,299000070
+7751,1,299000110
+7752,1,299000120
+7753,1,299000140
+7754,2,202000010
+7755,2,290000010
+7756,2,299000010
+7757,2,299000150
+7758,2,299000190
+7759,2,299000200
+7760,2,299000210
+7761,3,298000050
+7762,3,298000060
+7763,3,299000060
+7764,3,299000170
+7765,3,290000120
+7766,3,291000050
+7767,3,292000020
+7768,4,299000670
+7769,4,299000680
+7770,4,204000010
+7771,5,297000100
+7772,5,291000020
+7773,5,297000130
+7774,5,297000140
+7775,5,203000010
+7776,4,140000
+7777,5,150010
+7778,5,150020
+7779,5,150030
+7780,5,150040
+7782,3,101000050
+7783,3,101000060
+7784,3,101000080
+7785,3,101000040
+7786,3,109000060
+7787,3,109000070
+7788,3,109000080
+7789,3,105000060
+7790,3,105000070
+7791,3,105000080
+7792,3,104000050
+7793,3,106000050
+7794,3,102000060
+7795,3,102000070
+7796,3,102000080
+7797,3,103000050
+7798,3,105000050
+7799,3,107000060
+7800,3,107000070
+7801,3,107000080
+7802,3,108000050
+7803,3,109000050
+7804,3,103000060
+7805,3,103000070
+7806,3,103000080
+7807,3,110000050
+7808,3,106000060
+7809,3,106000070
+7810,3,106000080
+7811,3,101000070
+7812,3,110000060
+7813,3,104000060
+7814,3,104000070
+7815,3,104000080
+7816,3,102000050
+7817,3,104000170
+7818,3,104000260
+7819,3,111000010
+7820,3,111000020
+7821,3,111000030
+7822,3,112000020
+7823,3,112000030
+7824,3,108000060
+7825,3,108000070
+7826,3,108000080
+7827,3,107000050
+7828,3,112000010
+7829,3,110000070
+7830,3,110000080
+7831,3,118000020
+7832,3,118000030
+7833,3,118000040
+7834,4,101000090
+7835,4,101000100
+7836,4,101000110
+7837,4,109000100
+7838,4,105000100
+7839,4,105000110
+7840,4,108000090
+7841,4,110000090
+7842,4,102000100
+7843,4,102000110
+7844,4,106000090
+7845,4,109000090
+7846,4,107000100
+7847,4,103000090
+7848,4,102000090
+7849,4,103000100
+7850,4,106000100
+7851,4,106000110
+7852,4,104000090
+7853,4,104000100
+7854,4,104000110
+7855,4,107000090
+7856,4,104000180
+7857,4,111000040
+7858,4,112000040
+7859,4,108000100
+7860,4,105000090
+7861,4,110000100
+7862,4,118000050
+7863,4,118000060
+7864,5,101000120
+7865,5,109000110
+7866,5,105000120
+7867,5,102000120
+7868,5,107000110
+7869,5,103000120
+7870,5,106000120
+7871,5,104000120
+7872,5,104000190
+7873,5,111000060
+7874,5,112000060
+7875,5,108000110
+7876,5,110000110
+7877,5,118000070
+7878,3,170004
+7879,3,180004
+7880,1,201000010
+7881,1,292000010
+7882,1,299000040
+7883,1,299000070
+7884,1,299000110
+7885,1,299000120
+7886,1,299000140
+7887,2,202000010
+7888,2,290000010
+7889,2,299000010
+7890,2,299000150
+7891,2,299000190
+7892,2,299000200
+7893,2,299000210
+7894,3,298000050
+7895,3,298000060
+7896,3,299000060
+7897,3,299000170
+7898,3,290000120
+7899,3,291000050
+7900,3,292000020
+7901,4,299000670
+7902,4,299000680
+7903,4,204000010
+7904,5,297000100
+7905,5,291000020
+7906,5,297000130
+7907,5,297000140
+7908,5,203000010
+7909,4,140000
+7910,5,150010
+7911,5,150020
+7912,5,150030
+7913,5,150040
+7915,3,101000050
+7916,3,101000060
+7917,3,101000080
+7918,3,101000040
+7919,3,109000060
+7920,3,109000070
+7921,3,109000080
+7922,3,105000060
+7923,3,105000070
+7924,3,105000080
+7925,3,104000050
+7926,3,106000050
+7927,3,102000060
+7928,3,102000070
+7929,3,102000080
+7930,3,103000050
+7931,3,105000050
+7932,3,107000060
+7933,3,107000070
+7934,3,107000080
+7935,3,108000050
+7936,3,109000050
+7937,3,103000060
+7938,3,103000070
+7939,3,103000080
+7940,3,110000050
+7941,3,106000060
+7942,3,106000070
+7943,3,106000080
+7944,3,101000070
+7945,3,110000060
+7946,3,104000060
+7947,3,104000070
+7948,3,104000080
+7949,3,102000050
+7950,3,104000170
+7951,3,104000260
+7952,3,111000010
+7953,3,111000020
+7954,3,111000030
+7955,3,112000020
+7956,3,112000030
+7957,3,108000060
+7958,3,108000070
+7959,3,108000080
+7960,3,107000050
+7961,3,112000010
+7962,3,110000070
+7963,3,110000080
+7964,3,118000020
+7965,3,118000030
+7966,3,118000040
+7967,4,101000090
+7968,4,101000100
+7969,4,101000110
+7970,4,109000100
+7971,4,105000100
+7972,4,105000110
+7973,4,108000090
+7974,4,110000090
+7975,4,102000100
+7976,4,102000110
+7977,4,106000090
+7978,4,109000090
+7979,4,107000100
+7980,4,103000090
+7981,4,102000090
+7982,4,103000100
+7983,4,106000100
+7984,4,106000110
+7985,4,104000090
+7986,4,104000100
+7987,4,104000110
+7988,4,107000090
+7989,4,104000180
+7990,4,111000040
+7991,4,112000040
+7992,4,108000100
+7993,4,105000090
+7994,4,110000100
+7995,4,118000050
+7996,4,118000060
+7997,5,101000120
+7998,5,109000110
+7999,5,105000120
+8000,5,102000120
+8001,5,107000110
+8002,5,103000120
+8003,5,106000120
+8004,5,104000120
+8005,5,104000190
+8006,5,111000060
+8007,5,112000060
+8008,5,108000110
+8009,5,110000110
+8010,5,118000070
+8011,3,170004
+8012,3,180004
+8013,1,201000010
+8014,1,292000010
+8015,1,299000040
+8016,1,299000070
+8017,1,299000110
+8018,1,299000120
+8019,1,299000140
+8020,2,202000010
+8021,2,290000010
+8022,2,299000010
+8023,2,299000150
+8024,2,299000190
+8025,2,299000200
+8026,2,299000210
+8027,3,298000050
+8028,3,298000060
+8029,3,299000060
+8030,3,299000170
+8031,3,290000120
+8032,3,291000050
+8033,3,292000020
+8034,4,299000670
+8035,4,299000680
+8036,4,204000010
+8037,5,297000100
+8038,5,291000020
+8039,5,297000130
+8040,5,297000140
+8041,5,203000010
+8042,4,140000
+8043,5,150010
+8044,5,150020
+8045,5,150030
+8046,5,150040
+8048,3,101000050
+8049,3,101000060
+8050,3,101000080
+8051,3,101000040
+8052,3,109000060
+8053,3,109000070
+8054,3,109000080
+8055,3,105000060
+8056,3,105000070
+8057,3,105000080
+8058,3,104000050
+8059,3,106000050
+8060,3,102000060
+8061,3,102000070
+8062,3,102000080
+8063,3,103000050
+8064,3,105000050
+8065,3,107000060
+8066,3,107000070
+8067,3,107000080
+8068,3,108000050
+8069,3,109000050
+8070,3,103000060
+8071,3,103000070
+8072,3,103000080
+8073,3,110000050
+8074,3,106000060
+8075,3,106000070
+8076,3,106000080
+8077,3,101000070
+8078,3,110000060
+8079,3,104000060
+8080,3,104000070
+8081,3,104000080
+8082,3,102000050
+8083,3,104000170
+8084,3,104000260
+8085,3,111000010
+8086,3,111000020
+8087,3,111000030
+8088,3,112000020
+8089,3,112000030
+8090,3,108000060
+8091,3,108000070
+8092,3,108000080
+8093,3,107000050
+8094,3,112000010
+8095,3,110000070
+8096,3,110000080
+8097,3,118000020
+8098,3,118000030
+8099,3,118000040
+8100,4,101000090
+8101,4,101000100
+8102,4,101000110
+8103,4,109000100
+8104,4,105000100
+8105,4,105000110
+8106,4,108000090
+8107,4,110000090
+8108,4,102000100
+8109,4,102000110
+8110,4,106000090
+8111,4,109000090
+8112,4,107000100
+8113,4,103000090
+8114,4,102000090
+8115,4,103000100
+8116,4,106000100
+8117,4,106000110
+8118,4,104000090
+8119,4,104000100
+8120,4,104000110
+8121,4,107000090
+8122,4,104000180
+8123,4,111000040
+8124,4,112000040
+8125,4,108000100
+8126,4,105000090
+8127,4,110000100
+8128,4,118000050
+8129,4,118000060
+8130,5,101000120
+8131,5,109000110
+8132,5,105000120
+8133,5,102000120
+8134,5,107000110
+8135,5,103000120
+8136,5,106000120
+8137,5,104000120
+8138,5,104000190
+8139,5,111000060
+8140,5,112000060
+8141,5,108000110
+8142,5,110000110
+8143,5,118000070
+8144,3,170004
+8145,3,180004
+8146,1,201000010
+8147,1,292000010
+8148,1,299000040
+8149,1,299000070
+8150,1,299000110
+8151,1,299000120
+8152,1,299000140
+8153,2,202000010
+8154,2,290000010
+8155,2,299000010
+8156,2,299000150
+8157,2,299000190
+8158,2,299000200
+8159,2,299000210
+8160,3,298000050
+8161,3,298000060
+8162,3,299000060
+8163,3,299000170
+8164,3,290000120
+8165,3,291000050
+8166,3,292000020
+8167,4,299000670
+8168,4,299000680
+8169,4,204000010
+8170,5,297000100
+8171,5,291000020
+8172,5,297000130
+8173,5,297000140
+8174,5,203000010
+8175,4,140000
+8176,5,150010
+8177,5,150020
+8178,5,150030
+8179,5,150040
+8180,5,190000
+8181,5,200000
+8182,5,210000
+8184,3,102000060
+8185,3,102000070
+8186,3,102000080
+8187,3,103000050
+8188,3,105000050
+8189,3,107000060
+8190,3,107000070
+8191,3,107000080
+8192,3,108000050
+8193,3,109000050
+8194,3,103000060
+8195,3,103000070
+8196,3,103000080
+8197,3,110000050
+8198,4,102000100
+8199,4,102000110
+8200,4,106000090
+8201,4,109000090
+8202,4,107000100
+8203,4,103000090
+8204,4,102000090
+8205,4,103000100
+8206,5,102000120
+8207,5,107000110
+8208,5,103000120
+8209,1,102000000
+8210,2,102000001
+8211,3,102000002
+8212,4,102000003
+8213,5,102000004
+8214,1,105000000
+8215,2,105000001
+8216,3,105000002
+8217,4,105000003
+8218,5,105000004
+8219,1,112000000
+8220,2,112000001
+8221,3,112000002
+8222,4,112000003
+8223,5,112000004
+8224,3,170004
+8225,4,170005
+8226,3,180004
+8227,4,180005
+8228,4,140000
+8229,4,150010
+8230,4,150020
+8231,4,150030
+8232,4,150040
+8234,3,118000020
+8235,3,118000030
+8236,3,118000040
+8237,3,106000060
+8238,3,106000070
+8239,3,106000080
+8240,3,101000070
+8241,3,110000060
+8242,3,104000060
+8243,3,104000070
+8244,3,104000080
+8245,3,102000050
+8246,3,104000170
+8247,3,104000260
+8248,4,118000050
+8249,4,118000060
+8250,4,106000100
+8251,4,106000110
+8252,4,104000090
+8253,4,104000100
+8254,4,104000110
+8255,4,104000270
+8256,4,107000090
+8257,4,104000180
+8258,5,118000070
+8259,5,106000120
+8260,5,104000120
+8261,5,104000190
+8262,1,103000000
+8263,2,103000001
+8264,3,103000002
+8265,4,103000003
+8266,5,103000004
+8267,1,111000000
+8268,2,111000001
+8269,3,111000002
+8270,4,111000003
+8271,5,111000004
+8272,1,115000000
+8273,2,115000001
+8274,3,115000002
+8275,4,115000003
+8276,5,115000004
+8277,4,110024
+8278,4,110034
+8279,4,110044
+8280,4,110054
+8281,3,110060
+8282,3,110070
+8283,3,110080
+8284,3,110090
+8285,3,110100
+8286,3,110110
+8287,3,110120
+8288,3,110130
+8289,3,110140
+8290,3,110150
+8291,3,110160
+8292,3,110170
+8293,3,110180
+8294,3,110190
+8295,3,110200
+8296,3,110210
+8297,3,110220
+8298,3,110230
+8299,3,110240
+8300,3,110250
+8301,3,110260
+8302,3,110270
+8303,3,110620
+8304,3,110670
+8305,4,140000
+8306,4,150010
+8307,4,150020
+8308,4,150030
+8309,4,150040
+8311,3,111000010
+8312,3,111000020
+8313,3,111000030
+8314,3,112000020
+8315,3,112000030
+8316,3,108000060
+8317,3,108000070
+8318,3,108000080
+8319,3,107000050
+8320,3,112000010
+8321,3,110000070
+8322,3,110000080
+8323,4,111000040
+8324,4,112000040
+8325,4,108000100
+8326,4,105000090
+8327,4,110000100
+8328,5,111000060
+8329,5,112000060
+8330,5,108000110
+8331,5,110000110
+8332,1,108000000
+8333,2,108000001
+8334,3,108000002
+8335,4,108000003
+8336,5,108000004
+8337,1,107000000
+8338,2,107000001
+8339,3,107000002
+8340,4,107000003
+8341,5,107000004
+8342,1,120000000
+8343,2,120000001
+8344,3,120000002
+8345,4,120000003
+8346,5,120000004
+8347,4,120024
+8348,4,120034
+8349,4,120044
+8350,4,120054
+8351,3,120241
+8352,3,120251
+8353,3,120261
+8354,3,120271
+8355,3,120300
+8356,3,120310
+8357,3,120320
+8358,3,120330
+8359,3,120340
+8360,3,120350
+8361,3,120360
+8362,3,120370
+8363,3,120380
+8364,3,120390
+8365,3,120400
+8366,3,120410
+8367,3,120420
+8368,3,120430
+8369,3,120450
+8370,3,120460
+8371,3,120550
+8372,3,120560
+8373,3,120570
+8374,3,120990
+8375,3,121000
+8376,3,121010
+8377,3,121020
+8378,4,140000
+8379,4,150010
+8380,4,150020
+8381,4,150030
+8382,4,150040
+8384,3,101000050
+8385,3,101000060
+8386,3,101000080
+8387,3,101000040
+8388,3,109000060
+8389,3,109000070
+8390,3,109000080
+8391,3,105000060
+8392,3,105000070
+8393,3,105000080
+8394,3,104000050
+8395,3,106000050
+8396,4,101000090
+8397,4,101000100
+8398,4,101000110
+8399,4,109000100
+8400,4,105000100
+8401,4,105000110
+8402,4,108000090
+8403,4,110000090
+8404,5,101000120
+8405,5,109000110
+8406,5,105000120
+8407,1,101000000
+8408,2,101000001
+8409,3,101000002
+8410,4,101000008
+8411,5,101000004
+8412,1,109000000
+8413,2,109000001
+8414,3,109000002
+8415,4,109000003
+8416,5,109000004
+8417,4,130024
+8418,4,130034
+8419,4,130044
+8420,4,130054
+8421,3,130060
+8422,3,130070
+8423,3,130080
+8424,3,130090
+8425,3,130100
+8426,3,130110
+8427,3,130120
+8428,3,130130
+8429,3,130140
+8430,3,130150
+8431,3,130160
+8432,3,130170
+8433,3,130180
+8434,3,130190
+8435,3,130200
+8436,3,130420
+8437,3,130510
+8438,3,130520
+8439,3,130531
+8440,3,130540
+8441,3,130660
+8442,3,130790
+8443,3,130800
+8444,3,131130
+8445,4,140000
+8446,4,150010
+8447,4,150020
+8448,4,150030
+8449,4,150040
+8451,1,101000000
+8452,2,101000001
+8453,3,101000002
+8454,4,101000008
+8455,5,101000004
+8456,1,102000000
+8457,2,102000001
+8458,3,102000002
+8459,4,102000003
+8460,5,102000004
+8461,1,103000000
+8462,2,103000001
+8463,3,103000002
+8464,4,103000003
+8465,5,103000004
+8466,1,105000000
+8467,2,105000001
+8468,3,105000002
+8469,4,105000003
+8470,5,105000004
+8471,1,108000000
+8472,2,108000001
+8473,3,108000002
+8474,4,108000003
+8475,5,108000004
+8476,1,109000000
+8477,2,109000001
+8478,3,109000002
+8479,4,109000003
+8480,5,109000004
+8481,1,111000000
+8482,2,111000001
+8483,3,111000002
+8484,4,111000003
+8485,5,111000004
+8486,1,112000000
+8487,2,112000001
+8488,3,112000002
+8489,4,112000003
+8490,5,112000004
+8491,1,120000000
+8492,2,120000001
+8493,3,120000002
+8494,4,120000003
+8495,5,120000004
+8496,1,101000010
+8497,2,101000020
+8498,2,101000030
+8499,3,101000040
+8500,3,101000050
+8501,3,101000060
+8502,3,101000070
+8503,3,101000080
+8504,1,102000010
+8505,2,102000020
+8506,2,102000030
+8507,2,102000040
+8508,3,102000050
+8509,3,102000060
+8510,3,102000070
+8511,3,102000080
+8512,1,103000010
+8513,2,103000020
+8514,2,103000030
+8515,2,103000040
+8516,3,103000050
+8517,3,103000060
+8518,3,103000070
+8519,3,103000080
+8520,1,104000010
+8521,2,104000020
+8522,2,104000030
+8523,2,104000040
+8524,3,104000050
+8525,3,104000060
+8526,3,104000070
+8527,3,104000080
+8528,1,105000010
+8529,2,105000020
+8530,2,105000030
+8531,2,105000040
+8532,3,105000050
+8533,3,105000060
+8534,3,105000070
+8535,3,105000080
+8536,1,106000010
+8537,2,106000020
+8538,2,106000030
+8539,2,106000040
+8540,3,106000050
+8541,3,106000060
+8542,3,106000070
+8543,3,106000080
+8544,1,107000010
+8545,2,107000020
+8546,2,107000030
+8547,2,107000040
+8548,3,107000050
+8549,3,107000060
+8550,3,107000070
+8551,3,107000080
+8552,1,108000010
+8553,2,108000020
+8554,2,108000030
+8555,2,108000040
+8556,3,108000050
+8557,3,108000060
+8558,3,108000070
+8559,3,108000080
+8560,2,180000
+8561,2,170002
+8562,3,170003
+8563,4,170004
+8565,1,101000000
+8566,2,101000001
+8567,3,101000002
+8568,4,101000008
+8569,5,101000004
+8570,1,102000000
+8571,2,102000001
+8572,3,102000002
+8573,4,102000003
+8574,5,102000004
+8575,1,103000000
+8576,2,103000001
+8577,3,103000002
+8578,4,103000003
+8579,5,103000004
+8580,1,105000000
+8581,2,105000001
+8582,3,105000002
+8583,4,105000003
+8584,5,105000004
+8585,1,108000000
+8586,2,108000001
+8587,3,108000002
+8588,4,108000003
+8589,5,108000004
+8590,1,109000000
+8591,2,109000001
+8592,3,109000002
+8593,4,109000003
+8594,5,109000004
+8595,1,111000000
+8596,2,111000001
+8597,3,111000002
+8598,4,111000003
+8599,5,111000004
+8600,1,112000000
+8601,2,112000001
+8602,3,112000002
+8603,4,112000003
+8604,5,112000004
+8605,1,120000000
+8606,2,120000001
+8607,3,120000002
+8608,4,120000003
+8609,5,120000004
+8610,1,101000010
+8611,2,101000020
+8612,2,101000030
+8613,3,101000040
+8614,3,101000050
+8615,3,101000060
+8616,3,101000070
+8617,3,101000080
+8618,1,102000010
+8619,2,102000020
+8620,2,102000030
+8621,2,102000040
+8622,3,102000050
+8623,3,102000060
+8624,3,102000070
+8625,3,102000080
+8626,1,103000010
+8627,2,103000020
+8628,2,103000030
+8629,2,103000040
+8630,3,103000050
+8631,3,103000060
+8632,3,103000070
+8633,3,103000080
+8634,1,104000010
+8635,2,104000020
+8636,2,104000030
+8637,2,104000040
+8638,3,104000050
+8639,3,104000060
+8640,3,104000070
+8641,3,104000080
+8642,1,105000010
+8643,2,105000020
+8644,2,105000030
+8645,2,105000040
+8646,3,105000050
+8647,3,105000060
+8648,3,105000070
+8649,3,105000080
+8650,1,106000010
+8651,2,106000020
+8652,2,106000030
+8653,2,106000040
+8654,3,106000050
+8655,3,106000060
+8656,3,106000070
+8657,3,106000080
+8658,1,107000010
+8659,2,107000020
+8660,2,107000030
+8661,2,107000040
+8662,3,107000050
+8663,3,107000060
+8664,3,107000070
+8665,3,107000080
+8666,1,108000010
+8667,2,108000020
+8668,2,108000030
+8669,2,108000040
+8670,3,108000050
+8671,3,108000060
+8672,3,108000070
+8673,3,108000080
+8674,2,180000
+8675,2,170002
+8676,3,170003
+8677,4,170004
+8679,1,101000000
+8680,2,101000001
+8681,3,101000002
+8682,4,101000008
+8683,5,101000004
+8684,1,102000000
+8685,2,102000001
+8686,3,102000002
+8687,4,102000003
+8688,5,102000004
+8689,1,103000000
+8690,2,103000001
+8691,3,103000002
+8692,4,103000003
+8693,5,103000004
+8694,1,105000000
+8695,2,105000001
+8696,3,105000002
+8697,4,105000003
+8698,5,105000004
+8699,1,108000000
+8700,2,108000001
+8701,3,108000002
+8702,4,108000003
+8703,5,108000004
+8704,1,109000000
+8705,2,109000001
+8706,3,109000002
+8707,4,109000003
+8708,5,109000004
+8709,1,111000000
+8710,2,111000001
+8711,3,111000002
+8712,4,111000003
+8713,5,111000004
+8714,1,112000000
+8715,2,112000001
+8716,3,112000002
+8717,4,112000003
+8718,5,112000004
+8719,1,120000000
+8720,2,120000001
+8721,3,120000002
+8722,4,120000003
+8723,5,120000004
+8724,1,101000010
+8725,2,101000020
+8726,2,101000030
+8727,3,101000040
+8728,3,101000050
+8729,3,101000060
+8730,3,101000070
+8731,3,101000080
+8732,1,102000010
+8733,2,102000020
+8734,2,102000030
+8735,2,102000040
+8736,3,102000050
+8737,3,102000060
+8738,3,102000070
+8739,3,102000080
+8740,1,103000010
+8741,2,103000020
+8742,2,103000030
+8743,2,103000040
+8744,3,103000050
+8745,3,103000060
+8746,3,103000070
+8747,3,103000080
+8748,1,104000010
+8749,2,104000020
+8750,2,104000030
+8751,2,104000040
+8752,3,104000050
+8753,3,104000060
+8754,3,104000070
+8755,3,104000080
+8756,1,105000010
+8757,2,105000020
+8758,2,105000030
+8759,2,105000040
+8760,3,105000050
+8761,3,105000060
+8762,3,105000070
+8763,3,105000080
+8764,1,106000010
+8765,2,106000020
+8766,2,106000030
+8767,2,106000040
+8768,3,106000050
+8769,3,106000060
+8770,3,106000070
+8771,3,106000080
+8772,1,107000010
+8773,2,107000020
+8774,2,107000030
+8775,2,107000040
+8776,3,107000050
+8777,3,107000060
+8778,3,107000070
+8779,3,107000080
+8780,1,108000010
+8781,2,108000020
+8782,2,108000030
+8783,2,108000040
+8784,3,108000050
+8785,3,108000060
+8786,3,108000070
+8787,3,108000080
+8788,2,180001
+8789,2,170002
+8790,3,170003
+8791,4,170004
+8793,1,101000000
+8794,2,101000001
+8795,3,101000002
+8796,4,101000008
+8797,5,101000004
+8798,1,102000000
+8799,2,102000001
+8800,3,102000002
+8801,4,102000003
+8802,5,102000004
+8803,1,103000000
+8804,2,103000001
+8805,3,103000002
+8806,4,103000003
+8807,5,103000004
+8808,1,105000000
+8809,2,105000001
+8810,3,105000002
+8811,4,105000003
+8812,5,105000004
+8813,1,108000000
+8814,2,108000001
+8815,3,108000002
+8816,4,108000003
+8817,5,108000004
+8818,1,109000000
+8819,2,109000001
+8820,3,109000002
+8821,4,109000003
+8822,5,109000004
+8823,1,111000000
+8824,2,111000001
+8825,3,111000002
+8826,4,111000003
+8827,5,111000004
+8828,1,112000000
+8829,2,112000001
+8830,3,112000002
+8831,4,112000003
+8832,5,112000004
+8833,1,120000000
+8834,2,120000001
+8835,3,120000002
+8836,4,120000003
+8837,5,120000004
+8838,1,101000010
+8839,2,101000020
+8840,2,101000030
+8841,3,101000040
+8842,3,101000050
+8843,3,101000060
+8844,3,101000070
+8845,3,101000080
+8846,1,102000010
+8847,2,102000020
+8848,2,102000030
+8849,2,102000040
+8850,3,102000050
+8851,3,102000060
+8852,3,102000070
+8853,3,102000080
+8854,1,103000010
+8855,2,103000020
+8856,2,103000030
+8857,2,103000040
+8858,3,103000050
+8859,3,103000060
+8860,3,103000070
+8861,3,103000080
+8862,1,104000010
+8863,2,104000020
+8864,2,104000030
+8865,2,104000040
+8866,3,104000050
+8867,3,104000060
+8868,3,104000070
+8869,3,104000080
+8870,1,105000010
+8871,2,105000020
+8872,2,105000030
+8873,2,105000040
+8874,3,105000050
+8875,3,105000060
+8876,3,105000070
+8877,3,105000080
+8878,1,106000010
+8879,2,106000020
+8880,2,106000030
+8881,2,106000040
+8882,3,106000050
+8883,3,106000060
+8884,3,106000070
+8885,3,106000080
+8886,1,107000010
+8887,2,107000020
+8888,2,107000030
+8889,2,107000040
+8890,3,107000050
+8891,3,107000060
+8892,3,107000070
+8893,3,107000080
+8894,1,108000010
+8895,2,108000020
+8896,2,108000030
+8897,2,108000040
+8898,3,108000050
+8899,3,108000060
+8900,3,108000070
+8901,3,108000080
+8902,1,109000010
+8903,2,109000020
+8904,2,109000030
+8905,2,109000040
+8906,3,109000050
+8907,3,109000060
+8908,3,109000070
+8909,3,109000080
+8910,2,180001
+8911,2,170002
+8912,3,170003
+8913,4,170004
+8915,1,101000000
+8916,2,101000001
+8917,3,101000002
+8918,4,101000008
+8919,5,101000004
+8920,1,102000000
+8921,2,102000001
+8922,3,102000002
+8923,4,102000003
+8924,5,102000004
+8925,1,103000000
+8926,2,103000001
+8927,3,103000002
+8928,4,103000003
+8929,5,103000004
+8930,1,105000000
+8931,2,105000001
+8932,3,105000002
+8933,4,105000003
+8934,5,105000004
+8935,1,107000000
+8936,2,107000001
+8937,3,107000002
+8938,4,107000003
+8939,5,107000004
+8940,1,108000000
+8941,2,108000001
+8942,3,108000002
+8943,4,108000003
+8944,5,108000004
+8945,1,109000000
+8946,2,109000001
+8947,3,109000002
+8948,4,109000003
+8949,5,109000004
+8950,1,111000000
+8951,2,111000001
+8952,3,111000002
+8953,4,111000003
+8954,5,111000004
+8955,1,112000000
+8956,2,112000001
+8957,3,112000002
+8958,4,112000003
+8959,5,112000004
+8960,1,120000000
+8961,2,120000001
+8962,3,120000002
+8963,4,120000003
+8964,5,120000004
+8965,1,101000010
+8966,2,101000020
+8967,2,101000030
+8968,3,101000040
+8969,3,101000050
+8970,3,101000060
+8971,3,101000070
+8972,3,101000080
+8973,1,102000010
+8974,2,102000020
+8975,2,102000030
+8976,2,102000040
+8977,3,102000050
+8978,3,102000060
+8979,3,102000070
+8980,3,102000080
+8981,1,103000010
+8982,2,103000020
+8983,2,103000030
+8984,2,103000040
+8985,3,103000050
+8986,3,103000060
+8987,3,103000070
+8988,3,103000080
+8989,1,104000010
+8990,2,104000020
+8991,2,104000030
+8992,2,104000040
+8993,3,104000050
+8994,3,104000060
+8995,3,104000070
+8996,3,104000080
+8997,1,105000010
+8998,2,105000020
+8999,2,105000030
+9000,2,105000040
+9001,3,105000050
+9002,3,105000060
+9003,3,105000070
+9004,3,105000080
+9005,1,106000010
+9006,2,106000020
+9007,2,106000030
+9008,2,106000040
+9009,3,106000050
+9010,3,106000060
+9011,3,106000070
+9012,3,106000080
+9013,1,107000010
+9014,2,107000020
+9015,2,107000030
+9016,2,107000040
+9017,3,107000050
+9018,3,107000060
+9019,3,107000070
+9020,3,107000080
+9021,1,108000010
+9022,2,108000020
+9023,2,108000030
+9024,2,108000040
+9025,3,108000050
+9026,3,108000060
+9027,3,108000070
+9028,3,108000080
+9029,1,109000010
+9030,2,109000020
+9031,2,109000030
+9032,2,109000040
+9033,3,109000050
+9034,3,109000060
+9035,3,109000070
+9036,3,109000080
+9037,1,110000010
+9038,2,110000020
+9039,2,110000030
+9040,2,110000040
+9041,3,110000050
+9042,3,110000060
+9043,3,110000070
+9044,3,110000080
+9045,2,180001
+9046,2,170002
+9047,3,170003
+9048,4,170004
+9050,1,101000010
+9051,1,102000010
+9052,1,103000010
+9053,1,104000010
+9054,1,105000010
+9055,1,106000010
+9056,1,107000010
+9057,1,108000010
+9058,1,109000010
+9059,1,110000010
+9060,2,101000020
+9061,2,101000030
+9062,2,102000020
+9063,2,102000030
+9064,2,102000040
+9065,2,103000020
+9066,2,103000030
+9067,2,103000040
+9068,2,104000020
+9069,2,104000030
+9070,2,104000040
+9071,2,105000020
+9072,2,105000030
+9073,2,105000040
+9074,2,106000020
+9075,2,106000030
+9076,2,106000040
+9077,2,107000020
+9078,2,107000030
+9079,2,107000040
+9080,2,108000020
+9081,2,108000030
+9082,2,108000040
+9083,2,109000020
+9084,2,109000030
+9085,2,109000040
+9086,2,110000020
+9087,2,110000030
+9088,2,110000040
+9089,2,118000010
+9090,3,101000050
+9091,3,101000060
+9092,3,101000080
+9093,3,101000040
+9094,3,109000060
+9095,3,109000070
+9096,3,109000080
+9097,3,105000060
+9098,3,105000070
+9099,3,105000080
+9100,3,104000050
+9101,3,106000050
+9102,3,102000060
+9103,3,102000070
+9104,3,102000080
+9105,3,103000050
+9106,3,105000050
+9107,3,107000060
+9108,3,107000070
+9109,3,107000080
+9110,3,108000050
+9111,3,109000050
+9112,3,103000060
+9113,3,103000070
+9114,3,103000080
+9115,3,110000050
+9116,3,106000060
+9117,3,106000070
+9118,3,106000080
+9119,3,101000070
+9120,3,110000060
+9121,3,104000060
+9122,3,104000070
+9123,3,104000080
+9124,3,102000050
+9125,3,104000170
+9126,3,104000260
+9127,3,111000010
+9128,3,111000020
+9129,3,111000030
+9130,3,112000020
+9131,3,112000030
+9132,3,108000060
+9133,3,108000070
+9134,3,108000080
+9135,3,107000050
+9136,3,112000010
+9137,3,110000070
+9138,3,110000080
+9139,3,118000020
+9140,3,118000030
+9141,3,118000040
+9142,4,101000090
+9143,4,101000100
+9144,4,101000110
+9145,4,109000100
+9146,4,105000100
+9147,4,105000110
+9148,4,108000090
+9149,4,110000090
+9150,4,102000100
+9151,4,102000110
+9152,4,106000090
+9153,4,109000090
+9154,4,107000100
+9155,4,103000090
+9156,4,102000090
+9157,4,103000100
+9158,4,106000100
+9159,4,106000110
+9160,4,104000090
+9161,4,104000100
+9162,4,104000110
+9163,4,107000090
+9164,4,104000180
+9165,4,111000040
+9166,4,112000040
+9167,4,108000100
+9168,4,105000090
+9169,4,110000100
+9170,4,118000050
+9171,4,118000060
+9172,5,101000120
+9173,5,109000110
+9174,5,105000120
+9175,5,102000120
+9176,5,107000110
+9177,5,103000120
+9178,5,106000120
+9179,5,104000120
+9180,5,104000190
+9181,5,111000060
+9182,5,112000060
+9183,5,108000110
+9184,5,110000110
+9185,5,118000070
+9186,1,201000010
+9187,1,292000010
+9188,1,299000040
+9189,1,299000070
+9190,1,299000110
+9191,1,299000120
+9192,1,299000140
+9193,2,202000010
+9194,2,290000010
+9195,2,299000010
+9196,2,299000150
+9197,2,299000190
+9198,2,299000200
+9199,2,299000210
+9200,3,298000050
+9201,3,298000060
+9202,3,299000060
+9203,3,299000170
+9204,3,290000120
+9205,3,291000050
+9206,3,292000020
+9207,4,299000670
+9208,4,299000680
+9209,4,204000010
+9210,4,209000040
+9211,5,297000100
+9212,5,291000020
+9213,5,297000130
+9214,5,297000140
+9215,5,203000010
+9216,5,206000030
+9217,1,170002
+9218,1,180002
+9219,2,170003
+9220,2,180003
+9221,3,170004
+9222,3,180004
+9223,4,140000
+9224,5,150010
+9225,5,150020
+9226,5,150030
+9227,5,150040
+9229,1,101000010
+9230,1,102000010
+9231,1,103000010
+9232,1,104000010
+9233,1,105000010
+9234,1,106000010
+9235,1,107000010
+9236,1,108000010
+9237,1,109000010
+9238,1,110000010
+9239,2,101000020
+9240,2,101000030
+9241,2,102000020
+9242,2,102000030
+9243,2,102000040
+9244,2,103000020
+9245,2,103000030
+9246,2,103000040
+9247,2,104000020
+9248,2,104000030
+9249,2,104000040
+9250,2,105000020
+9251,2,105000030
+9252,2,105000040
+9253,2,106000020
+9254,2,106000030
+9255,2,106000040
+9256,2,107000020
+9257,2,107000030
+9258,2,107000040
+9259,2,108000020
+9260,2,108000030
+9261,2,108000040
+9262,2,109000020
+9263,2,109000030
+9264,2,109000040
+9265,2,110000020
+9266,2,110000030
+9267,2,110000040
+9268,2,118000010
+9269,3,101000050
+9270,3,101000060
+9271,3,101000080
+9272,3,101000040
+9273,3,109000060
+9274,3,109000070
+9275,3,109000080
+9276,3,105000060
+9277,3,105000070
+9278,3,105000080
+9279,3,104000050
+9280,3,106000050
+9281,3,102000060
+9282,3,102000070
+9283,3,102000080
+9284,3,103000050
+9285,3,105000050
+9286,3,107000060
+9287,3,107000070
+9288,3,107000080
+9289,3,108000050
+9290,3,109000050
+9291,3,103000060
+9292,3,103000070
+9293,3,103000080
+9294,3,110000050
+9295,3,106000060
+9296,3,106000070
+9297,3,106000080
+9298,3,101000070
+9299,3,110000060
+9300,3,104000060
+9301,3,104000070
+9302,3,104000080
+9303,3,102000050
+9304,3,104000170
+9305,3,104000260
+9306,3,111000010
+9307,3,111000020
+9308,3,111000030
+9309,3,112000020
+9310,3,112000030
+9311,3,108000060
+9312,3,108000070
+9313,3,108000080
+9314,3,107000050
+9315,3,112000010
+9316,3,110000070
+9317,3,110000080
+9318,3,118000020
+9319,3,118000030
+9320,3,118000040
+9321,4,101000090
+9322,4,101000100
+9323,4,101000110
+9324,4,109000100
+9325,4,105000100
+9326,4,105000110
+9327,4,108000090
+9328,4,110000090
+9329,4,102000100
+9330,4,102000110
+9331,4,106000090
+9332,4,109000090
+9333,4,107000100
+9334,4,103000090
+9335,4,102000090
+9336,4,103000100
+9337,4,106000100
+9338,4,106000110
+9339,4,104000090
+9340,4,104000100
+9341,4,104000110
+9342,4,107000090
+9343,4,104000180
+9344,4,111000040
+9345,4,112000040
+9346,4,108000100
+9347,4,105000090
+9348,4,110000100
+9349,4,118000050
+9350,4,118000060
+9351,5,101000120
+9352,5,109000110
+9353,5,105000120
+9354,5,102000120
+9355,5,107000110
+9356,5,103000120
+9357,5,106000120
+9358,5,104000120
+9359,5,104000190
+9360,5,111000060
+9361,5,112000060
+9362,5,108000110
+9363,5,110000110
+9364,5,118000070
+9365,1,201000010
+9366,1,292000010
+9367,1,299000040
+9368,1,299000070
+9369,1,299000110
+9370,1,299000120
+9371,1,299000140
+9372,2,202000010
+9373,2,290000010
+9374,2,299000010
+9375,2,299000150
+9376,2,299000190
+9377,2,299000200
+9378,2,299000210
+9379,3,298000050
+9380,3,298000060
+9381,3,299000060
+9382,3,299000170
+9383,3,290000120
+9384,3,291000050
+9385,3,292000020
+9386,4,299000670
+9387,4,299000680
+9388,4,204000010
+9389,4,209000040
+9390,5,297000100
+9391,5,291000020
+9392,5,297000130
+9393,5,297000140
+9394,5,203000010
+9395,5,206000030
+9396,2,170003
+9397,2,180003
+9398,3,170004
+9399,3,180004
+9400,4,140000
+9401,5,150010
+9402,5,150020
+9403,5,150030
+9404,5,150040
+9406,3,101000050
+9407,3,101000060
+9408,3,101000080
+9409,3,101000040
+9410,3,109000060
+9411,3,109000070
+9412,3,109000080
+9413,3,105000060
+9414,3,105000070
+9415,3,105000080
+9416,3,104000050
+9417,3,106000050
+9418,3,102000060
+9419,3,102000070
+9420,3,102000080
+9421,3,103000050
+9422,3,105000050
+9423,3,107000060
+9424,3,107000070
+9425,3,107000080
+9426,3,108000050
+9427,3,109000050
+9428,3,103000060
+9429,3,103000070
+9430,3,103000080
+9431,3,110000050
+9432,3,106000060
+9433,3,106000070
+9434,3,106000080
+9435,3,101000070
+9436,3,110000060
+9437,3,104000060
+9438,3,104000070
+9439,3,104000080
+9440,3,102000050
+9441,3,104000170
+9442,3,104000260
+9443,3,111000010
+9444,3,111000020
+9445,3,111000030
+9446,3,112000020
+9447,3,112000030
+9448,3,108000060
+9449,3,108000070
+9450,3,108000080
+9451,3,107000050
+9452,3,112000010
+9453,3,110000070
+9454,3,110000080
+9455,3,118000020
+9456,3,118000030
+9457,3,118000040
+9458,4,101000090
+9459,4,101000100
+9460,4,101000110
+9461,4,109000100
+9462,4,105000100
+9463,4,105000110
+9464,4,108000090
+9465,4,110000090
+9466,4,102000100
+9467,4,102000110
+9468,4,106000090
+9469,4,109000090
+9470,4,107000100
+9471,4,103000090
+9472,4,102000090
+9473,4,103000100
+9474,4,106000100
+9475,4,106000110
+9476,4,104000090
+9477,4,104000100
+9478,4,104000110
+9479,4,107000090
+9480,4,104000180
+9481,4,111000040
+9482,4,112000040
+9483,4,108000100
+9484,4,105000090
+9485,4,110000100
+9486,4,118000050
+9487,4,118000060
+9488,5,101000120
+9489,5,109000110
+9490,5,105000120
+9491,5,102000120
+9492,5,107000110
+9493,5,103000120
+9494,5,106000120
+9495,5,104000120
+9496,5,104000190
+9497,5,111000060
+9498,5,112000060
+9499,5,108000110
+9500,5,110000110
+9501,5,118000070
+9502,1,201000010
+9503,1,292000010
+9504,1,299000040
+9505,1,299000070
+9506,1,299000110
+9507,1,299000120
+9508,1,299000140
+9509,2,202000010
+9510,2,290000010
+9511,2,299000010
+9512,2,299000150
+9513,2,299000190
+9514,2,299000200
+9515,2,299000210
+9516,3,298000050
+9517,3,298000060
+9518,3,299000060
+9519,3,299000170
+9520,3,290000120
+9521,3,291000050
+9522,3,292000020
+9523,4,299000670
+9524,4,299000680
+9525,4,204000010
+9526,4,209000040
+9527,5,297000100
+9528,5,291000020
+9529,5,297000130
+9530,5,297000140
+9531,5,203000010
+9532,5,206000030
+9533,3,170004
+9534,3,180004
+9535,4,140000
+9536,5,150010
+9537,5,150020
+9538,5,150030
+9539,5,150040
+9541,3,101000050
+9542,3,101000060
+9543,3,101000080
+9544,3,101000040
+9545,3,109000060
+9546,3,109000070
+9547,3,109000080
+9548,3,105000060
+9549,3,105000070
+9550,3,105000080
+9551,3,104000050
+9552,3,106000050
+9553,3,102000060
+9554,3,102000070
+9555,3,102000080
+9556,3,103000050
+9557,3,105000050
+9558,3,107000060
+9559,3,107000070
+9560,3,107000080
+9561,3,108000050
+9562,3,109000050
+9563,3,103000060
+9564,3,103000070
+9565,3,103000080
+9566,3,110000050
+9567,3,106000060
+9568,3,106000070
+9569,3,106000080
+9570,3,101000070
+9571,3,110000060
+9572,3,104000060
+9573,3,104000070
+9574,3,104000080
+9575,3,102000050
+9576,3,104000170
+9577,3,104000260
+9578,3,111000010
+9579,3,111000020
+9580,3,111000030
+9581,3,112000020
+9582,3,112000030
+9583,3,108000060
+9584,3,108000070
+9585,3,108000080
+9586,3,107000050
+9587,3,112000010
+9588,3,110000070
+9589,3,110000080
+9590,3,118000020
+9591,3,118000030
+9592,3,118000040
+9593,4,101000090
+9594,4,101000100
+9595,4,101000110
+9596,4,109000100
+9597,4,105000100
+9598,4,105000110
+9599,4,108000090
+9600,4,110000090
+9601,4,102000100
+9602,4,102000110
+9603,4,106000090
+9604,4,109000090
+9605,4,107000100
+9606,4,103000090
+9607,4,102000090
+9608,4,103000100
+9609,4,106000100
+9610,4,106000110
+9611,4,104000090
+9612,4,104000100
+9613,4,104000110
+9614,4,107000090
+9615,4,104000180
+9616,4,111000040
+9617,4,112000040
+9618,4,108000100
+9619,4,105000090
+9620,4,110000100
+9621,4,118000050
+9622,4,118000060
+9623,5,101000120
+9624,5,109000110
+9625,5,105000120
+9626,5,102000120
+9627,5,107000110
+9628,5,103000120
+9629,5,106000120
+9630,5,104000120
+9631,5,104000190
+9632,5,111000060
+9633,5,112000060
+9634,5,108000110
+9635,5,110000110
+9636,5,118000070
+9637,1,201000010
+9638,1,292000010
+9639,1,299000040
+9640,1,299000070
+9641,1,299000110
+9642,1,299000120
+9643,1,299000140
+9644,2,202000010
+9645,2,290000010
+9646,2,299000010
+9647,2,299000150
+9648,2,299000190
+9649,2,299000200
+9650,2,299000210
+9651,3,298000050
+9652,3,298000060
+9653,3,299000060
+9654,3,299000170
+9655,3,290000120
+9656,3,291000050
+9657,3,292000020
+9658,4,299000670
+9659,4,299000680
+9660,4,204000010
+9661,4,209000040
+9662,5,297000100
+9663,5,291000020
+9664,5,297000130
+9665,5,297000140
+9666,5,203000010
+9667,5,206000030
+9668,3,170004
+9669,3,180004
+9670,4,140000
+9671,5,150010
+9672,5,150020
+9673,5,150030
+9674,5,150040
+9676,3,101000050
+9677,3,101000060
+9678,3,101000080
+9679,3,101000040
+9680,3,109000060
+9681,3,109000070
+9682,3,109000080
+9683,3,105000060
+9684,3,105000070
+9685,3,105000080
+9686,3,104000050
+9687,3,106000050
+9688,3,102000060
+9689,3,102000070
+9690,3,102000080
+9691,3,103000050
+9692,3,105000050
+9693,3,107000060
+9694,3,107000070
+9695,3,107000080
+9696,3,108000050
+9697,3,109000050
+9698,3,103000060
+9699,3,103000070
+9700,3,103000080
+9701,3,110000050
+9702,3,106000060
+9703,3,106000070
+9704,3,106000080
+9705,3,101000070
+9706,3,110000060
+9707,3,104000060
+9708,3,104000070
+9709,3,104000080
+9710,3,102000050
+9711,3,104000170
+9712,3,104000260
+9713,3,111000010
+9714,3,111000020
+9715,3,111000030
+9716,3,112000020
+9717,3,112000030
+9718,3,108000060
+9719,3,108000070
+9720,3,108000080
+9721,3,107000050
+9722,3,112000010
+9723,3,110000070
+9724,3,110000080
+9725,3,118000020
+9726,3,118000030
+9727,3,118000040
+9728,4,101000090
+9729,4,101000100
+9730,4,101000110
+9731,4,109000100
+9732,4,105000100
+9733,4,105000110
+9734,4,108000090
+9735,4,110000090
+9736,4,102000100
+9737,4,102000110
+9738,4,106000090
+9739,4,109000090
+9740,4,107000100
+9741,4,103000090
+9742,4,102000090
+9743,4,103000100
+9744,4,106000100
+9745,4,106000110
+9746,4,104000090
+9747,4,104000100
+9748,4,104000110
+9749,4,107000090
+9750,4,104000180
+9751,4,111000040
+9752,4,112000040
+9753,4,108000100
+9754,4,105000090
+9755,4,110000100
+9756,4,118000050
+9757,4,118000060
+9758,5,101000120
+9759,5,109000110
+9760,5,105000120
+9761,5,102000120
+9762,5,107000110
+9763,5,103000120
+9764,5,106000120
+9765,5,104000120
+9766,5,104000190
+9767,5,111000060
+9768,5,112000060
+9769,5,108000110
+9770,5,110000110
+9771,5,118000070
+9772,1,201000010
+9773,1,292000010
+9774,1,299000040
+9775,1,299000070
+9776,1,299000110
+9777,1,299000120
+9778,1,299000140
+9779,2,202000010
+9780,2,290000010
+9781,2,299000010
+9782,2,299000150
+9783,2,299000190
+9784,2,299000200
+9785,2,299000210
+9786,3,298000050
+9787,3,298000060
+9788,3,299000060
+9789,3,299000170
+9790,3,290000120
+9791,3,291000050
+9792,3,292000020
+9793,4,299000670
+9794,4,299000680
+9795,4,204000010
+9796,4,209000040
+9797,5,297000100
+9798,5,291000020
+9799,5,297000130
+9800,5,297000140
+9801,5,203000010
+9802,5,206000030
+9803,3,170004
+9804,3,180004
+9805,4,140000
+9806,5,150010
+9807,5,150020
+9808,5,150030
+9809,5,150040
+9810,5,190000
+9811,5,200000
+9812,5,210000
+9814,3,101000050
+9815,3,101000060
+9816,3,101000080
+9817,3,101000040
+9818,3,109000060
+9819,3,109000070
+9820,3,109000080
+9821,3,105000060
+9822,3,105000070
+9823,3,105000080
+9824,3,104000050
+9825,3,106000050
+9826,4,101000090
+9827,4,101000100
+9828,4,101000110
+9829,4,109000100
+9830,4,105000100
+9831,4,105000110
+9832,4,108000090
+9833,4,110000090
+9834,5,101000120
+9835,5,109000110
+9836,5,105000120
+9837,1,101000000
+9838,2,101000001
+9839,3,101000002
+9840,4,101000008
+9841,5,101000004
+9842,1,109000000
+9843,2,109000001
+9844,3,109000002
+9845,4,109000003
+9846,5,109000004
+9847,3,170004
+9848,4,170005
+9849,3,180004
+9850,4,180005
+9851,4,140000
+9852,4,150010
+9853,4,150020
+9854,4,150030
+9855,4,150040
+9857,3,102000060
+9858,3,102000070
+9859,3,102000080
+9860,3,103000050
+9861,3,105000050
+9862,3,107000060
+9863,3,107000070
+9864,3,107000080
+9865,3,108000050
+9866,3,109000050
+9867,3,103000060
+9868,3,103000070
+9869,3,103000080
+9870,3,110000050
+9871,4,102000100
+9872,4,102000350
+9873,4,102000110
+9874,4,106000090
+9875,4,109000090
+9876,4,107000100
+9877,4,103000090
+9878,4,102000090
+9879,4,103000100
+9880,5,102000120
+9881,5,107000110
+9882,5,103000120
+9883,1,102000000
+9884,2,102000001
+9885,3,102000002
+9886,4,102000003
+9887,5,102000004
+9888,1,105000000
+9889,2,105000001
+9890,3,105000002
+9891,4,105000003
+9892,5,105000004
+9893,1,112000000
+9894,2,112000001
+9895,3,112000002
+9896,4,112000003
+9897,5,112000004
+9898,4,110024
+9899,4,110034
+9900,4,110044
+9901,4,110054
+9902,3,110060
+9903,3,110070
+9904,3,110080
+9905,3,110090
+9906,3,110100
+9907,3,110110
+9908,3,110120
+9909,3,110130
+9910,3,110140
+9911,3,110150
+9912,3,110160
+9913,3,110170
+9914,3,110180
+9915,3,110190
+9916,3,110200
+9917,3,110210
+9918,3,110220
+9919,3,110230
+9920,3,110240
+9921,3,110250
+9922,3,110260
+9923,3,110270
+9924,3,110620
+9925,3,110670
+9926,4,140000
+9927,4,150010
+9928,4,150020
+9929,4,150030
+9930,4,150040
+9932,3,118000020
+9933,3,118000030
+9934,3,118000040
+9935,3,106000060
+9936,3,106000070
+9937,3,106000080
+9938,3,101000070
+9939,3,110000060
+9940,3,104000060
+9941,3,104000070
+9942,3,104000080
+9943,3,102000050
+9944,3,104000170
+9945,3,104000260
+9946,4,118000050
+9947,4,118000060
+9948,4,106000100
+9949,4,106000110
+9950,4,104000090
+9951,4,104000100
+9952,4,104000110
+9953,4,104000270
+9954,4,107000090
+9955,4,104000180
+9956,5,118000070
+9957,5,106000120
+9958,5,104000120
+9959,5,104000190
+9960,1,103000000
+9961,2,103000001
+9962,3,103000002
+9963,4,103000003
+9964,5,103000004
+9965,1,111000000
+9966,2,111000001
+9967,3,111000002
+9968,4,111000003
+9969,5,111000004
+9970,1,115000000
+9971,2,115000001
+9972,3,115000002
+9973,4,115000003
+9974,5,115000004
+9975,4,120024
+9976,4,120034
+9977,4,120044
+9978,4,120054
+9979,3,120241
+9980,3,120251
+9981,3,120261
+9982,3,120271
+9983,3,120300
+9984,3,120310
+9985,3,120320
+9986,3,120330
+9987,3,120340
+9988,3,120350
+9989,3,120360
+9990,3,120370
+9991,3,120380
+9992,3,120390
+9993,3,120400
+9994,3,120410
+9995,3,120420
+9996,3,120430
+9997,3,120450
+9998,3,120460
+9999,3,120550
+10000,3,120560
+10001,3,120570
+10002,3,120990
+10003,3,121000
+10004,3,121010
+10005,3,121020
+10006,4,140000
+10007,4,150010
+10008,4,150020
+10009,4,150030
+10010,4,150040
+10012,3,111000010
+10013,3,111000020
+10014,3,111000030
+10015,3,112000020
+10016,3,112000030
+10017,3,108000060
+10018,3,108000070
+10019,3,108000080
+10020,3,107000050
+10021,3,112000010
+10022,3,110000070
+10023,3,110000080
+10024,4,111000040
+10025,4,112000040
+10026,4,108000100
+10027,4,105000090
+10028,4,110000100
+10029,5,111000060
+10030,5,112000060
+10031,5,108000110
+10032,5,110000110
+10033,1,108000000
+10034,2,108000001
+10035,3,108000002
+10036,4,108000003
+10037,5,108000004
+10038,1,107000000
+10039,2,107000001
+10040,3,107000002
+10041,4,107000003
+10042,5,107000004
+10043,1,120000000
+10044,2,120000001
+10045,3,120000002
+10046,4,120000003
+10047,5,120000004
+10048,4,130024
+10049,4,130034
+10050,4,130044
+10051,4,130054
+10052,3,130060
+10053,3,130070
+10054,3,130080
+10055,3,130090
+10056,3,130100
+10057,3,130110
+10058,3,130120
+10059,3,130130
+10060,3,130140
+10061,3,130150
+10062,3,130160
+10063,3,130170
+10064,3,130180
+10065,3,130190
+10066,3,130200
+10067,3,130420
+10068,3,130510
+10069,3,130520
+10070,3,130531
+10071,3,130540
+10072,3,130660
+10073,3,130790
+10074,3,130800
+10075,3,131130
+10076,4,140000
+10077,4,150010
+10078,4,150020
+10079,4,150030
+10080,4,150040
+10082,3,111000010
+10083,3,111000020
+10084,3,111000030
+10085,3,112000020
+10086,3,112000030
+10087,3,108000060
+10088,3,108000070
+10089,3,108000080
+10090,3,107000050
+10091,3,112000010
+10092,3,110000070
+10093,3,110000080
+10094,4,111000040
+10095,4,112000040
+10096,4,108000100
+10097,4,105000090
+10098,4,110000100
+10099,5,111000060
+10100,5,112000060
+10101,5,108000110
+10102,5,110000110
+10103,1,108000000
+10104,2,108000001
+10105,3,108000002
+10106,4,108000003
+10107,5,108000004
+10108,1,107000000
+10109,2,107000001
+10110,3,107000002
+10111,4,107000003
+10112,5,107000004
+10113,1,120000000
+10114,2,120000001
+10115,3,120000002
+10116,4,120000003
+10117,5,120000004
+10118,3,170004
+10119,4,170005
+10120,3,180004
+10121,4,180005
+10122,4,140000
+10123,4,150010
+10124,4,150020
+10125,4,150030
+10126,4,150040
+10128,3,101000050
+10129,3,101000060
+10130,3,101000080
+10131,3,101000040
+10132,3,109000060
+10133,3,109000070
+10134,3,109000080
+10135,3,105000060
+10136,3,105000070
+10137,3,105000080
+10138,3,104000050
+10139,3,106000050
+10140,4,101000090
+10141,4,101000100
+10142,4,101000110
+10143,4,109000100
+10144,4,105000100
+10145,4,105000110
+10146,4,108000090
+10147,4,110000090
+10148,5,101000120
+10149,5,109000110
+10150,5,105000120
+10151,1,101000000
+10152,2,101000001
+10153,3,101000002
+10154,4,101000008
+10155,5,101000004
+10156,1,109000000
+10157,2,109000001
+10158,3,109000002
+10159,4,109000003
+10160,5,109000004
+10161,4,110024
+10162,4,110034
+10163,4,110044
+10164,4,110054
+10165,3,110060
+10166,3,110070
+10167,3,110080
+10168,3,110090
+10169,3,110100
+10170,3,110110
+10171,3,110120
+10172,3,110130
+10173,3,110140
+10174,3,110150
+10175,3,110160
+10176,3,110170
+10177,3,110180
+10178,3,110190
+10179,3,110200
+10180,3,110210
+10181,3,110220
+10182,3,110230
+10183,3,110240
+10184,3,110250
+10185,3,110260
+10186,3,110270
+10187,3,110620
+10188,3,110670
+10189,4,140000
+10190,4,150010
+10191,4,150020
+10192,4,150030
+10193,4,150040
+10195,3,102000060
+10196,3,102000070
+10197,3,102000080
+10198,3,103000050
+10199,3,105000050
+10200,3,107000060
+10201,3,107000070
+10202,3,107000080
+10203,3,108000050
+10204,3,109000050
+10205,3,103000060
+10206,3,103000070
+10207,3,103000080
+10208,3,110000050
+10209,4,102000100
+10210,4,102000110
+10211,4,102000350
+10212,4,106000090
+10213,4,109000090
+10214,4,107000100
+10215,4,103000090
+10216,4,102000090
+10217,4,103000100
+10218,5,102000120
+10219,5,107000110
+10220,5,103000120
+10221,1,102000000
+10222,2,102000001
+10223,3,102000002
+10224,4,102000003
+10225,5,102000004
+10226,1,105000000
+10227,2,105000001
+10228,3,105000002
+10229,4,105000003
+10230,5,105000004
+10231,1,112000000
+10232,2,112000001
+10233,3,112000002
+10234,4,112000003
+10235,5,112000004
+10236,4,120024
+10237,4,120034
+10238,4,120044
+10239,4,120054
+10240,3,120241
+10241,3,120251
+10242,3,120261
+10243,3,120271
+10244,3,120300
+10245,3,120310
+10246,3,120320
+10247,3,120330
+10248,3,120340
+10249,3,120350
+10250,3,120360
+10251,3,120370
+10252,3,120380
+10253,3,120390
+10254,3,120400
+10255,3,120410
+10256,3,120420
+10257,3,120430
+10258,3,120450
+10259,3,120460
+10260,3,120550
+10261,3,120560
+10262,3,120570
+10263,3,120990
+10264,3,121000
+10265,3,121010
+10266,3,121020
+10267,3,121100
+10268,4,140000
+10269,4,150010
+10270,4,150020
+10271,4,150030
+10272,4,150040
+10274,3,118000020
+10275,3,118000030
+10276,3,118000040
+10277,3,106000060
+10278,3,106000070
+10279,3,106000080
+10280,3,101000070
+10281,3,110000060
+10282,3,104000060
+10283,3,104000070
+10284,3,104000080
+10285,3,102000050
+10286,3,104000170
+10287,3,104000260
+10288,4,118000050
+10289,4,118000060
+10290,4,106000100
+10291,4,106000110
+10292,4,104000090
+10293,4,104000100
+10294,4,104000110
+10295,4,104000270
+10296,4,107000090
+10297,4,104000180
+10298,5,118000070
+10299,5,106000120
+10300,5,104000120
+10301,5,104000190
+10302,1,103000000
+10303,2,103000001
+10304,3,103000002
+10305,4,103000003
+10306,5,103000004
+10307,1,111000000
+10308,2,111000001
+10309,3,111000002
+10310,4,111000003
+10311,5,111000004
+10312,1,115000000
+10313,2,115000001
+10314,3,115000002
+10315,4,115000003
+10316,5,115000004
+10317,4,130024
+10318,4,130034
+10319,4,130044
+10320,4,130054
+10321,3,130060
+10322,3,130070
+10323,3,130080
+10324,3,130090
+10325,3,130100
+10326,3,130110
+10327,3,130120
+10328,3,130130
+10329,3,130140
+10330,3,130150
+10331,3,130160
+10332,3,130170
+10333,3,130180
+10334,3,130190
+10335,3,130200
+10336,3,130420
+10337,3,130510
+10338,3,130520
+10339,3,130531
+10340,3,130540
+10341,3,130660
+10342,3,130790
+10343,3,130800
+10344,3,131130
+10345,4,140000
+10346,4,150010
+10347,4,150020
+10348,4,150030
+10349,4,150040
+10351,1,101000010
+10352,1,102000010
+10353,1,103000010
+10354,1,104000010
+10355,1,105000010
+10356,1,106000010
+10357,1,107000010
+10358,1,108000010
+10359,1,109000010
+10360,1,110000010
+10361,2,101000020
+10362,2,101000030
+10363,2,102000020
+10364,2,102000030
+10365,2,102000040
+10366,2,103000020
+10367,2,103000030
+10368,2,103000040
+10369,2,104000020
+10370,2,104000030
+10371,2,104000040
+10372,2,105000020
+10373,2,105000030
+10374,2,105000040
+10375,2,106000020
+10376,2,106000030
+10377,2,106000040
+10378,2,107000020
+10379,2,107000030
+10380,2,107000040
+10381,2,108000020
+10382,2,108000030
+10383,2,108000040
+10384,2,109000020
+10385,2,109000030
+10386,2,109000040
+10387,2,110000020
+10388,2,110000030
+10389,2,110000040
+10390,2,118000010
+10391,3,101000050
+10392,3,101000060
+10393,3,101000080
+10394,3,101000040
+10395,3,109000060
+10396,3,109000070
+10397,3,109000080
+10398,3,105000060
+10399,3,105000070
+10400,3,105000080
+10401,3,104000050
+10402,3,106000050
+10403,3,102000060
+10404,3,102000070
+10405,3,102000080
+10406,3,103000050
+10407,3,105000050
+10408,3,107000060
+10409,3,107000070
+10410,3,107000080
+10411,3,108000050
+10412,3,109000050
+10413,3,103000060
+10414,3,103000070
+10415,3,103000080
+10416,3,110000050
+10417,3,106000060
+10418,3,106000070
+10419,3,106000080
+10420,3,101000070
+10421,3,110000060
+10422,3,104000060
+10423,3,104000070
+10424,3,104000080
+10425,3,102000050
+10426,3,104000170
+10427,3,104000260
+10428,3,111000010
+10429,3,111000020
+10430,3,111000030
+10431,3,112000020
+10432,3,112000030
+10433,3,108000060
+10434,3,108000070
+10435,3,108000080
+10436,3,107000050
+10437,3,112000010
+10438,3,110000070
+10439,3,110000080
+10440,3,118000020
+10441,3,118000030
+10442,3,118000040
+10443,4,101000090
+10444,4,101000100
+10445,4,101000110
+10446,4,109000100
+10447,4,105000100
+10448,4,105000110
+10449,4,108000090
+10450,4,110000090
+10451,4,102000100
+10452,4,102000110
+10453,4,106000090
+10454,4,109000090
+10455,4,107000100
+10456,4,103000090
+10457,4,102000090
+10458,4,103000100
+10459,4,106000100
+10460,4,106000110
+10461,4,104000090
+10462,4,104000100
+10463,4,104000110
+10464,4,107000090
+10465,4,104000180
+10466,4,111000040
+10467,4,112000040
+10468,4,108000100
+10469,4,105000090
+10470,4,110000100
+10471,4,118000050
+10472,4,118000060
+10473,5,101000120
+10474,5,109000110
+10475,5,105000120
+10476,5,102000120
+10477,5,107000110
+10478,5,103000120
+10479,5,106000120
+10480,5,104000120
+10481,5,104000190
+10482,5,111000060
+10483,5,112000060
+10484,5,108000110
+10485,5,110000110
+10486,5,118000070
+10487,1,201000010
+10488,1,292000010
+10489,1,299000040
+10490,1,299000070
+10491,1,299000110
+10492,1,299000120
+10493,1,299000140
+10494,2,202000010
+10495,2,290000010
+10496,2,299000010
+10497,2,299000150
+10498,2,299000190
+10499,2,299000200
+10500,2,299000210
+10501,3,298000050
+10502,3,298000060
+10503,3,299000060
+10504,3,299000170
+10505,3,290000120
+10506,3,291000050
+10507,3,292000020
+10508,4,299000670
+10509,4,299000680
+10510,4,204000010
+10511,4,209000040
+10512,4,202000070
+10513,5,297000100
+10514,5,291000020
+10515,5,297000130
+10516,5,297000140
+10517,5,203000010
+10518,5,206000030
+10519,5,203000050
+10520,1,170002
+10521,1,180002
+10522,2,170003
+10523,2,180003
+10524,3,170004
+10525,3,180004
+10526,4,140000
+10527,5,150010
+10528,5,150020
+10529,5,150030
+10530,5,150040
+10532,1,101000010
+10533,1,102000010
+10534,1,103000010
+10535,1,104000010
+10536,1,105000010
+10537,1,106000010
+10538,1,107000010
+10539,1,108000010
+10540,1,109000010
+10541,1,110000010
+10542,2,101000020
+10543,2,101000030
+10544,2,102000020
+10545,2,102000030
+10546,2,102000040
+10547,2,103000020
+10548,2,103000030
+10549,2,103000040
+10550,2,104000020
+10551,2,104000030
+10552,2,104000040
+10553,2,105000020
+10554,2,105000030
+10555,2,105000040
+10556,2,106000020
+10557,2,106000030
+10558,2,106000040
+10559,2,107000020
+10560,2,107000030
+10561,2,107000040
+10562,2,108000020
+10563,2,108000030
+10564,2,108000040
+10565,2,109000020
+10566,2,109000030
+10567,2,109000040
+10568,2,110000020
+10569,2,110000030
+10570,2,110000040
+10571,2,118000010
+10572,3,101000050
+10573,3,101000060
+10574,3,101000080
+10575,3,101000040
+10576,3,109000060
+10577,3,109000070
+10578,3,109000080
+10579,3,105000060
+10580,3,105000070
+10581,3,105000080
+10582,3,104000050
+10583,3,106000050
+10584,3,102000060
+10585,3,102000070
+10586,3,102000080
+10587,3,103000050
+10588,3,105000050
+10589,3,107000060
+10590,3,107000070
+10591,3,107000080
+10592,3,108000050
+10593,3,109000050
+10594,3,103000060
+10595,3,103000070
+10596,3,103000080
+10597,3,110000050
+10598,3,106000060
+10599,3,106000070
+10600,3,106000080
+10601,3,101000070
+10602,3,110000060
+10603,3,104000060
+10604,3,104000070
+10605,3,104000080
+10606,3,102000050
+10607,3,104000170
+10608,3,104000260
+10609,3,111000010
+10610,3,111000020
+10611,3,111000030
+10612,3,112000020
+10613,3,112000030
+10614,3,108000060
+10615,3,108000070
+10616,3,108000080
+10617,3,107000050
+10618,3,112000010
+10619,3,110000070
+10620,3,110000080
+10621,3,118000020
+10622,3,118000030
+10623,3,118000040
+10624,4,101000090
+10625,4,101000100
+10626,4,101000110
+10627,4,109000100
+10628,4,105000100
+10629,4,105000110
+10630,4,108000090
+10631,4,110000090
+10632,4,102000100
+10633,4,102000110
+10634,4,106000090
+10635,4,109000090
+10636,4,107000100
+10637,4,103000090
+10638,4,102000090
+10639,4,103000100
+10640,4,106000100
+10641,4,106000110
+10642,4,104000090
+10643,4,104000100
+10644,4,104000110
+10645,4,107000090
+10646,4,104000180
+10647,4,111000040
+10648,4,112000040
+10649,4,108000100
+10650,4,105000090
+10651,4,110000100
+10652,4,118000050
+10653,4,118000060
+10654,5,101000120
+10655,5,109000110
+10656,5,105000120
+10657,5,102000120
+10658,5,107000110
+10659,5,103000120
+10660,5,106000120
+10661,5,104000120
+10662,5,104000190
+10663,5,111000060
+10664,5,112000060
+10665,5,108000110
+10666,5,110000110
+10667,5,118000070
+10668,1,201000010
+10669,1,292000010
+10670,1,299000040
+10671,1,299000070
+10672,1,299000110
+10673,1,299000120
+10674,1,299000140
+10675,2,202000010
+10676,2,290000010
+10677,2,299000010
+10678,2,299000150
+10679,2,299000190
+10680,2,299000200
+10681,2,299000210
+10682,3,298000050
+10683,3,298000060
+10684,3,299000060
+10685,3,299000170
+10686,3,290000120
+10687,3,291000050
+10688,3,292000020
+10689,4,299000670
+10690,4,299000680
+10691,4,204000010
+10692,4,209000040
+10693,4,202000070
+10694,5,297000100
+10695,5,291000020
+10696,5,297000130
+10697,5,297000140
+10698,5,203000010
+10699,5,206000030
+10700,5,203000050
+10701,2,170003
+10702,2,180003
+10703,3,170004
+10704,3,180004
+10705,4,140000
+10706,5,150010
+10707,5,150020
+10708,5,150030
+10709,5,150040
+10711,3,101000050
+10712,3,101000060
+10713,3,101000080
+10714,3,101000040
+10715,3,109000060
+10716,3,109000070
+10717,3,109000080
+10718,3,105000060
+10719,3,105000070
+10720,3,105000080
+10721,3,104000050
+10722,3,106000050
+10723,3,102000060
+10724,3,102000070
+10725,3,102000080
+10726,3,103000050
+10727,3,105000050
+10728,3,107000060
+10729,3,107000070
+10730,3,107000080
+10731,3,108000050
+10732,3,109000050
+10733,3,103000060
+10734,3,103000070
+10735,3,103000080
+10736,3,110000050
+10737,3,106000060
+10738,3,106000070
+10739,3,106000080
+10740,3,101000070
+10741,3,110000060
+10742,3,104000060
+10743,3,104000070
+10744,3,104000080
+10745,3,102000050
+10746,3,104000170
+10747,3,104000260
+10748,3,111000010
+10749,3,111000020
+10750,3,111000030
+10751,3,112000020
+10752,3,112000030
+10753,3,108000060
+10754,3,108000070
+10755,3,108000080
+10756,3,107000050
+10757,3,112000010
+10758,3,110000070
+10759,3,110000080
+10760,3,118000020
+10761,3,118000030
+10762,3,118000040
+10763,4,101000090
+10764,4,101000100
+10765,4,101000110
+10766,4,109000100
+10767,4,105000100
+10768,4,105000110
+10769,4,108000090
+10770,4,110000090
+10771,4,102000100
+10772,4,102000110
+10773,4,106000090
+10774,4,109000090
+10775,4,107000100
+10776,4,103000090
+10777,4,102000090
+10778,4,103000100
+10779,4,106000100
+10780,4,106000110
+10781,4,104000090
+10782,4,104000100
+10783,4,104000110
+10784,4,107000090
+10785,4,104000180
+10786,4,111000040
+10787,4,112000040
+10788,4,108000100
+10789,4,105000090
+10790,4,110000100
+10791,4,118000050
+10792,4,118000060
+10793,5,101000120
+10794,5,109000110
+10795,5,105000120
+10796,5,102000120
+10797,5,107000110
+10798,5,103000120
+10799,5,106000120
+10800,5,104000120
+10801,5,104000190
+10802,5,111000060
+10803,5,112000060
+10804,5,108000110
+10805,5,110000110
+10806,5,118000070
+10807,1,201000010
+10808,1,292000010
+10809,1,299000040
+10810,1,299000070
+10811,1,299000110
+10812,1,299000120
+10813,1,299000140
+10814,2,202000010
+10815,2,290000010
+10816,2,299000010
+10817,2,299000150
+10818,2,299000190
+10819,2,299000200
+10820,2,299000210
+10821,3,298000050
+10822,3,298000060
+10823,3,299000060
+10824,3,299000170
+10825,3,290000120
+10826,3,291000050
+10827,3,292000020
+10828,4,299000670
+10829,4,299000680
+10830,4,204000010
+10831,4,209000040
+10832,4,202000070
+10833,5,297000100
+10834,5,291000020
+10835,5,297000130
+10836,5,297000140
+10837,5,203000010
+10838,5,206000030
+10839,5,203000050
+10840,3,170004
+10841,3,180004
+10842,4,140000
+10843,5,150010
+10844,5,150020
+10845,5,150030
+10846,5,150040
+10848,3,101000050
+10849,3,101000060
+10850,3,101000080
+10851,3,101000040
+10852,3,109000060
+10853,3,109000070
+10854,3,109000080
+10855,3,105000060
+10856,3,105000070
+10857,3,105000080
+10858,3,104000050
+10859,3,106000050
+10860,3,102000060
+10861,3,102000070
+10862,3,102000080
+10863,3,103000050
+10864,3,105000050
+10865,3,107000060
+10866,3,107000070
+10867,3,107000080
+10868,3,108000050
+10869,3,109000050
+10870,3,103000060
+10871,3,103000070
+10872,3,103000080
+10873,3,110000050
+10874,3,106000060
+10875,3,106000070
+10876,3,106000080
+10877,3,101000070
+10878,3,110000060
+10879,3,104000060
+10880,3,104000070
+10881,3,104000080
+10882,3,102000050
+10883,3,104000170
+10884,3,104000260
+10885,3,111000010
+10886,3,111000020
+10887,3,111000030
+10888,3,112000020
+10889,3,112000030
+10890,3,108000060
+10891,3,108000070
+10892,3,108000080
+10893,3,107000050
+10894,3,112000010
+10895,3,110000070
+10896,3,110000080
+10897,3,118000020
+10898,3,118000030
+10899,3,118000040
+10900,4,101000090
+10901,4,101000100
+10902,4,101000110
+10903,4,109000100
+10904,4,105000100
+10905,4,105000110
+10906,4,108000090
+10907,4,110000090
+10908,4,102000100
+10909,4,102000110
+10910,4,106000090
+10911,4,109000090
+10912,4,107000100
+10913,4,103000090
+10914,4,102000090
+10915,4,103000100
+10916,4,106000100
+10917,4,106000110
+10918,4,104000090
+10919,4,104000100
+10920,4,104000110
+10921,4,107000090
+10922,4,104000180
+10923,4,111000040
+10924,4,112000040
+10925,4,108000100
+10926,4,105000090
+10927,4,110000100
+10928,4,118000050
+10929,4,118000060
+10930,5,101000120
+10931,5,109000110
+10932,5,105000120
+10933,5,102000120
+10934,5,107000110
+10935,5,103000120
+10936,5,106000120
+10937,5,104000120
+10938,5,104000190
+10939,5,111000060
+10940,5,112000060
+10941,5,108000110
+10942,5,110000110
+10943,5,118000070
+10944,1,201000010
+10945,1,292000010
+10946,1,299000040
+10947,1,299000070
+10948,1,299000110
+10949,1,299000120
+10950,1,299000140
+10951,2,202000010
+10952,2,290000010
+10953,2,299000010
+10954,2,299000150
+10955,2,299000190
+10956,2,299000200
+10957,2,299000210
+10958,3,298000050
+10959,3,298000060
+10960,3,299000060
+10961,3,299000170
+10962,3,290000120
+10963,3,291000050
+10964,3,292000020
+10965,4,299000670
+10966,4,299000680
+10967,4,204000010
+10968,4,209000040
+10969,4,202000070
+10970,5,297000100
+10971,5,291000020
+10972,5,297000130
+10973,5,297000140
+10974,5,203000010
+10975,5,206000030
+10976,5,203000050
+10977,3,170004
+10978,3,180004
+10979,4,140000
+10980,5,150010
+10981,5,150020
+10982,5,150030
+10983,5,150040
+10985,3,101000050
+10986,3,101000060
+10987,3,101000080
+10988,3,101000040
+10989,3,109000060
+10990,3,109000070
+10991,3,109000080
+10992,3,105000060
+10993,3,105000070
+10994,3,105000080
+10995,3,104000050
+10996,3,106000050
+10997,3,102000060
+10998,3,102000070
+10999,3,102000080
+11000,3,103000050
+11001,3,105000050
+11002,3,107000060
+11003,3,107000070
+11004,3,107000080
+11005,3,108000050
+11006,3,109000050
+11007,3,103000060
+11008,3,103000070
+11009,3,103000080
+11010,3,110000050
+11011,3,106000060
+11012,3,106000070
+11013,3,106000080
+11014,3,101000070
+11015,3,110000060
+11016,3,104000060
+11017,3,104000070
+11018,3,104000080
+11019,3,102000050
+11020,3,104000170
+11021,3,104000260
+11022,3,111000010
+11023,3,111000020
+11024,3,111000030
+11025,3,112000020
+11026,3,112000030
+11027,3,108000060
+11028,3,108000070
+11029,3,108000080
+11030,3,107000050
+11031,3,112000010
+11032,3,110000070
+11033,3,110000080
+11034,3,118000020
+11035,3,118000030
+11036,3,118000040
+11037,4,101000090
+11038,4,101000100
+11039,4,101000110
+11040,4,109000100
+11041,4,105000100
+11042,4,105000110
+11043,4,108000090
+11044,4,110000090
+11045,4,102000100
+11046,4,102000110
+11047,4,106000090
+11048,4,109000090
+11049,4,107000100
+11050,4,103000090
+11051,4,102000090
+11052,4,103000100
+11053,4,106000100
+11054,4,106000110
+11055,4,104000090
+11056,4,104000100
+11057,4,104000110
+11058,4,107000090
+11059,4,104000180
+11060,4,111000040
+11061,4,112000040
+11062,4,108000100
+11063,4,105000090
+11064,4,110000100
+11065,4,118000050
+11066,4,118000060
+11067,5,101000120
+11068,5,109000110
+11069,5,105000120
+11070,5,102000120
+11071,5,107000110
+11072,5,103000120
+11073,5,106000120
+11074,5,104000120
+11075,5,104000190
+11076,5,111000060
+11077,5,112000060
+11078,5,108000110
+11079,5,110000110
+11080,5,118000070
+11081,1,201000010
+11082,1,292000010
+11083,1,299000040
+11084,1,299000070
+11085,1,299000110
+11086,1,299000120
+11087,1,299000140
+11088,2,202000010
+11089,2,290000010
+11090,2,299000010
+11091,2,299000150
+11092,2,299000190
+11093,2,299000200
+11094,2,299000210
+11095,3,298000050
+11096,3,298000060
+11097,3,299000060
+11098,3,299000170
+11099,3,290000120
+11100,3,291000050
+11101,3,292000020
+11102,4,299000670
+11103,4,299000680
+11104,4,204000010
+11105,4,209000040
+11106,4,202000070
+11107,5,297000100
+11108,5,291000020
+11109,5,297000130
+11110,5,297000140
+11111,5,203000010
+11112,5,206000030
+11113,5,203000050
+11114,3,170004
+11115,3,180004
+11116,4,140000
+11117,5,150010
+11118,5,150020
+11119,5,150030
+11120,5,150040
+11121,5,190000
+11122,5,200000
+11123,5,210000
+11125,3,118000020
+11126,3,118000030
+11127,3,118000040
+11128,3,106000060
+11129,3,106000070
+11130,3,106000080
+11131,3,101000070
+11132,3,110000060
+11133,3,104000060
+11134,3,104000070
+11135,3,104000080
+11136,3,102000050
+11137,3,104000170
+11138,3,104000260
+11139,4,118000050
+11140,4,118000060
+11141,4,106000100
+11142,4,106000110
+11143,4,104000090
+11144,4,104000100
+11145,4,104000110
+11146,4,104000270
+11147,4,107000090
+11148,4,104000180
+11149,5,118000070
+11150,5,106000120
+11151,5,104000120
+11152,5,104000190
+11153,1,103000000
+11154,2,103000001
+11155,3,103000002
+11156,4,103000003
+11157,5,103000004
+11158,1,111000000
+11159,2,111000001
+11160,3,111000002
+11161,4,111000003
+11162,5,111000004
+11163,1,115000000
+11164,2,115000001
+11165,3,115000002
+11166,4,115000003
+11167,5,115000004
+11168,3,170004
+11169,4,170005
+11170,3,180004
+11171,4,180005
+11172,4,140000
+11173,4,150010
+11174,4,150020
+11175,4,150030
+11176,4,150040
+11178,3,111000010
+11179,3,111000020
+11180,3,111000030
+11181,3,112000020
+11182,3,112000030
+11183,3,108000060
+11184,3,108000070
+11185,3,108000080
+11186,3,107000050
+11187,3,112000010
+11188,3,110000070
+11189,3,110000080
+11190,4,111000040
+11191,4,112000040
+11192,4,108000100
+11193,4,105000090
+11194,4,110000100
+11195,5,111000060
+11196,5,112000060
+11197,5,108000110
+11198,5,110000110
+11199,1,108000000
+11200,2,108000001
+11201,3,108000002
+11202,4,108000003
+11203,5,108000004
+11204,1,107000000
+11205,2,107000001
+11206,3,107000002
+11207,4,107000003
+11208,5,107000004
+11209,1,120000000
+11210,2,120000001
+11211,3,120000002
+11212,4,120000003
+11213,5,120000004
+11214,4,110024
+11215,4,110034
+11216,4,110044
+11217,4,110054
+11218,3,110060
+11219,3,110070
+11220,3,110080
+11221,3,110090
+11222,3,110100
+11223,3,110110
+11224,3,110120
+11225,3,110130
+11226,3,110140
+11227,3,110150
+11228,3,110160
+11229,3,110170
+11230,3,110180
+11231,3,110190
+11232,3,110200
+11233,3,110210
+11234,3,110220
+11235,3,110230
+11236,3,110240
+11237,3,110250
+11238,3,110260
+11239,3,110270
+11240,3,110620
+11241,3,110670
+11242,4,140000
+11243,4,150010
+11244,4,150020
+11245,4,150030
+11246,4,150040
+11248,3,101000050
+11249,3,101000060
+11250,3,101000080
+11251,3,101000040
+11252,3,109000060
+11253,3,109000070
+11254,3,109000080
+11255,3,105000060
+11256,3,105000070
+11257,3,105000080
+11258,3,104000050
+11259,3,106000050
+11260,4,101000090
+11261,4,101000100
+11262,4,101000110
+11263,4,109000100
+11264,4,105000100
+11265,4,105000110
+11266,4,108000090
+11267,4,110000090
+11268,5,101000120
+11269,5,109000110
+11270,5,105000120
+11271,1,101000000
+11272,2,101000001
+11273,3,101000002
+11274,4,101000008
+11275,5,101000004
+11276,1,109000000
+11277,2,109000001
+11278,3,109000002
+11279,4,109000003
+11280,5,109000004
+11281,4,120024
+11282,4,120034
+11283,4,120044
+11284,4,120054
+11285,3,120241
+11286,3,120251
+11287,3,120261
+11288,3,120271
+11289,3,120300
+11290,3,120310
+11291,3,120320
+11292,3,120330
+11293,3,120340
+11294,3,120350
+11295,3,120360
+11296,3,120370
+11297,3,120380
+11298,3,120390
+11299,3,120400
+11300,3,120410
+11301,3,120420
+11302,3,120430
+11303,3,120450
+11304,3,120460
+11305,3,120550
+11306,3,120560
+11307,3,120570
+11308,3,120990
+11309,3,121000
+11310,3,121010
+11311,3,121020
+11312,3,121100
+11313,4,140000
+11314,4,150010
+11315,4,150020
+11316,4,150030
+11317,4,150040
+11319,3,102000060
+11320,3,102000070
+11321,3,102000080
+11322,3,103000050
+11323,3,105000050
+11324,3,107000060
+11325,3,107000070
+11326,3,107000080
+11327,3,108000050
+11328,3,109000050
+11329,3,103000060
+11330,3,103000070
+11331,3,103000080
+11332,3,110000050
+11333,4,102000100
+11334,4,102000110
+11335,4,102000350
+11336,4,106000090
+11337,4,109000090
+11338,4,107000100
+11339,4,103000090
+11340,4,102000090
+11341,4,103000100
+11342,5,102000120
+11343,5,107000110
+11344,5,103000120
+11345,1,102000000
+11346,2,102000001
+11347,3,102000002
+11348,4,102000003
+11349,5,102000004
+11350,1,105000000
+11351,2,105000001
+11352,3,105000002
+11353,4,105000003
+11354,5,105000004
+11355,1,112000000
+11356,2,112000001
+11357,3,112000002
+11358,4,112000003
+11359,5,112000004
+11360,4,130024
+11361,4,130034
+11362,4,130044
+11363,4,130054
+11364,3,130060
+11365,3,130070
+11366,3,130080
+11367,3,130090
+11368,3,130100
+11369,3,130110
+11370,3,130120
+11371,3,130130
+11372,3,130140
+11373,3,130150
+11374,3,130160
+11375,3,130170
+11376,3,130180
+11377,3,130190
+11378,3,130200
+11379,3,130420
+11380,3,130510
+11381,3,130520
+11382,3,130531
+11383,3,130540
+11384,3,130660
+11385,3,130790
+11386,3,130800
+11387,3,131130
+11388,4,140000
+11389,4,150010
+11390,4,150020
+11391,4,150030
+11392,4,150040
+11394,1,101000010
+11395,1,102000010
+11396,1,103000010
+11397,1,104000010
+11398,1,105000010
+11399,1,106000010
+11400,1,107000010
+11401,1,108000010
+11402,1,109000010
+11403,1,110000010
+11404,2,101000020
+11405,2,101000030
+11406,2,102000020
+11407,2,102000030
+11408,2,102000040
+11409,2,103000020
+11410,2,103000030
+11411,2,103000040
+11412,2,104000020
+11413,2,104000030
+11414,2,104000040
+11415,2,105000020
+11416,2,105000030
+11417,2,105000040
+11418,2,106000020
+11419,2,106000030
+11420,2,106000040
+11421,2,107000020
+11422,2,107000030
+11423,2,107000040
+11424,2,108000020
+11425,2,108000030
+11426,2,108000040
+11427,2,109000020
+11428,2,109000030
+11429,2,109000040
+11430,2,110000020
+11431,2,110000030
+11432,2,110000040
+11433,2,118000010
+11434,3,101000050
+11435,3,101000060
+11436,3,101000080
+11437,3,101000040
+11438,3,109000060
+11439,3,109000070
+11440,3,109000080
+11441,3,105000060
+11442,3,105000070
+11443,3,105000080
+11444,3,104000050
+11445,3,106000050
+11446,3,102000060
+11447,3,102000070
+11448,3,102000080
+11449,3,103000050
+11450,3,105000050
+11451,3,107000060
+11452,3,107000070
+11453,3,107000080
+11454,3,108000050
+11455,3,109000050
+11456,3,103000060
+11457,3,103000070
+11458,3,103000080
+11459,3,110000050
+11460,3,106000060
+11461,3,106000070
+11462,3,106000080
+11463,3,101000070
+11464,3,110000060
+11465,3,104000060
+11466,3,104000070
+11467,3,104000080
+11468,3,102000050
+11469,3,104000170
+11470,3,104000260
+11471,3,111000010
+11472,3,111000020
+11473,3,111000030
+11474,3,112000020
+11475,3,112000030
+11476,3,108000060
+11477,3,108000070
+11478,3,108000080
+11479,3,107000050
+11480,3,112000010
+11481,3,110000070
+11482,3,110000080
+11483,3,118000020
+11484,3,118000030
+11485,3,118000040
+11486,4,101000090
+11487,4,101000100
+11488,4,101000110
+11489,4,109000100
+11490,4,105000100
+11491,4,105000110
+11492,4,108000090
+11493,4,110000090
+11494,4,102000100
+11495,4,102000110
+11496,4,106000090
+11497,4,109000090
+11498,4,107000100
+11499,4,103000090
+11500,4,102000090
+11501,4,103000100
+11502,4,106000100
+11503,4,106000110
+11504,4,104000090
+11505,4,104000100
+11506,4,104000110
+11507,4,107000090
+11508,4,104000180
+11509,4,111000040
+11510,4,112000040
+11511,4,108000100
+11512,4,105000090
+11513,4,110000100
+11514,4,118000050
+11515,4,118000060
+11516,5,101000120
+11517,5,109000110
+11518,5,105000120
+11519,5,102000120
+11520,5,107000110
+11521,5,103000120
+11522,5,106000120
+11523,5,104000120
+11524,5,104000190
+11525,5,111000060
+11526,5,112000060
+11527,5,108000110
+11528,5,110000110
+11529,5,118000070
+11530,1,201000010
+11531,1,292000010
+11532,1,299000040
+11533,1,299000070
+11534,1,299000110
+11535,1,299000120
+11536,1,299000140
+11537,2,202000010
+11538,2,290000010
+11539,2,299000010
+11540,2,299000150
+11541,2,299000190
+11542,2,299000200
+11543,2,299000210
+11544,3,298000050
+11545,3,298000060
+11546,3,299000060
+11547,3,299000170
+11548,3,290000120
+11549,3,291000050
+11550,3,292000020
+11551,4,299000670
+11552,4,299000680
+11553,4,204000010
+11554,4,209000040
+11555,4,202000070
+11556,4,209000070
+11557,5,297000100
+11558,5,291000020
+11559,5,297000130
+11560,5,297000140
+11561,5,203000010
+11562,5,206000030
+11563,5,203000050
+11564,5,202000090
+11565,1,170002
+11566,1,180002
+11567,2,170003
+11568,2,180003
+11569,3,170004
+11570,3,180004
+11571,4,140000
+11572,5,150010
+11573,5,150020
+11574,5,150030
+11575,5,150040
+11577,1,101000010
+11578,1,102000010
+11579,1,103000010
+11580,1,104000010
+11581,1,105000010
+11582,1,106000010
+11583,1,107000010
+11584,1,108000010
+11585,1,109000010
+11586,1,110000010
+11587,2,101000020
+11588,2,101000030
+11589,2,102000020
+11590,2,102000030
+11591,2,102000040
+11592,2,103000020
+11593,2,103000030
+11594,2,103000040
+11595,2,104000020
+11596,2,104000030
+11597,2,104000040
+11598,2,105000020
+11599,2,105000030
+11600,2,105000040
+11601,2,106000020
+11602,2,106000030
+11603,2,106000040
+11604,2,107000020
+11605,2,107000030
+11606,2,107000040
+11607,2,108000020
+11608,2,108000030
+11609,2,108000040
+11610,2,109000020
+11611,2,109000030
+11612,2,109000040
+11613,2,110000020
+11614,2,110000030
+11615,2,110000040
+11616,2,118000010
+11617,3,101000050
+11618,3,101000060
+11619,3,101000080
+11620,3,101000040
+11621,3,109000060
+11622,3,109000070
+11623,3,109000080
+11624,3,105000060
+11625,3,105000070
+11626,3,105000080
+11627,3,104000050
+11628,3,106000050
+11629,3,102000060
+11630,3,102000070
+11631,3,102000080
+11632,3,103000050
+11633,3,105000050
+11634,3,107000060
+11635,3,107000070
+11636,3,107000080
+11637,3,108000050
+11638,3,109000050
+11639,3,103000060
+11640,3,103000070
+11641,3,103000080
+11642,3,110000050
+11643,3,106000060
+11644,3,106000070
+11645,3,106000080
+11646,3,101000070
+11647,3,110000060
+11648,3,104000060
+11649,3,104000070
+11650,3,104000080
+11651,3,102000050
+11652,3,104000170
+11653,3,104000260
+11654,3,111000010
+11655,3,111000020
+11656,3,111000030
+11657,3,112000020
+11658,3,112000030
+11659,3,108000060
+11660,3,108000070
+11661,3,108000080
+11662,3,107000050
+11663,3,112000010
+11664,3,110000070
+11665,3,110000080
+11666,3,118000020
+11667,3,118000030
+11668,3,118000040
+11669,4,101000090
+11670,4,101000100
+11671,4,101000110
+11672,4,109000100
+11673,4,105000100
+11674,4,105000110
+11675,4,108000090
+11676,4,110000090
+11677,4,102000100
+11678,4,102000110
+11679,4,106000090
+11680,4,109000090
+11681,4,107000100
+11682,4,103000090
+11683,4,102000090
+11684,4,103000100
+11685,4,106000100
+11686,4,106000110
+11687,4,104000090
+11688,4,104000100
+11689,4,104000110
+11690,4,107000090
+11691,4,104000180
+11692,4,111000040
+11693,4,112000040
+11694,4,108000100
+11695,4,105000090
+11696,4,110000100
+11697,4,118000050
+11698,4,118000060
+11699,5,101000120
+11700,5,109000110
+11701,5,105000120
+11702,5,102000120
+11703,5,107000110
+11704,5,103000120
+11705,5,106000120
+11706,5,104000120
+11707,5,104000190
+11708,5,111000060
+11709,5,112000060
+11710,5,108000110
+11711,5,110000110
+11712,5,118000070
+11713,1,201000010
+11714,1,292000010
+11715,1,299000040
+11716,1,299000070
+11717,1,299000110
+11718,1,299000120
+11719,1,299000140
+11720,2,202000010
+11721,2,290000010
+11722,2,299000010
+11723,2,299000150
+11724,2,299000190
+11725,2,299000200
+11726,2,299000210
+11727,3,298000050
+11728,3,298000060
+11729,3,299000060
+11730,3,299000170
+11731,3,290000120
+11732,3,291000050
+11733,3,292000020
+11734,4,299000670
+11735,4,299000680
+11736,4,204000010
+11737,4,209000040
+11738,4,202000070
+11739,4,209000070
+11740,5,297000100
+11741,5,291000020
+11742,5,297000130
+11743,5,297000140
+11744,5,203000010
+11745,5,206000030
+11746,5,203000050
+11747,5,202000090
+11748,2,170003
+11749,2,180003
+11750,3,170004
+11751,3,180004
+11752,4,140000
+11753,5,150010
+11754,5,150020
+11755,5,150030
+11756,5,150040
+11758,3,101000050
+11759,3,101000060
+11760,3,101000080
+11761,3,101000040
+11762,3,109000060
+11763,3,109000070
+11764,3,109000080
+11765,3,105000060
+11766,3,105000070
+11767,3,105000080
+11768,3,104000050
+11769,3,106000050
+11770,3,102000060
+11771,3,102000070
+11772,3,102000080
+11773,3,103000050
+11774,3,105000050
+11775,3,107000060
+11776,3,107000070
+11777,3,107000080
+11778,3,108000050
+11779,3,109000050
+11780,3,103000060
+11781,3,103000070
+11782,3,103000080
+11783,3,110000050
+11784,3,106000060
+11785,3,106000070
+11786,3,106000080
+11787,3,101000070
+11788,3,110000060
+11789,3,104000060
+11790,3,104000070
+11791,3,104000080
+11792,3,102000050
+11793,3,104000170
+11794,3,104000260
+11795,3,111000010
+11796,3,111000020
+11797,3,111000030
+11798,3,112000020
+11799,3,112000030
+11800,3,108000060
+11801,3,108000070
+11802,3,108000080
+11803,3,107000050
+11804,3,112000010
+11805,3,110000070
+11806,3,110000080
+11807,3,118000020
+11808,3,118000030
+11809,3,118000040
+11810,4,101000090
+11811,4,101000100
+11812,4,101000110
+11813,4,109000100
+11814,4,105000100
+11815,4,105000110
+11816,4,108000090
+11817,4,110000090
+11818,4,102000100
+11819,4,102000110
+11820,4,106000090
+11821,4,109000090
+11822,4,107000100
+11823,4,103000090
+11824,4,102000090
+11825,4,103000100
+11826,4,106000100
+11827,4,106000110
+11828,4,104000090
+11829,4,104000100
+11830,4,104000110
+11831,4,107000090
+11832,4,104000180
+11833,4,111000040
+11834,4,112000040
+11835,4,108000100
+11836,4,105000090
+11837,4,110000100
+11838,4,118000050
+11839,4,118000060
+11840,5,101000120
+11841,5,109000110
+11842,5,105000120
+11843,5,102000120
+11844,5,107000110
+11845,5,103000120
+11846,5,106000120
+11847,5,104000120
+11848,5,104000190
+11849,5,111000060
+11850,5,112000060
+11851,5,108000110
+11852,5,110000110
+11853,5,118000070
+11854,1,201000010
+11855,1,292000010
+11856,1,299000040
+11857,1,299000070
+11858,1,299000110
+11859,1,299000120
+11860,1,299000140
+11861,2,202000010
+11862,2,290000010
+11863,2,299000010
+11864,2,299000150
+11865,2,299000190
+11866,2,299000200
+11867,2,299000210
+11868,3,298000050
+11869,3,298000060
+11870,3,299000060
+11871,3,299000170
+11872,3,290000120
+11873,3,291000050
+11874,3,292000020
+11875,4,299000670
+11876,4,299000680
+11877,4,204000010
+11878,4,209000040
+11879,4,202000070
+11880,4,209000070
+11881,5,297000100
+11882,5,291000020
+11883,5,297000130
+11884,5,297000140
+11885,5,203000010
+11886,5,206000030
+11887,5,203000050
+11888,5,202000090
+11889,3,170004
+11890,3,180004
+11891,4,140000
+11892,5,150010
+11893,5,150020
+11894,5,150030
+11895,5,150040
+11897,3,101000050
+11898,3,101000060
+11899,3,101000080
+11900,3,101000040
+11901,3,109000060
+11902,3,109000070
+11903,3,109000080
+11904,3,105000060
+11905,3,105000070
+11906,3,105000080
+11907,3,104000050
+11908,3,106000050
+11909,3,102000060
+11910,3,102000070
+11911,3,102000080
+11912,3,103000050
+11913,3,105000050
+11914,3,107000060
+11915,3,107000070
+11916,3,107000080
+11917,3,108000050
+11918,3,109000050
+11919,3,103000060
+11920,3,103000070
+11921,3,103000080
+11922,3,110000050
+11923,3,106000060
+11924,3,106000070
+11925,3,106000080
+11926,3,101000070
+11927,3,110000060
+11928,3,104000060
+11929,3,104000070
+11930,3,104000080
+11931,3,102000050
+11932,3,104000170
+11933,3,104000260
+11934,3,111000010
+11935,3,111000020
+11936,3,111000030
+11937,3,112000020
+11938,3,112000030
+11939,3,108000060
+11940,3,108000070
+11941,3,108000080
+11942,3,107000050
+11943,3,112000010
+11944,3,110000070
+11945,3,110000080
+11946,3,118000020
+11947,3,118000030
+11948,3,118000040
+11949,4,101000090
+11950,4,101000100
+11951,4,101000110
+11952,4,109000100
+11953,4,105000100
+11954,4,105000110
+11955,4,108000090
+11956,4,110000090
+11957,4,102000100
+11958,4,102000110
+11959,4,106000090
+11960,4,109000090
+11961,4,107000100
+11962,4,103000090
+11963,4,102000090
+11964,4,103000100
+11965,4,106000100
+11966,4,106000110
+11967,4,104000090
+11968,4,104000100
+11969,4,104000110
+11970,4,107000090
+11971,4,104000180
+11972,4,111000040
+11973,4,112000040
+11974,4,108000100
+11975,4,105000090
+11976,4,110000100
+11977,4,118000050
+11978,4,118000060
+11979,5,101000120
+11980,5,109000110
+11981,5,105000120
+11982,5,102000120
+11983,5,107000110
+11984,5,103000120
+11985,5,106000120
+11986,5,104000120
+11987,5,104000190
+11988,5,111000060
+11989,5,112000060
+11990,5,108000110
+11991,5,110000110
+11992,5,118000070
+11993,1,201000010
+11994,1,292000010
+11995,1,299000040
+11996,1,299000070
+11997,1,299000110
+11998,1,299000120
+11999,1,299000140
+12000,2,202000010
+12001,2,290000010
+12002,2,299000010
+12003,2,299000150
+12004,2,299000190
+12005,2,299000200
+12006,2,299000210
+12007,3,298000050
+12008,3,298000060
+12009,3,299000060
+12010,3,299000170
+12011,3,290000120
+12012,3,291000050
+12013,3,292000020
+12014,4,299000670
+12015,4,299000680
+12016,4,204000010
+12017,4,209000040
+12018,4,202000070
+12019,4,209000070
+12020,5,297000100
+12021,5,291000020
+12022,5,297000130
+12023,5,297000140
+12024,5,203000010
+12025,5,206000030
+12026,5,203000050
+12027,5,202000090
+12028,3,170004
+12029,3,180004
+12030,4,140000
+12031,5,150010
+12032,5,150020
+12033,5,150030
+12034,5,150040
+12036,3,101000050
+12037,3,101000060
+12038,3,101000080
+12039,3,101000040
+12040,3,109000060
+12041,3,109000070
+12042,3,109000080
+12043,3,105000060
+12044,3,105000070
+12045,3,105000080
+12046,3,104000050
+12047,3,106000050
+12048,3,102000060
+12049,3,102000070
+12050,3,102000080
+12051,3,103000050
+12052,3,105000050
+12053,3,107000060
+12054,3,107000070
+12055,3,107000080
+12056,3,108000050
+12057,3,109000050
+12058,3,103000060
+12059,3,103000070
+12060,3,103000080
+12061,3,110000050
+12062,3,106000060
+12063,3,106000070
+12064,3,106000080
+12065,3,101000070
+12066,3,110000060
+12067,3,104000060
+12068,3,104000070
+12069,3,104000080
+12070,3,102000050
+12071,3,104000170
+12072,3,104000260
+12073,3,111000010
+12074,3,111000020
+12075,3,111000030
+12076,3,112000020
+12077,3,112000030
+12078,3,108000060
+12079,3,108000070
+12080,3,108000080
+12081,3,107000050
+12082,3,112000010
+12083,3,110000070
+12084,3,110000080
+12085,3,118000020
+12086,3,118000030
+12087,3,118000040
+12088,4,101000090
+12089,4,101000100
+12090,4,101000110
+12091,4,109000100
+12092,4,105000100
+12093,4,105000110
+12094,4,108000090
+12095,4,110000090
+12096,4,102000100
+12097,4,102000110
+12098,4,106000090
+12099,4,109000090
+12100,4,107000100
+12101,4,103000090
+12102,4,102000090
+12103,4,103000100
+12104,4,106000100
+12105,4,106000110
+12106,4,104000090
+12107,4,104000100
+12108,4,104000110
+12109,4,107000090
+12110,4,104000180
+12111,4,111000040
+12112,4,112000040
+12113,4,108000100
+12114,4,105000090
+12115,4,110000100
+12116,4,118000050
+12117,4,118000060
+12118,5,101000120
+12119,5,109000110
+12120,5,105000120
+12121,5,102000120
+12122,5,107000110
+12123,5,103000120
+12124,5,106000120
+12125,5,104000120
+12126,5,104000190
+12127,5,111000060
+12128,5,112000060
+12129,5,108000110
+12130,5,110000110
+12131,5,118000070
+12132,1,201000010
+12133,1,292000010
+12134,1,299000040
+12135,1,299000070
+12136,1,299000110
+12137,1,299000120
+12138,1,299000140
+12139,2,202000010
+12140,2,290000010
+12141,2,299000010
+12142,2,299000150
+12143,2,299000190
+12144,2,299000200
+12145,2,299000210
+12146,3,298000050
+12147,3,298000060
+12148,3,299000060
+12149,3,299000170
+12150,3,290000120
+12151,3,291000050
+12152,3,292000020
+12153,4,299000670
+12154,4,299000680
+12155,4,204000010
+12156,4,209000040
+12157,4,202000070
+12158,4,209000070
+12159,5,297000100
+12160,5,291000020
+12161,5,297000130
+12162,5,297000140
+12163,5,203000010
+12164,5,206000030
+12165,5,203000050
+12166,5,202000090
+12167,3,170004
+12168,3,180004
+12169,4,140000
+12170,5,150010
+12171,5,150020
+12172,5,150030
+12173,5,150040
+12174,5,190000
+12175,5,200000
+12176,5,210000
+12178,1,101000010
+12179,1,102000010
+12180,1,103000010
+12181,1,104000010
+12182,1,105000010
+12183,1,106000010
+12184,1,107000010
+12185,1,108000010
+12186,1,109000010
+12187,1,110000010
+12188,2,101000020
+12189,2,101000030
+12190,2,102000020
+12191,2,102000030
+12192,2,102000040
+12193,2,103000020
+12194,2,103000030
+12195,2,103000040
+12196,2,104000020
+12197,2,104000030
+12198,2,104000040
+12199,2,105000020
+12200,2,105000030
+12201,2,105000040
+12202,2,106000020
+12203,2,106000030
+12204,2,106000040
+12205,2,107000020
+12206,2,107000030
+12207,2,107000040
+12208,2,108000020
+12209,2,108000030
+12210,2,108000040
+12211,2,109000020
+12212,2,109000030
+12213,2,109000040
+12214,2,110000020
+12215,2,110000030
+12216,2,110000040
+12217,2,118000010
+12218,3,101000050
+12219,3,101000060
+12220,3,101000080
+12221,3,101000040
+12222,3,109000060
+12223,3,109000070
+12224,3,109000080
+12225,3,105000060
+12226,3,105000070
+12227,3,105000080
+12228,3,104000050
+12229,3,106000050
+12230,3,102000060
+12231,3,102000070
+12232,3,102000080
+12233,3,103000050
+12234,3,105000050
+12235,3,107000060
+12236,3,107000070
+12237,3,107000080
+12238,3,108000050
+12239,3,109000050
+12240,3,103000060
+12241,3,103000070
+12242,3,103000080
+12243,3,110000050
+12244,3,106000060
+12245,3,106000070
+12246,3,106000080
+12247,3,101000070
+12248,3,110000060
+12249,3,104000060
+12250,3,104000070
+12251,3,104000080
+12252,3,102000050
+12253,3,104000170
+12254,3,104000260
+12255,3,111000010
+12256,3,111000020
+12257,3,111000030
+12258,3,112000020
+12259,3,112000030
+12260,3,108000060
+12261,3,108000070
+12262,3,108000080
+12263,3,107000050
+12264,3,112000010
+12265,3,110000070
+12266,3,110000080
+12267,3,118000020
+12268,3,118000030
+12269,3,118000040
+12270,4,101000090
+12271,4,101000100
+12272,4,101000110
+12273,4,109000100
+12274,4,105000100
+12275,4,105000110
+12276,4,108000090
+12277,4,110000090
+12278,4,102000100
+12279,4,102000110
+12280,4,106000090
+12281,4,109000090
+12282,4,107000100
+12283,4,103000090
+12284,4,102000090
+12285,4,103000100
+12286,4,106000100
+12287,4,106000110
+12288,4,104000090
+12289,4,104000100
+12290,4,104000110
+12291,4,107000090
+12292,4,104000180
+12293,4,111000040
+12294,4,112000040
+12295,4,108000100
+12296,4,105000090
+12297,4,110000100
+12298,4,118000050
+12299,4,118000060
+12300,5,101000120
+12301,5,109000110
+12302,5,105000120
+12303,5,102000120
+12304,5,107000110
+12305,5,103000120
+12306,5,106000120
+12307,5,104000120
+12308,5,104000190
+12309,5,111000060
+12310,5,112000060
+12311,5,108000110
+12312,5,110000110
+12313,5,118000070
+12314,1,201000010
+12315,1,292000010
+12316,1,299000040
+12317,1,299000070
+12318,1,299000110
+12319,1,299000120
+12320,1,299000140
+12321,2,202000010
+12322,2,290000010
+12323,2,299000010
+12324,2,299000150
+12325,2,299000190
+12326,2,299000200
+12327,2,299000210
+12328,3,298000050
+12329,3,298000060
+12330,3,299000060
+12331,3,299000170
+12332,3,290000120
+12333,3,291000050
+12334,3,292000020
+12335,4,299000670
+12336,4,299000680
+12337,4,204000010
+12338,4,209000040
+12339,4,202000070
+12340,4,209000070
+12341,4,203000110
+12342,5,297000100
+12343,5,291000020
+12344,5,297000130
+12345,5,297000140
+12346,5,203000010
+12347,5,206000030
+12348,5,203000050
+12349,5,202000090
+12350,5,204000080
+12351,1,170002
+12352,1,180002
+12353,2,170003
+12354,2,180003
+12355,3,170004
+12356,3,180004
+12357,4,140000
+12358,5,150010
+12359,5,150020
+12360,5,150030
+12361,5,150040
+12363,1,101000010
+12364,1,102000010
+12365,1,103000010
+12366,1,104000010
+12367,1,105000010
+12368,1,106000010
+12369,1,107000010
+12370,1,108000010
+12371,1,109000010
+12372,1,110000010
+12373,2,101000020
+12374,2,101000030
+12375,2,102000020
+12376,2,102000030
+12377,2,102000040
+12378,2,103000020
+12379,2,103000030
+12380,2,103000040
+12381,2,104000020
+12382,2,104000030
+12383,2,104000040
+12384,2,105000020
+12385,2,105000030
+12386,2,105000040
+12387,2,106000020
+12388,2,106000030
+12389,2,106000040
+12390,2,107000020
+12391,2,107000030
+12392,2,107000040
+12393,2,108000020
+12394,2,108000030
+12395,2,108000040
+12396,2,109000020
+12397,2,109000030
+12398,2,109000040
+12399,2,110000020
+12400,2,110000030
+12401,2,110000040
+12402,2,118000010
+12403,3,101000050
+12404,3,101000060
+12405,3,101000080
+12406,3,101000040
+12407,3,109000060
+12408,3,109000070
+12409,3,109000080
+12410,3,105000060
+12411,3,105000070
+12412,3,105000080
+12413,3,104000050
+12414,3,106000050
+12415,3,102000060
+12416,3,102000070
+12417,3,102000080
+12418,3,103000050
+12419,3,105000050
+12420,3,107000060
+12421,3,107000070
+12422,3,107000080
+12423,3,108000050
+12424,3,109000050
+12425,3,103000060
+12426,3,103000070
+12427,3,103000080
+12428,3,110000050
+12429,3,106000060
+12430,3,106000070
+12431,3,106000080
+12432,3,101000070
+12433,3,110000060
+12434,3,104000060
+12435,3,104000070
+12436,3,104000080
+12437,3,102000050
+12438,3,104000170
+12439,3,104000260
+12440,3,111000010
+12441,3,111000020
+12442,3,111000030
+12443,3,112000020
+12444,3,112000030
+12445,3,108000060
+12446,3,108000070
+12447,3,108000080
+12448,3,107000050
+12449,3,112000010
+12450,3,110000070
+12451,3,110000080
+12452,3,118000020
+12453,3,118000030
+12454,3,118000040
+12455,4,101000090
+12456,4,101000100
+12457,4,101000110
+12458,4,109000100
+12459,4,105000100
+12460,4,105000110
+12461,4,108000090
+12462,4,110000090
+12463,4,102000100
+12464,4,102000110
+12465,4,106000090
+12466,4,109000090
+12467,4,107000100
+12468,4,103000090
+12469,4,102000090
+12470,4,103000100
+12471,4,106000100
+12472,4,106000110
+12473,4,104000090
+12474,4,104000100
+12475,4,104000110
+12476,4,107000090
+12477,4,104000180
+12478,4,111000040
+12479,4,112000040
+12480,4,108000100
+12481,4,105000090
+12482,4,110000100
+12483,4,118000050
+12484,4,118000060
+12485,5,101000120
+12486,5,109000110
+12487,5,105000120
+12488,5,102000120
+12489,5,107000110
+12490,5,103000120
+12491,5,106000120
+12492,5,104000120
+12493,5,104000190
+12494,5,111000060
+12495,5,112000060
+12496,5,108000110
+12497,5,110000110
+12498,5,118000070
+12499,1,201000010
+12500,1,292000010
+12501,1,299000040
+12502,1,299000070
+12503,1,299000110
+12504,1,299000120
+12505,1,299000140
+12506,2,202000010
+12507,2,290000010
+12508,2,299000010
+12509,2,299000150
+12510,2,299000190
+12511,2,299000200
+12512,2,299000210
+12513,3,298000050
+12514,3,298000060
+12515,3,299000060
+12516,3,299000170
+12517,3,290000120
+12518,3,291000050
+12519,3,292000020
+12520,4,299000670
+12521,4,299000680
+12522,4,204000010
+12523,4,209000040
+12524,4,202000070
+12525,4,209000070
+12526,4,203000110
+12527,5,297000100
+12528,5,291000020
+12529,5,297000130
+12530,5,297000140
+12531,5,203000010
+12532,5,206000030
+12533,5,203000050
+12534,5,202000090
+12535,5,204000080
+12536,2,170003
+12537,2,180003
+12538,3,170004
+12539,3,180004
+12540,4,140000
+12541,5,150010
+12542,5,150020
+12543,5,150030
+12544,5,150040
+12546,3,101000050
+12547,3,101000060
+12548,3,101000080
+12549,3,101000040
+12550,3,109000060
+12551,3,109000070
+12552,3,109000080
+12553,3,105000060
+12554,3,105000070
+12555,3,105000080
+12556,3,104000050
+12557,3,106000050
+12558,3,102000060
+12559,3,102000070
+12560,3,102000080
+12561,3,103000050
+12562,3,105000050
+12563,3,107000060
+12564,3,107000070
+12565,3,107000080
+12566,3,108000050
+12567,3,109000050
+12568,3,103000060
+12569,3,103000070
+12570,3,103000080
+12571,3,110000050
+12572,3,106000060
+12573,3,106000070
+12574,3,106000080
+12575,3,101000070
+12576,3,110000060
+12577,3,104000060
+12578,3,104000070
+12579,3,104000080
+12580,3,102000050
+12581,3,104000170
+12582,3,104000260
+12583,3,111000010
+12584,3,111000020
+12585,3,111000030
+12586,3,112000020
+12587,3,112000030
+12588,3,108000060
+12589,3,108000070
+12590,3,108000080
+12591,3,107000050
+12592,3,112000010
+12593,3,110000070
+12594,3,110000080
+12595,3,118000020
+12596,3,118000030
+12597,3,118000040
+12598,4,101000090
+12599,4,101000100
+12600,4,101000110
+12601,4,109000100
+12602,4,105000100
+12603,4,105000110
+12604,4,108000090
+12605,4,110000090
+12606,4,102000100
+12607,4,102000110
+12608,4,106000090
+12609,4,109000090
+12610,4,107000100
+12611,4,103000090
+12612,4,102000090
+12613,4,103000100
+12614,4,106000100
+12615,4,106000110
+12616,4,104000090
+12617,4,104000100
+12618,4,104000110
+12619,4,107000090
+12620,4,104000180
+12621,4,111000040
+12622,4,112000040
+12623,4,108000100
+12624,4,105000090
+12625,4,110000100
+12626,4,118000050
+12627,4,118000060
+12628,5,101000120
+12629,5,109000110
+12630,5,105000120
+12631,5,102000120
+12632,5,107000110
+12633,5,103000120
+12634,5,106000120
+12635,5,104000120
+12636,5,104000190
+12637,5,111000060
+12638,5,112000060
+12639,5,108000110
+12640,5,110000110
+12641,5,118000070
+12642,1,201000010
+12643,1,292000010
+12644,1,299000040
+12645,1,299000070
+12646,1,299000110
+12647,1,299000120
+12648,1,299000140
+12649,2,202000010
+12650,2,290000010
+12651,2,299000010
+12652,2,299000150
+12653,2,299000190
+12654,2,299000200
+12655,2,299000210
+12656,3,298000050
+12657,3,298000060
+12658,3,299000060
+12659,3,299000170
+12660,3,290000120
+12661,3,291000050
+12662,3,292000020
+12663,4,299000670
+12664,4,299000680
+12665,4,204000010
+12666,4,209000040
+12667,4,202000070
+12668,4,209000070
+12669,4,203000110
+12670,5,297000100
+12671,5,291000020
+12672,5,297000130
+12673,5,297000140
+12674,5,203000010
+12675,5,206000030
+12676,5,203000050
+12677,5,202000090
+12678,5,204000080
+12679,3,170004
+12680,3,180004
+12681,4,140000
+12682,5,150010
+12683,5,150020
+12684,5,150030
+12685,5,150040
+12687,3,101000050
+12688,3,101000060
+12689,3,101000080
+12690,3,101000040
+12691,3,109000060
+12692,3,109000070
+12693,3,109000080
+12694,3,105000060
+12695,3,105000070
+12696,3,105000080
+12697,3,104000050
+12698,3,106000050
+12699,3,102000060
+12700,3,102000070
+12701,3,102000080
+12702,3,103000050
+12703,3,105000050
+12704,3,107000060
+12705,3,107000070
+12706,3,107000080
+12707,3,108000050
+12708,3,109000050
+12709,3,103000060
+12710,3,103000070
+12711,3,103000080
+12712,3,110000050
+12713,3,106000060
+12714,3,106000070
+12715,3,106000080
+12716,3,101000070
+12717,3,110000060
+12718,3,104000060
+12719,3,104000070
+12720,3,104000080
+12721,3,102000050
+12722,3,104000170
+12723,3,104000260
+12724,3,111000010
+12725,3,111000020
+12726,3,111000030
+12727,3,112000020
+12728,3,112000030
+12729,3,108000060
+12730,3,108000070
+12731,3,108000080
+12732,3,107000050
+12733,3,112000010
+12734,3,110000070
+12735,3,110000080
+12736,3,118000020
+12737,3,118000030
+12738,3,118000040
+12739,4,101000090
+12740,4,101000100
+12741,4,101000110
+12742,4,109000100
+12743,4,105000100
+12744,4,105000110
+12745,4,108000090
+12746,4,110000090
+12747,4,102000100
+12748,4,102000110
+12749,4,106000090
+12750,4,109000090
+12751,4,107000100
+12752,4,103000090
+12753,4,102000090
+12754,4,103000100
+12755,4,106000100
+12756,4,106000110
+12757,4,104000090
+12758,4,104000100
+12759,4,104000110
+12760,4,107000090
+12761,4,104000180
+12762,4,111000040
+12763,4,112000040
+12764,4,108000100
+12765,4,105000090
+12766,4,110000100
+12767,4,118000050
+12768,4,118000060
+12769,5,101000120
+12770,5,109000110
+12771,5,105000120
+12772,5,102000120
+12773,5,107000110
+12774,5,103000120
+12775,5,106000120
+12776,5,104000120
+12777,5,104000190
+12778,5,111000060
+12779,5,112000060
+12780,5,108000110
+12781,5,110000110
+12782,5,118000070
+12783,1,201000010
+12784,1,292000010
+12785,1,299000040
+12786,1,299000070
+12787,1,299000110
+12788,1,299000120
+12789,1,299000140
+12790,2,202000010
+12791,2,290000010
+12792,2,299000010
+12793,2,299000150
+12794,2,299000190
+12795,2,299000200
+12796,2,299000210
+12797,3,298000050
+12798,3,298000060
+12799,3,299000060
+12800,3,299000170
+12801,3,290000120
+12802,3,291000050
+12803,3,292000020
+12804,4,299000670
+12805,4,299000680
+12806,4,204000010
+12807,4,209000040
+12808,4,202000070
+12809,4,209000070
+12810,4,203000110
+12811,5,297000100
+12812,5,291000020
+12813,5,297000130
+12814,5,297000140
+12815,5,203000010
+12816,5,206000030
+12817,5,203000050
+12818,5,202000090
+12819,5,204000080
+12820,3,170004
+12821,3,180004
+12822,4,140000
+12823,5,150010
+12824,5,150020
+12825,5,150030
+12826,5,150040
+12828,3,101000050
+12829,3,101000060
+12830,3,101000080
+12831,3,101000040
+12832,3,109000060
+12833,3,109000070
+12834,3,109000080
+12835,3,105000060
+12836,3,105000070
+12837,3,105000080
+12838,3,104000050
+12839,3,106000050
+12840,3,102000060
+12841,3,102000070
+12842,3,102000080
+12843,3,103000050
+12844,3,105000050
+12845,3,107000060
+12846,3,107000070
+12847,3,107000080
+12848,3,108000050
+12849,3,109000050
+12850,3,103000060
+12851,3,103000070
+12852,3,103000080
+12853,3,110000050
+12854,3,106000060
+12855,3,106000070
+12856,3,106000080
+12857,3,101000070
+12858,3,110000060
+12859,3,104000060
+12860,3,104000070
+12861,3,104000080
+12862,3,102000050
+12863,3,104000170
+12864,3,104000260
+12865,3,111000010
+12866,3,111000020
+12867,3,111000030
+12868,3,112000020
+12869,3,112000030
+12870,3,108000060
+12871,3,108000070
+12872,3,108000080
+12873,3,107000050
+12874,3,112000010
+12875,3,110000070
+12876,3,110000080
+12877,3,118000020
+12878,3,118000030
+12879,3,118000040
+12880,4,101000090
+12881,4,101000100
+12882,4,101000110
+12883,4,109000100
+12884,4,105000100
+12885,4,105000110
+12886,4,108000090
+12887,4,110000090
+12888,4,102000100
+12889,4,102000110
+12890,4,106000090
+12891,4,109000090
+12892,4,107000100
+12893,4,103000090
+12894,4,102000090
+12895,4,103000100
+12896,4,106000100
+12897,4,106000110
+12898,4,104000090
+12899,4,104000100
+12900,4,104000110
+12901,4,107000090
+12902,4,104000180
+12903,4,111000040
+12904,4,112000040
+12905,4,108000100
+12906,4,105000090
+12907,4,110000100
+12908,4,118000050
+12909,4,118000060
+12910,5,101000120
+12911,5,109000110
+12912,5,105000120
+12913,5,102000120
+12914,5,107000110
+12915,5,103000120
+12916,5,106000120
+12917,5,104000120
+12918,5,104000190
+12919,5,111000060
+12920,5,112000060
+12921,5,108000110
+12922,5,110000110
+12923,5,118000070
+12924,1,201000010
+12925,1,292000010
+12926,1,299000040
+12927,1,299000070
+12928,1,299000110
+12929,1,299000120
+12930,1,299000140
+12931,2,202000010
+12932,2,290000010
+12933,2,299000010
+12934,2,299000150
+12935,2,299000190
+12936,2,299000200
+12937,2,299000210
+12938,3,298000050
+12939,3,298000060
+12940,3,299000060
+12941,3,299000170
+12942,3,290000120
+12943,3,291000050
+12944,3,292000020
+12945,4,299000670
+12946,4,299000680
+12947,4,204000010
+12948,4,209000040
+12949,4,202000070
+12950,4,209000070
+12951,4,203000110
+12952,5,297000100
+12953,5,291000020
+12954,5,297000130
+12955,5,297000140
+12956,5,203000010
+12957,5,206000030
+12958,5,203000050
+12959,5,202000090
+12960,5,204000080
+12961,3,170004
+12962,3,180004
+12963,4,140000
+12964,5,150010
+12965,5,150020
+12966,5,150030
+12967,5,150040
+12968,5,190000
+12969,5,200000
+12970,5,210000
+12972,3,102000060
+12973,3,102000070
+12974,3,102000080
+12975,3,103000050
+12976,3,105000050
+12977,3,107000060
+12978,3,107000070
+12979,3,107000080
+12980,3,108000050
+12981,3,109000050
+12982,3,103000060
+12983,3,103000070
+12984,3,103000080
+12985,3,110000050
+12986,4,102000100
+12987,4,102000110
+12988,4,102000350
+12989,4,106000090
+12990,4,109000090
+12991,4,107000100
+12992,4,103000090
+12993,4,102000090
+12994,4,103000100
+12995,5,102000120
+12996,5,107000110
+12997,5,103000120
+12998,1,102000000
+12999,2,102000001
+13000,3,102000002
+13001,4,102000003
+13002,5,102000004
+13003,1,105000000
+13004,2,105000001
+13005,3,105000002
+13006,4,105000003
+13007,5,105000004
+13008,1,112000000
+13009,2,112000001
+13010,3,112000002
+13011,4,112000003
+13012,5,112000004
+13013,3,170004
+13014,4,170005
+13015,3,180004
+13016,4,180005
+13017,4,140000
+13018,4,150010
+13019,4,150020
+13020,4,150030
+13021,4,150040
+13023,3,118000020
+13024,3,118000030
+13025,3,118000040
+13026,3,106000060
+13027,3,106000070
+13028,3,106000080
+13029,3,101000070
+13030,3,110000060
+13031,3,104000060
+13032,3,104000070
+13033,3,104000080
+13034,3,102000050
+13035,3,104000170
+13036,3,104000260
+13037,4,118000050
+13038,4,118000060
+13039,4,106000100
+13040,4,106000110
+13041,4,104000090
+13042,4,104000100
+13043,4,104000110
+13044,4,104000270
+13045,4,107000090
+13046,4,104000180
+13047,5,118000070
+13048,5,106000120
+13049,5,104000120
+13050,5,104000190
+13051,1,103000000
+13052,2,103000001
+13053,3,103000002
+13054,4,103000003
+13055,5,103000004
+13056,1,111000000
+13057,2,111000001
+13058,3,111000002
+13059,4,111000003
+13060,5,111000004
+13061,1,115000000
+13062,2,115000001
+13063,3,115000002
+13064,4,115000003
+13065,5,115000004
+13066,4,110024
+13067,4,110034
+13068,4,110044
+13069,4,110054
+13070,3,110060
+13071,3,110070
+13072,3,110080
+13073,3,110090
+13074,3,110100
+13075,3,110110
+13076,3,110120
+13077,3,110130
+13078,3,110140
+13079,3,110150
+13080,3,110160
+13081,3,110170
+13082,3,110180
+13083,3,110190
+13084,3,110200
+13085,3,110210
+13086,3,110220
+13087,3,110230
+13088,3,110240
+13089,3,110250
+13090,3,110260
+13091,3,110270
+13092,3,110620
+13093,3,110670
+13094,4,140000
+13095,4,150010
+13096,4,150020
+13097,4,150030
+13098,4,150040
+13100,3,111000010
+13101,3,111000020
+13102,3,111000030
+13103,3,112000020
+13104,3,112000030
+13105,3,108000060
+13106,3,108000070
+13107,3,108000080
+13108,3,107000050
+13109,3,112000010
+13110,3,110000070
+13111,3,110000080
+13112,4,111000040
+13113,4,112000040
+13114,4,108000100
+13115,4,105000090
+13116,4,110000100
+13117,5,111000060
+13118,5,112000060
+13119,5,108000110
+13120,5,110000110
+13121,1,108000000
+13122,2,108000001
+13123,3,108000002
+13124,4,108000003
+13125,5,108000004
+13126,1,107000000
+13127,2,107000001
+13128,3,107000002
+13129,4,107000003
+13130,5,107000004
+13131,1,120000000
+13132,2,120000001
+13133,3,120000002
+13134,4,120000003
+13135,5,120000004
+13136,4,120024
+13137,4,120034
+13138,4,120044
+13139,4,120054
+13140,3,120241
+13141,3,120251
+13142,3,120261
+13143,3,120271
+13144,3,120300
+13145,3,120310
+13146,3,120320
+13147,3,120330
+13148,3,120340
+13149,3,120350
+13150,3,120360
+13151,3,120370
+13152,3,120380
+13153,3,120390
+13154,3,120400
+13155,3,120410
+13156,3,120420
+13157,3,120430
+13158,3,120450
+13159,3,120460
+13160,3,120550
+13161,3,120560
+13162,3,120570
+13163,3,120990
+13164,3,121000
+13165,3,121010
+13166,3,121020
+13167,3,121100
+13168,4,140000
+13169,4,150010
+13170,4,150020
+13171,4,150030
+13172,4,150040
+13174,3,101000050
+13175,3,101000060
+13176,3,101000080
+13177,3,101000040
+13178,3,109000060
+13179,3,109000070
+13180,3,109000080
+13181,3,105000060
+13182,3,105000070
+13183,3,105000080
+13184,3,104000050
+13185,3,106000050
+13186,4,101000090
+13187,4,101000100
+13188,4,101000110
+13189,4,109000100
+13190,4,105000100
+13191,4,105000110
+13192,4,108000090
+13193,4,110000090
+13194,5,101000120
+13195,5,109000110
+13196,5,105000120
+13197,1,101000000
+13198,2,101000001
+13199,3,101000002
+13200,4,101000008
+13201,5,101000004
+13202,1,109000000
+13203,2,109000001
+13204,3,109000002
+13205,4,109000003
+13206,5,109000004
+13207,4,130024
+13208,4,130034
+13209,4,130044
+13210,4,130054
+13211,3,130060
+13212,3,130070
+13213,3,130080
+13214,3,130090
+13215,3,130100
+13216,3,130110
+13217,3,130120
+13218,3,130130
+13219,3,130140
+13220,3,130150
+13221,3,130160
+13222,3,130170
+13223,3,130180
+13224,3,130190
+13225,3,130200
+13226,3,130420
+13227,3,130510
+13228,3,130520
+13229,3,130531
+13230,3,130540
+13231,3,130660
+13232,3,130700
+13233,3,130790
+13234,3,130800
+13235,3,131130
+13236,4,140000
+13237,4,150010
+13238,4,150020
+13239,4,150030
+13240,4,150040
+13242,3,101000050
+13243,3,101000060
+13244,3,101000080
+13245,3,101000040
+13246,3,109000060
+13247,3,109000070
+13248,3,109000080
+13249,3,105000060
+13250,3,105000070
+13251,3,105000080
+13252,3,104000050
+13253,3,106000050
+13254,4,101000090
+13255,4,101000100
+13256,4,101000110
+13257,4,109000100
+13258,4,105000100
+13259,4,105000110
+13260,4,108000090
+13261,4,110000090
+13262,5,101000120
+13263,5,109000110
+13264,5,105000120
+13265,1,101000000
+13266,2,101000001
+13267,3,101000002
+13268,4,101000008
+13269,5,101000004
+13270,1,109000000
+13271,2,109000001
+13272,3,109000002
+13273,4,109000003
+13274,5,109000004
+13275,3,170004
+13276,4,170005
+13277,3,180004
+13278,4,180005
+13279,4,140000
+13280,4,150010
+13281,4,150020
+13282,4,150030
+13283,4,150040
+13285,3,102000060
+13286,3,102000070
+13287,3,102000080
+13288,3,103000050
+13289,3,105000050
+13290,3,107000060
+13291,3,107000070
+13292,3,107000080
+13293,3,108000050
+13294,3,109000050
+13295,3,103000060
+13296,3,103000070
+13297,3,103000080
+13298,3,110000050
+13299,4,102000100
+13300,4,102000110
+13301,4,102000350
+13302,4,106000090
+13303,4,109000090
+13304,4,107000100
+13305,4,103000090
+13306,4,102000090
+13307,4,103000100
+13308,5,102000120
+13309,5,107000110
+13310,5,103000120
+13311,1,102000000
+13312,2,102000001
+13313,3,102000002
+13314,4,102000003
+13315,5,102000004
+13316,1,105000000
+13317,2,105000001
+13318,3,105000002
+13319,4,105000003
+13320,5,105000004
+13321,1,112000000
+13322,2,112000001
+13323,3,112000002
+13324,4,112000003
+13325,5,112000004
+13326,4,110024
+13327,4,110034
+13328,4,110044
+13329,4,110054
+13330,3,110060
+13331,3,110070
+13332,3,110080
+13333,3,110090
+13334,3,110100
+13335,3,110110
+13336,3,110120
+13337,3,110130
+13338,3,110140
+13339,3,110150
+13340,3,110160
+13341,3,110170
+13342,3,110180
+13343,3,110190
+13344,3,110200
+13345,3,110210
+13346,3,110220
+13347,3,110230
+13348,3,110240
+13349,3,110250
+13350,3,110260
+13351,3,110270
+13352,3,110620
+13353,3,110670
+13354,4,140000
+13355,4,150010
+13356,4,150020
+13357,4,150030
+13358,4,150040
+13360,3,118000020
+13361,3,118000030
+13362,3,118000040
+13363,3,106000060
+13364,3,106000070
+13365,3,106000080
+13366,3,101000070
+13367,3,110000060
+13368,3,104000060
+13369,3,104000070
+13370,3,104000080
+13371,3,102000050
+13372,3,104000170
+13373,3,104000260
+13374,4,118000050
+13375,4,118000060
+13376,4,106000100
+13377,4,106000110
+13378,4,104000090
+13379,4,104000100
+13380,4,104000110
+13381,4,104000270
+13382,4,107000090
+13383,4,104000180
+13384,5,118000070
+13385,5,106000120
+13386,5,104000120
+13387,5,104000190
+13388,1,103000000
+13389,2,103000001
+13390,3,103000002
+13391,4,103000003
+13392,5,103000004
+13393,1,111000000
+13394,2,111000001
+13395,3,111000002
+13396,4,111000003
+13397,5,111000004
+13398,1,115000000
+13399,2,115000001
+13400,3,115000002
+13401,4,115000003
+13402,5,115000004
+13403,4,120024
+13404,4,120034
+13405,4,120044
+13406,4,120054
+13407,3,120241
+13408,3,120251
+13409,3,120261
+13410,3,120271
+13411,3,120300
+13412,3,120310
+13413,3,120320
+13414,3,120330
+13415,3,120340
+13416,3,120350
+13417,3,120360
+13418,3,120370
+13419,3,120380
+13420,3,120390
+13421,3,120400
+13422,3,120410
+13423,3,120420
+13424,3,120430
+13425,3,120450
+13426,3,120460
+13427,3,120550
+13428,3,120560
+13429,3,120570
+13430,3,120990
+13431,3,121000
+13432,3,121010
+13433,3,121020
+13434,3,121100
+13435,4,140000
+13436,4,150010
+13437,4,150020
+13438,4,150030
+13439,4,150040
+13441,3,111000010
+13442,3,111000020
+13443,3,111000030
+13444,3,112000020
+13445,3,112000030
+13446,3,108000060
+13447,3,108000070
+13448,3,108000080
+13449,3,107000050
+13450,3,112000010
+13451,3,110000070
+13452,3,110000080
+13453,4,111000040
+13454,4,112000040
+13455,4,108000100
+13456,4,105000090
+13457,4,110000100
+13458,5,111000060
+13459,5,112000060
+13460,5,108000110
+13461,5,110000110
+13462,1,108000000
+13463,2,108000001
+13464,3,108000002
+13465,4,108000003
+13466,5,108000004
+13467,1,107000000
+13468,2,107000001
+13469,3,107000002
+13470,4,107000003
+13471,5,107000004
+13472,1,120000000
+13473,2,120000001
+13474,3,120000002
+13475,4,120000003
+13476,5,120000004
+13477,4,130024
+13478,4,130034
+13479,4,130044
+13480,4,130054
+13481,3,130060
+13482,3,130070
+13483,3,130080
+13484,3,130090
+13485,3,130100
+13486,3,130110
+13487,3,130120
+13488,3,130130
+13489,3,130140
+13490,3,130150
+13491,3,130160
+13492,3,130170
+13493,3,130180
+13494,3,130190
+13495,3,130200
+13496,3,130420
+13497,3,130510
+13498,3,130520
+13499,3,130531
+13500,3,130540
+13501,3,130660
+13502,3,130700
+13503,3,130790
+13504,3,130800
+13505,3,131130
+13506,4,140000
+13507,4,150010
+13508,4,150020
+13509,4,150030
+13510,4,150040
+13512,1,101000010
+13513,1,102000010
+13514,1,103000010
+13515,1,104000010
+13516,1,105000010
+13517,1,106000010
+13518,1,107000010
+13519,1,108000010
+13520,1,109000010
+13521,1,110000010
+13522,2,101000020
+13523,2,101000030
+13524,2,102000020
+13525,2,102000030
+13526,2,102000040
+13527,2,103000020
+13528,2,103000030
+13529,2,103000040
+13530,2,104000020
+13531,2,104000030
+13532,2,104000040
+13533,2,105000020
+13534,2,105000030
+13535,2,105000040
+13536,2,106000020
+13537,2,106000030
+13538,2,106000040
+13539,2,107000020
+13540,2,107000030
+13541,2,107000040
+13542,2,108000020
+13543,2,108000030
+13544,2,108000040
+13545,2,109000020
+13546,2,109000030
+13547,2,109000040
+13548,2,110000020
+13549,2,110000030
+13550,2,110000040
+13551,2,118000010
+13552,3,101000050
+13553,3,101000060
+13554,3,101000080
+13555,3,101000040
+13556,3,109000060
+13557,3,109000070
+13558,3,109000080
+13559,3,105000060
+13560,3,105000070
+13561,3,105000080
+13562,3,104000050
+13563,3,106000050
+13564,3,102000060
+13565,3,102000070
+13566,3,102000080
+13567,3,103000050
+13568,3,105000050
+13569,3,107000060
+13570,3,107000070
+13571,3,107000080
+13572,3,108000050
+13573,3,109000050
+13574,3,103000060
+13575,3,103000070
+13576,3,103000080
+13577,3,110000050
+13578,3,106000060
+13579,3,106000070
+13580,3,106000080
+13581,3,101000070
+13582,3,110000060
+13583,3,104000060
+13584,3,104000070
+13585,3,104000080
+13586,3,102000050
+13587,3,104000170
+13588,3,104000260
+13589,3,111000010
+13590,3,111000020
+13591,3,111000030
+13592,3,112000020
+13593,3,112000030
+13594,3,108000060
+13595,3,108000070
+13596,3,108000080
+13597,3,107000050
+13598,3,112000010
+13599,3,110000070
+13600,3,110000080
+13601,3,118000020
+13602,3,118000030
+13603,3,118000040
+13604,4,101000090
+13605,4,101000100
+13606,4,101000110
+13607,4,109000100
+13608,4,105000100
+13609,4,105000110
+13610,4,108000090
+13611,4,110000090
+13612,4,102000100
+13613,4,102000110
+13614,4,106000090
+13615,4,109000090
+13616,4,107000100
+13617,4,103000090
+13618,4,102000090
+13619,4,103000100
+13620,4,106000100
+13621,4,106000110
+13622,4,104000090
+13623,4,104000100
+13624,4,104000110
+13625,4,107000090
+13626,4,104000180
+13627,4,111000040
+13628,4,112000040
+13629,4,108000100
+13630,4,105000090
+13631,4,110000100
+13632,4,118000050
+13633,4,118000060
+13634,5,101000120
+13635,5,109000110
+13636,5,105000120
+13637,5,102000120
+13638,5,107000110
+13639,5,103000120
+13640,5,106000120
+13641,5,104000120
+13642,5,104000190
+13643,5,111000060
+13644,5,112000060
+13645,5,108000110
+13646,5,110000110
+13647,5,118000070
+13648,1,201000010
+13649,1,292000010
+13650,1,299000040
+13651,1,299000070
+13652,1,299000110
+13653,1,299000120
+13654,1,299000140
+13655,2,202000010
+13656,2,290000010
+13657,2,299000010
+13658,2,299000150
+13659,2,299000190
+13660,2,299000200
+13661,2,299000210
+13662,3,298000050
+13663,3,298000060
+13664,3,299000060
+13665,3,299000170
+13666,3,290000120
+13667,3,291000050
+13668,3,292000020
+13669,4,299000670
+13670,4,299000680
+13671,4,204000010
+13672,4,209000040
+13673,4,202000070
+13674,4,209000070
+13675,4,203000110
+13676,4,290000110
+13677,5,297000100
+13678,5,291000020
+13679,5,297000130
+13680,5,297000140
+13681,5,203000010
+13682,5,206000030
+13683,5,203000050
+13684,5,202000090
+13685,5,204000080
+13686,5,202000150
+13687,1,170002
+13688,1,180002
+13689,2,170003
+13690,2,180003
+13691,3,170004
+13692,3,180004
+13693,4,140000
+13694,5,150010
+13695,5,150020
+13696,5,150030
+13697,5,150040
+13699,1,101000010
+13700,1,102000010
+13701,1,103000010
+13702,1,104000010
+13703,1,105000010
+13704,1,106000010
+13705,1,107000010
+13706,1,108000010
+13707,1,109000010
+13708,1,110000010
+13709,2,101000020
+13710,2,101000030
+13711,2,102000020
+13712,2,102000030
+13713,2,102000040
+13714,2,103000020
+13715,2,103000030
+13716,2,103000040
+13717,2,104000020
+13718,2,104000030
+13719,2,104000040
+13720,2,105000020
+13721,2,105000030
+13722,2,105000040
+13723,2,106000020
+13724,2,106000030
+13725,2,106000040
+13726,2,107000020
+13727,2,107000030
+13728,2,107000040
+13729,2,108000020
+13730,2,108000030
+13731,2,108000040
+13732,2,109000020
+13733,2,109000030
+13734,2,109000040
+13735,2,110000020
+13736,2,110000030
+13737,2,110000040
+13738,2,118000010
+13739,3,101000050
+13740,3,101000060
+13741,3,101000080
+13742,3,101000040
+13743,3,109000060
+13744,3,109000070
+13745,3,109000080
+13746,3,105000060
+13747,3,105000070
+13748,3,105000080
+13749,3,104000050
+13750,3,106000050
+13751,3,102000060
+13752,3,102000070
+13753,3,102000080
+13754,3,103000050
+13755,3,105000050
+13756,3,107000060
+13757,3,107000070
+13758,3,107000080
+13759,3,108000050
+13760,3,109000050
+13761,3,103000060
+13762,3,103000070
+13763,3,103000080
+13764,3,110000050
+13765,3,106000060
+13766,3,106000070
+13767,3,106000080
+13768,3,101000070
+13769,3,110000060
+13770,3,104000060
+13771,3,104000070
+13772,3,104000080
+13773,3,102000050
+13774,3,104000170
+13775,3,104000260
+13776,3,111000010
+13777,3,111000020
+13778,3,111000030
+13779,3,112000020
+13780,3,112000030
+13781,3,108000060
+13782,3,108000070
+13783,3,108000080
+13784,3,107000050
+13785,3,112000010
+13786,3,110000070
+13787,3,110000080
+13788,3,118000020
+13789,3,118000030
+13790,3,118000040
+13791,4,101000090
+13792,4,101000100
+13793,4,101000110
+13794,4,109000100
+13795,4,105000100
+13796,4,105000110
+13797,4,108000090
+13798,4,110000090
+13799,4,102000100
+13800,4,102000110
+13801,4,106000090
+13802,4,109000090
+13803,4,107000100
+13804,4,103000090
+13805,4,102000090
+13806,4,103000100
+13807,4,106000100
+13808,4,106000110
+13809,4,104000090
+13810,4,104000100
+13811,4,104000110
+13812,4,107000090
+13813,4,104000180
+13814,4,111000040
+13815,4,112000040
+13816,4,108000100
+13817,4,105000090
+13818,4,110000100
+13819,4,118000050
+13820,4,118000060
+13821,5,101000120
+13822,5,109000110
+13823,5,105000120
+13824,5,102000120
+13825,5,107000110
+13826,5,103000120
+13827,5,106000120
+13828,5,104000120
+13829,5,104000190
+13830,5,111000060
+13831,5,112000060
+13832,5,108000110
+13833,5,110000110
+13834,5,118000070
+13835,1,201000010
+13836,1,292000010
+13837,1,299000040
+13838,1,299000070
+13839,1,299000110
+13840,1,299000120
+13841,1,299000140
+13842,2,202000010
+13843,2,290000010
+13844,2,299000010
+13845,2,299000150
+13846,2,299000190
+13847,2,299000200
+13848,2,299000210
+13849,3,298000050
+13850,3,298000060
+13851,3,299000060
+13852,3,299000170
+13853,3,290000120
+13854,3,291000050
+13855,3,292000020
+13856,4,299000670
+13857,4,299000680
+13858,4,204000010
+13859,4,209000040
+13860,4,202000070
+13861,4,209000070
+13862,4,203000110
+13863,4,290000110
+13864,5,297000100
+13865,5,291000020
+13866,5,297000130
+13867,5,297000140
+13868,5,203000010
+13869,5,206000030
+13870,5,203000050
+13871,5,202000090
+13872,5,204000080
+13873,5,202000150
+13874,2,170003
+13875,2,180003
+13876,3,170004
+13877,3,180004
+13878,4,140000
+13879,5,150010
+13880,5,150020
+13881,5,150030
+13882,5,150040
+13884,3,101000050
+13885,3,101000060
+13886,3,101000080
+13887,3,101000040
+13888,3,109000060
+13889,3,109000070
+13890,3,109000080
+13891,3,105000060
+13892,3,105000070
+13893,3,105000080
+13894,3,104000050
+13895,3,106000050
+13896,3,102000060
+13897,3,102000070
+13898,3,102000080
+13899,3,103000050
+13900,3,105000050
+13901,3,107000060
+13902,3,107000070
+13903,3,107000080
+13904,3,108000050
+13905,3,109000050
+13906,3,103000060
+13907,3,103000070
+13908,3,103000080
+13909,3,110000050
+13910,3,106000060
+13911,3,106000070
+13912,3,106000080
+13913,3,101000070
+13914,3,110000060
+13915,3,104000060
+13916,3,104000070
+13917,3,104000080
+13918,3,102000050
+13919,3,104000170
+13920,3,104000260
+13921,3,111000010
+13922,3,111000020
+13923,3,111000030
+13924,3,112000020
+13925,3,112000030
+13926,3,108000060
+13927,3,108000070
+13928,3,108000080
+13929,3,107000050
+13930,3,112000010
+13931,3,110000070
+13932,3,110000080
+13933,3,118000020
+13934,3,118000030
+13935,3,118000040
+13936,4,101000090
+13937,4,101000100
+13938,4,101000110
+13939,4,109000100
+13940,4,105000100
+13941,4,105000110
+13942,4,108000090
+13943,4,110000090
+13944,4,102000100
+13945,4,102000110
+13946,4,106000090
+13947,4,109000090
+13948,4,107000100
+13949,4,103000090
+13950,4,102000090
+13951,4,103000100
+13952,4,106000100
+13953,4,106000110
+13954,4,104000090
+13955,4,104000100
+13956,4,104000110
+13957,4,107000090
+13958,4,104000180
+13959,4,111000040
+13960,4,112000040
+13961,4,108000100
+13962,4,105000090
+13963,4,110000100
+13964,4,118000050
+13965,4,118000060
+13966,5,101000120
+13967,5,109000110
+13968,5,105000120
+13969,5,102000120
+13970,5,107000110
+13971,5,103000120
+13972,5,106000120
+13973,5,104000120
+13974,5,104000190
+13975,5,111000060
+13976,5,112000060
+13977,5,108000110
+13978,5,110000110
+13979,5,118000070
+13980,1,201000010
+13981,1,292000010
+13982,1,299000040
+13983,1,299000070
+13984,1,299000110
+13985,1,299000120
+13986,1,299000140
+13987,2,202000010
+13988,2,290000010
+13989,2,299000010
+13990,2,299000150
+13991,2,299000190
+13992,2,299000200
+13993,2,299000210
+13994,3,298000050
+13995,3,298000060
+13996,3,299000060
+13997,3,299000170
+13998,3,290000120
+13999,3,291000050
+14000,3,292000020
+14001,4,299000670
+14002,4,299000680
+14003,4,204000010
+14004,4,209000040
+14005,4,202000070
+14006,4,209000070
+14007,4,203000110
+14008,4,290000110
+14009,5,297000100
+14010,5,291000020
+14011,5,297000130
+14012,5,297000140
+14013,5,203000010
+14014,5,206000030
+14015,5,203000050
+14016,5,202000090
+14017,5,204000080
+14018,5,202000150
+14019,3,170004
+14020,3,180004
+14021,4,140000
+14022,5,150010
+14023,5,150020
+14024,5,150030
+14025,5,150040
+14027,3,101000050
+14028,3,101000060
+14029,3,101000080
+14030,3,101000040
+14031,3,109000060
+14032,3,109000070
+14033,3,109000080
+14034,3,105000060
+14035,3,105000070
+14036,3,105000080
+14037,3,104000050
+14038,3,106000050
+14039,3,102000060
+14040,3,102000070
+14041,3,102000080
+14042,3,103000050
+14043,3,105000050
+14044,3,107000060
+14045,3,107000070
+14046,3,107000080
+14047,3,108000050
+14048,3,109000050
+14049,3,103000060
+14050,3,103000070
+14051,3,103000080
+14052,3,110000050
+14053,3,106000060
+14054,3,106000070
+14055,3,106000080
+14056,3,101000070
+14057,3,110000060
+14058,3,104000060
+14059,3,104000070
+14060,3,104000080
+14061,3,102000050
+14062,3,104000170
+14063,3,104000260
+14064,3,111000010
+14065,3,111000020
+14066,3,111000030
+14067,3,112000020
+14068,3,112000030
+14069,3,108000060
+14070,3,108000070
+14071,3,108000080
+14072,3,107000050
+14073,3,112000010
+14074,3,110000070
+14075,3,110000080
+14076,3,118000020
+14077,3,118000030
+14078,3,118000040
+14079,4,101000090
+14080,4,101000100
+14081,4,101000110
+14082,4,109000100
+14083,4,105000100
+14084,4,105000110
+14085,4,108000090
+14086,4,110000090
+14087,4,102000100
+14088,4,102000110
+14089,4,106000090
+14090,4,109000090
+14091,4,107000100
+14092,4,103000090
+14093,4,102000090
+14094,4,103000100
+14095,4,106000100
+14096,4,106000110
+14097,4,104000090
+14098,4,104000100
+14099,4,104000110
+14100,4,107000090
+14101,4,104000180
+14102,4,111000040
+14103,4,112000040
+14104,4,108000100
+14105,4,105000090
+14106,4,110000100
+14107,4,118000050
+14108,4,118000060
+14109,5,101000120
+14110,5,109000110
+14111,5,105000120
+14112,5,102000120
+14113,5,107000110
+14114,5,103000120
+14115,5,106000120
+14116,5,104000120
+14117,5,104000190
+14118,5,111000060
+14119,5,112000060
+14120,5,108000110
+14121,5,110000110
+14122,5,118000070
+14123,1,201000010
+14124,1,292000010
+14125,1,299000040
+14126,1,299000070
+14127,1,299000110
+14128,1,299000120
+14129,1,299000140
+14130,2,202000010
+14131,2,290000010
+14132,2,299000010
+14133,2,299000150
+14134,2,299000190
+14135,2,299000200
+14136,2,299000210
+14137,3,298000050
+14138,3,298000060
+14139,3,299000060
+14140,3,299000170
+14141,3,290000120
+14142,3,291000050
+14143,3,292000020
+14144,4,299000670
+14145,4,299000680
+14146,4,204000010
+14147,4,209000040
+14148,4,202000070
+14149,4,209000070
+14150,4,203000110
+14151,4,290000110
+14152,5,297000100
+14153,5,291000020
+14154,5,297000130
+14155,5,297000140
+14156,5,203000010
+14157,5,206000030
+14158,5,203000050
+14159,5,202000090
+14160,5,204000080
+14161,5,202000150
+14162,3,170004
+14163,3,180004
+14164,4,140000
+14165,5,150010
+14166,5,150020
+14167,5,150030
+14168,5,150040
+14170,3,101000050
+14171,3,101000060
+14172,3,101000080
+14173,3,101000040
+14174,3,109000060
+14175,3,109000070
+14176,3,109000080
+14177,3,105000060
+14178,3,105000070
+14179,3,105000080
+14180,3,104000050
+14181,3,106000050
+14182,3,102000060
+14183,3,102000070
+14184,3,102000080
+14185,3,103000050
+14186,3,105000050
+14187,3,107000060
+14188,3,107000070
+14189,3,107000080
+14190,3,108000050
+14191,3,109000050
+14192,3,103000060
+14193,3,103000070
+14194,3,103000080
+14195,3,110000050
+14196,3,106000060
+14197,3,106000070
+14198,3,106000080
+14199,3,101000070
+14200,3,110000060
+14201,3,104000060
+14202,3,104000070
+14203,3,104000080
+14204,3,102000050
+14205,3,104000170
+14206,3,104000260
+14207,3,111000010
+14208,3,111000020
+14209,3,111000030
+14210,3,112000020
+14211,3,112000030
+14212,3,108000060
+14213,3,108000070
+14214,3,108000080
+14215,3,107000050
+14216,3,112000010
+14217,3,110000070
+14218,3,110000080
+14219,3,118000020
+14220,3,118000030
+14221,3,118000040
+14222,4,101000090
+14223,4,101000100
+14224,4,101000110
+14225,4,109000100
+14226,4,105000100
+14227,4,105000110
+14228,4,108000090
+14229,4,110000090
+14230,4,102000100
+14231,4,102000110
+14232,4,106000090
+14233,4,109000090
+14234,4,107000100
+14235,4,103000090
+14236,4,102000090
+14237,4,103000100
+14238,4,106000100
+14239,4,106000110
+14240,4,104000090
+14241,4,104000100
+14242,4,104000110
+14243,4,107000090
+14244,4,104000180
+14245,4,111000040
+14246,4,112000040
+14247,4,108000100
+14248,4,105000090
+14249,4,110000100
+14250,4,118000050
+14251,4,118000060
+14252,5,101000120
+14253,5,109000110
+14254,5,105000120
+14255,5,102000120
+14256,5,107000110
+14257,5,103000120
+14258,5,106000120
+14259,5,104000120
+14260,5,104000190
+14261,5,111000060
+14262,5,112000060
+14263,5,108000110
+14264,5,110000110
+14265,5,118000070
+14266,1,201000010
+14267,1,292000010
+14268,1,299000040
+14269,1,299000070
+14270,1,299000110
+14271,1,299000120
+14272,1,299000140
+14273,2,202000010
+14274,2,290000010
+14275,2,299000010
+14276,2,299000150
+14277,2,299000190
+14278,2,299000200
+14279,2,299000210
+14280,3,298000050
+14281,3,298000060
+14282,3,299000060
+14283,3,299000170
+14284,3,290000120
+14285,3,291000050
+14286,3,292000020
+14287,4,299000670
+14288,4,299000680
+14289,4,204000010
+14290,4,209000040
+14291,4,202000070
+14292,4,209000070
+14293,4,203000110
+14294,4,290000110
+14295,5,297000100
+14296,5,291000020
+14297,5,297000130
+14298,5,297000140
+14299,5,203000010
+14300,5,206000030
+14301,5,203000050
+14302,5,202000090
+14303,5,204000080
+14304,5,202000150
+14305,3,170004
+14306,3,180004
+14307,4,140000
+14308,5,150010
+14309,5,150020
+14310,5,150030
+14311,5,150040
+14312,5,190000
+14313,5,200000
+14314,5,210000
+14316,1,101000010
+14317,1,102000010
+14318,1,103000010
+14319,1,104000010
+14320,1,105000010
+14321,1,106000010
+14322,1,107000010
+14323,1,108000010
+14324,1,109000010
+14325,1,110000010
+14326,2,101000020
+14327,2,101000030
+14328,2,102000020
+14329,2,102000030
+14330,2,102000040
+14331,2,103000020
+14332,2,103000030
+14333,2,103000040
+14334,2,104000020
+14335,2,104000030
+14336,2,104000040
+14337,2,105000020
+14338,2,105000030
+14339,2,105000040
+14340,2,106000020
+14341,2,106000030
+14342,2,106000040
+14343,2,107000020
+14344,2,107000030
+14345,2,107000040
+14346,2,108000020
+14347,2,108000030
+14348,2,108000040
+14349,2,109000020
+14350,2,109000030
+14351,2,109000040
+14352,2,110000020
+14353,2,110000030
+14354,2,110000040
+14355,2,118000010
+14356,3,101000050
+14357,3,101000060
+14358,3,101000080
+14359,3,101000040
+14360,3,109000060
+14361,3,109000070
+14362,3,109000080
+14363,3,105000060
+14364,3,105000070
+14365,3,105000080
+14366,3,104000050
+14367,3,106000050
+14368,3,102000060
+14369,3,102000070
+14370,3,102000080
+14371,3,103000050
+14372,3,105000050
+14373,3,107000060
+14374,3,107000070
+14375,3,107000080
+14376,3,108000050
+14377,3,109000050
+14378,3,103000060
+14379,3,103000070
+14380,3,103000080
+14381,3,110000050
+14382,3,106000060
+14383,3,106000070
+14384,3,106000080
+14385,3,101000070
+14386,3,110000060
+14387,3,104000060
+14388,3,104000070
+14389,3,104000080
+14390,3,102000050
+14391,3,104000170
+14392,3,104000260
+14393,3,111000010
+14394,3,111000020
+14395,3,111000030
+14396,3,112000020
+14397,3,112000030
+14398,3,108000060
+14399,3,108000070
+14400,3,108000080
+14401,3,107000050
+14402,3,112000010
+14403,3,110000070
+14404,3,110000080
+14405,3,118000020
+14406,3,118000030
+14407,3,118000040
+14408,4,101000090
+14409,4,101000100
+14410,4,101000110
+14411,4,109000100
+14412,4,105000100
+14413,4,105000110
+14414,4,108000090
+14415,4,110000090
+14416,4,102000100
+14417,4,102000110
+14418,4,106000090
+14419,4,109000090
+14420,4,107000100
+14421,4,103000090
+14422,4,102000090
+14423,4,103000100
+14424,4,106000100
+14425,4,106000110
+14426,4,104000090
+14427,4,104000100
+14428,4,104000110
+14429,4,107000090
+14430,4,104000180
+14431,4,111000040
+14432,4,112000040
+14433,4,108000100
+14434,4,105000090
+14435,4,110000100
+14436,4,118000050
+14437,4,118000060
+14438,5,101000120
+14439,5,109000110
+14440,5,105000120
+14441,5,102000120
+14442,5,107000110
+14443,5,103000120
+14444,5,106000120
+14445,5,104000120
+14446,5,104000190
+14447,5,111000060
+14448,5,112000060
+14449,5,108000110
+14450,5,110000110
+14451,5,118000070
+14452,1,201000010
+14453,1,292000010
+14454,1,299000040
+14455,1,299000070
+14456,1,299000110
+14457,1,299000120
+14458,1,299000140
+14459,2,202000010
+14460,2,290000010
+14461,2,299000010
+14462,2,299000150
+14463,2,299000190
+14464,2,299000200
+14465,2,299000210
+14466,3,298000050
+14467,3,298000060
+14468,3,299000060
+14469,3,299000170
+14470,3,290000120
+14471,3,291000050
+14472,3,292000020
+14473,4,299000670
+14474,4,299000680
+14475,4,204000010
+14476,4,209000040
+14477,4,202000070
+14478,4,209000070
+14479,4,203000110
+14480,4,290000110
+14481,4,206000110
+14482,5,297000100
+14483,5,291000020
+14484,5,297000130
+14485,5,297000140
+14486,5,203000010
+14487,5,206000030
+14488,5,203000050
+14489,5,202000090
+14490,5,204000080
+14491,5,202000150
+14492,5,204000100
+14493,1,170002
+14494,1,180002
+14495,2,170003
+14496,2,180003
+14497,3,170004
+14498,3,180004
+14499,4,140000
+14500,5,150010
+14501,5,150020
+14502,5,150030
+14503,5,150040
+14505,1,101000010
+14506,1,102000010
+14507,1,103000010
+14508,1,104000010
+14509,1,105000010
+14510,1,106000010
+14511,1,107000010
+14512,1,108000010
+14513,1,109000010
+14514,1,110000010
+14515,2,101000020
+14516,2,101000030
+14517,2,102000020
+14518,2,102000030
+14519,2,102000040
+14520,2,103000020
+14521,2,103000030
+14522,2,103000040
+14523,2,104000020
+14524,2,104000030
+14525,2,104000040
+14526,2,105000020
+14527,2,105000030
+14528,2,105000040
+14529,2,106000020
+14530,2,106000030
+14531,2,106000040
+14532,2,107000020
+14533,2,107000030
+14534,2,107000040
+14535,2,108000020
+14536,2,108000030
+14537,2,108000040
+14538,2,109000020
+14539,2,109000030
+14540,2,109000040
+14541,2,110000020
+14542,2,110000030
+14543,2,110000040
+14544,2,118000010
+14545,3,101000050
+14546,3,101000060
+14547,3,101000080
+14548,3,101000040
+14549,3,109000060
+14550,3,109000070
+14551,3,109000080
+14552,3,105000060
+14553,3,105000070
+14554,3,105000080
+14555,3,104000050
+14556,3,106000050
+14557,3,102000060
+14558,3,102000070
+14559,3,102000080
+14560,3,103000050
+14561,3,105000050
+14562,3,107000060
+14563,3,107000070
+14564,3,107000080
+14565,3,108000050
+14566,3,109000050
+14567,3,103000060
+14568,3,103000070
+14569,3,103000080
+14570,3,110000050
+14571,3,106000060
+14572,3,106000070
+14573,3,106000080
+14574,3,101000070
+14575,3,110000060
+14576,3,104000060
+14577,3,104000070
+14578,3,104000080
+14579,3,102000050
+14580,3,104000170
+14581,3,104000260
+14582,3,111000010
+14583,3,111000020
+14584,3,111000030
+14585,3,112000020
+14586,3,112000030
+14587,3,108000060
+14588,3,108000070
+14589,3,108000080
+14590,3,107000050
+14591,3,112000010
+14592,3,110000070
+14593,3,110000080
+14594,3,118000020
+14595,3,118000030
+14596,3,118000040
+14597,4,101000090
+14598,4,101000100
+14599,4,101000110
+14600,4,109000100
+14601,4,105000100
+14602,4,105000110
+14603,4,108000090
+14604,4,110000090
+14605,4,102000100
+14606,4,102000110
+14607,4,106000090
+14608,4,109000090
+14609,4,107000100
+14610,4,103000090
+14611,4,102000090
+14612,4,103000100
+14613,4,106000100
+14614,4,106000110
+14615,4,104000090
+14616,4,104000100
+14617,4,104000110
+14618,4,107000090
+14619,4,104000180
+14620,4,111000040
+14621,4,112000040
+14622,4,108000100
+14623,4,105000090
+14624,4,110000100
+14625,4,118000050
+14626,4,118000060
+14627,5,101000120
+14628,5,109000110
+14629,5,105000120
+14630,5,102000120
+14631,5,107000110
+14632,5,103000120
+14633,5,106000120
+14634,5,104000120
+14635,5,104000190
+14636,5,111000060
+14637,5,112000060
+14638,5,108000110
+14639,5,110000110
+14640,5,118000070
+14641,1,201000010
+14642,1,292000010
+14643,1,299000040
+14644,1,299000070
+14645,1,299000110
+14646,1,299000120
+14647,1,299000140
+14648,2,202000010
+14649,2,290000010
+14650,2,299000010
+14651,2,299000150
+14652,2,299000190
+14653,2,299000200
+14654,2,299000210
+14655,3,298000050
+14656,3,298000060
+14657,3,299000060
+14658,3,299000170
+14659,3,290000120
+14660,3,291000050
+14661,3,292000020
+14662,4,299000670
+14663,4,299000680
+14664,4,204000010
+14665,4,209000040
+14666,4,202000070
+14667,4,209000070
+14668,4,203000110
+14669,4,290000110
+14670,4,206000110
+14671,5,297000100
+14672,5,291000020
+14673,5,297000130
+14674,5,297000140
+14675,5,203000010
+14676,5,206000030
+14677,5,203000050
+14678,5,202000090
+14679,5,204000080
+14680,5,202000150
+14681,5,204000100
+14682,2,170003
+14683,2,180003
+14684,3,170004
+14685,3,180004
+14686,4,140000
+14687,5,150010
+14688,5,150020
+14689,5,150030
+14690,5,150040
+14692,3,101000050
+14693,3,101000060
+14694,3,101000080
+14695,3,101000040
+14696,3,109000060
+14697,3,109000070
+14698,3,109000080
+14699,3,105000060
+14700,3,105000070
+14701,3,105000080
+14702,3,104000050
+14703,3,106000050
+14704,3,102000060
+14705,3,102000070
+14706,3,102000080
+14707,3,103000050
+14708,3,105000050
+14709,3,107000060
+14710,3,107000070
+14711,3,107000080
+14712,3,108000050
+14713,3,109000050
+14714,3,103000060
+14715,3,103000070
+14716,3,103000080
+14717,3,110000050
+14718,3,106000060
+14719,3,106000070
+14720,3,106000080
+14721,3,101000070
+14722,3,110000060
+14723,3,104000060
+14724,3,104000070
+14725,3,104000080
+14726,3,102000050
+14727,3,104000170
+14728,3,104000260
+14729,3,111000010
+14730,3,111000020
+14731,3,111000030
+14732,3,112000020
+14733,3,112000030
+14734,3,108000060
+14735,3,108000070
+14736,3,108000080
+14737,3,107000050
+14738,3,112000010
+14739,3,110000070
+14740,3,110000080
+14741,3,118000020
+14742,3,118000030
+14743,3,118000040
+14744,4,101000090
+14745,4,101000100
+14746,4,101000110
+14747,4,109000100
+14748,4,105000100
+14749,4,105000110
+14750,4,108000090
+14751,4,110000090
+14752,4,102000100
+14753,4,102000110
+14754,4,106000090
+14755,4,109000090
+14756,4,107000100
+14757,4,103000090
+14758,4,102000090
+14759,4,103000100
+14760,4,106000100
+14761,4,106000110
+14762,4,104000090
+14763,4,104000100
+14764,4,104000110
+14765,4,107000090
+14766,4,104000180
+14767,4,111000040
+14768,4,112000040
+14769,4,108000100
+14770,4,105000090
+14771,4,110000100
+14772,4,118000050
+14773,4,118000060
+14774,5,101000120
+14775,5,109000110
+14776,5,105000120
+14777,5,102000120
+14778,5,107000110
+14779,5,103000120
+14780,5,106000120
+14781,5,104000120
+14782,5,104000190
+14783,5,111000060
+14784,5,112000060
+14785,5,108000110
+14786,5,110000110
+14787,5,118000070
+14788,1,201000010
+14789,1,292000010
+14790,1,299000040
+14791,1,299000070
+14792,1,299000110
+14793,1,299000120
+14794,1,299000140
+14795,2,202000010
+14796,2,290000010
+14797,2,299000010
+14798,2,299000150
+14799,2,299000190
+14800,2,299000200
+14801,2,299000210
+14802,3,298000050
+14803,3,298000060
+14804,3,299000060
+14805,3,299000170
+14806,3,290000120
+14807,3,291000050
+14808,3,292000020
+14809,4,299000670
+14810,4,299000680
+14811,4,204000010
+14812,4,209000040
+14813,4,202000070
+14814,4,209000070
+14815,4,203000110
+14816,4,290000110
+14817,4,206000110
+14818,5,297000100
+14819,5,291000020
+14820,5,297000130
+14821,5,297000140
+14822,5,203000010
+14823,5,206000030
+14824,5,203000050
+14825,5,202000090
+14826,5,204000080
+14827,5,202000150
+14828,5,204000100
+14829,3,170004
+14830,3,180004
+14831,4,140000
+14832,5,150010
+14833,5,150020
+14834,5,150030
+14835,5,150040
+14837,3,101000050
+14838,3,101000060
+14839,3,101000080
+14840,3,101000040
+14841,3,109000060
+14842,3,109000070
+14843,3,109000080
+14844,3,105000060
+14845,3,105000070
+14846,3,105000080
+14847,3,104000050
+14848,3,106000050
+14849,3,102000060
+14850,3,102000070
+14851,3,102000080
+14852,3,103000050
+14853,3,105000050
+14854,3,107000060
+14855,3,107000070
+14856,3,107000080
+14857,3,108000050
+14858,3,109000050
+14859,3,103000060
+14860,3,103000070
+14861,3,103000080
+14862,3,110000050
+14863,3,106000060
+14864,3,106000070
+14865,3,106000080
+14866,3,101000070
+14867,3,110000060
+14868,3,104000060
+14869,3,104000070
+14870,3,104000080
+14871,3,102000050
+14872,3,104000170
+14873,3,104000260
+14874,3,111000010
+14875,3,111000020
+14876,3,111000030
+14877,3,112000020
+14878,3,112000030
+14879,3,108000060
+14880,3,108000070
+14881,3,108000080
+14882,3,107000050
+14883,3,112000010
+14884,3,110000070
+14885,3,110000080
+14886,3,118000020
+14887,3,118000030
+14888,3,118000040
+14889,4,101000090
+14890,4,101000100
+14891,4,101000110
+14892,4,109000100
+14893,4,105000100
+14894,4,105000110
+14895,4,108000090
+14896,4,110000090
+14897,4,102000100
+14898,4,102000110
+14899,4,106000090
+14900,4,109000090
+14901,4,107000100
+14902,4,103000090
+14903,4,102000090
+14904,4,103000100
+14905,4,106000100
+14906,4,106000110
+14907,4,104000090
+14908,4,104000100
+14909,4,104000110
+14910,4,107000090
+14911,4,104000180
+14912,4,111000040
+14913,4,112000040
+14914,4,108000100
+14915,4,105000090
+14916,4,110000100
+14917,4,118000050
+14918,4,118000060
+14919,5,101000120
+14920,5,109000110
+14921,5,105000120
+14922,5,102000120
+14923,5,107000110
+14924,5,103000120
+14925,5,106000120
+14926,5,104000120
+14927,5,104000190
+14928,5,111000060
+14929,5,112000060
+14930,5,108000110
+14931,5,110000110
+14932,5,118000070
+14933,1,201000010
+14934,1,292000010
+14935,1,299000040
+14936,1,299000070
+14937,1,299000110
+14938,1,299000120
+14939,1,299000140
+14940,2,202000010
+14941,2,290000010
+14942,2,299000010
+14943,2,299000150
+14944,2,299000190
+14945,2,299000200
+14946,2,299000210
+14947,3,298000050
+14948,3,298000060
+14949,3,299000060
+14950,3,299000170
+14951,3,290000120
+14952,3,291000050
+14953,3,292000020
+14954,4,299000670
+14955,4,299000680
+14956,4,204000010
+14957,4,209000040
+14958,4,202000070
+14959,4,209000070
+14960,4,203000110
+14961,4,290000110
+14962,4,206000110
+14963,5,297000100
+14964,5,291000020
+14965,5,297000130
+14966,5,297000140
+14967,5,203000010
+14968,5,206000030
+14969,5,203000050
+14970,5,202000090
+14971,5,204000080
+14972,5,202000150
+14973,5,204000100
+14974,3,170004
+14975,3,180004
+14976,4,140000
+14977,5,150010
+14978,5,150020
+14979,5,150030
+14980,5,150040
+14982,3,101000050
+14983,3,101000060
+14984,3,101000080
+14985,3,101000040
+14986,3,109000060
+14987,3,109000070
+14988,3,109000080
+14989,3,105000060
+14990,3,105000070
+14991,3,105000080
+14992,3,104000050
+14993,3,106000050
+14994,3,102000060
+14995,3,102000070
+14996,3,102000080
+14997,3,103000050
+14998,3,105000050
+14999,3,107000060
+15000,3,107000070
+15001,3,107000080
+15002,3,108000050
+15003,3,109000050
+15004,3,103000060
+15005,3,103000070
+15006,3,103000080
+15007,3,110000050
+15008,3,106000060
+15009,3,106000070
+15010,3,106000080
+15011,3,101000070
+15012,3,110000060
+15013,3,104000060
+15014,3,104000070
+15015,3,104000080
+15016,3,102000050
+15017,3,104000170
+15018,3,104000260
+15019,3,111000010
+15020,3,111000020
+15021,3,111000030
+15022,3,112000020
+15023,3,112000030
+15024,3,108000060
+15025,3,108000070
+15026,3,108000080
+15027,3,107000050
+15028,3,112000010
+15029,3,110000070
+15030,3,110000080
+15031,3,118000020
+15032,3,118000030
+15033,3,118000040
+15034,4,101000090
+15035,4,101000100
+15036,4,101000110
+15037,4,109000100
+15038,4,105000100
+15039,4,105000110
+15040,4,108000090
+15041,4,110000090
+15042,4,102000100
+15043,4,102000110
+15044,4,106000090
+15045,4,109000090
+15046,4,107000100
+15047,4,103000090
+15048,4,102000090
+15049,4,103000100
+15050,4,106000100
+15051,4,106000110
+15052,4,104000090
+15053,4,104000100
+15054,4,104000110
+15055,4,107000090
+15056,4,104000180
+15057,4,111000040
+15058,4,112000040
+15059,4,108000100
+15060,4,105000090
+15061,4,110000100
+15062,4,118000050
+15063,4,118000060
+15064,5,101000120
+15065,5,109000110
+15066,5,105000120
+15067,5,102000120
+15068,5,107000110
+15069,5,103000120
+15070,5,106000120
+15071,5,104000120
+15072,5,104000190
+15073,5,111000060
+15074,5,112000060
+15075,5,108000110
+15076,5,110000110
+15077,5,118000070
+15078,1,201000010
+15079,1,292000010
+15080,1,299000040
+15081,1,299000070
+15082,1,299000110
+15083,1,299000120
+15084,1,299000140
+15085,2,202000010
+15086,2,290000010
+15087,2,299000010
+15088,2,299000150
+15089,2,299000190
+15090,2,299000200
+15091,2,299000210
+15092,3,298000050
+15093,3,298000060
+15094,3,299000060
+15095,3,299000170
+15096,3,290000120
+15097,3,291000050
+15098,3,292000020
+15099,4,299000670
+15100,4,299000680
+15101,4,204000010
+15102,4,209000040
+15103,4,202000070
+15104,4,209000070
+15105,4,203000110
+15106,4,290000110
+15107,4,206000110
+15108,5,297000100
+15109,5,291000020
+15110,5,297000130
+15111,5,297000140
+15112,5,203000010
+15113,5,206000030
+15114,5,203000050
+15115,5,202000090
+15116,5,204000080
+15117,5,202000150
+15118,5,204000100
+15119,3,170004
+15120,3,180004
+15121,4,140000
+15122,5,150010
+15123,5,150020
+15124,5,150030
+15125,5,150040
+15126,5,190000
+15127,5,200000
+15128,5,210000
+15130,3,111000010
+15131,3,111000020
+15132,3,111000030
+15133,3,112000020
+15134,3,112000030
+15135,3,108000060
+15136,3,108000070
+15137,3,108000080
+15138,3,107000050
+15139,3,112000010
+15140,3,110000070
+15141,3,110000080
+15142,4,111000040
+15143,4,112000040
+15144,4,108000100
+15145,4,105000090
+15146,4,110000100
+15147,5,111000060
+15148,5,112000060
+15149,5,108000110
+15150,5,110000110
+15151,1,108000000
+15152,2,108000001
+15153,3,108000002
+15154,4,108000003
+15155,5,108000004
+15156,1,107000000
+15157,2,107000001
+15158,3,107000002
+15159,4,107000003
+15160,5,107000004
+15161,1,120000000
+15162,2,120000001
+15163,3,120000002
+15164,4,120000003
+15165,5,120000004
+15166,3,170004
+15167,4,170005
+15168,3,180004
+15169,4,180005
+15170,4,140000
+15171,4,150010
+15172,4,150020
+15173,4,150030
+15174,4,150040
+15176,3,101000050
+15177,3,101000060
+15178,3,101000080
+15179,3,101000040
+15180,3,109000060
+15181,3,109000070
+15182,3,109000080
+15183,3,105000060
+15184,3,105000070
+15185,3,105000080
+15186,3,104000050
+15187,3,106000050
+15188,4,101000090
+15189,4,101000100
+15190,4,101000110
+15191,4,109000100
+15192,4,105000100
+15193,4,105000110
+15194,4,108000090
+15195,4,110000090
+15196,5,101000120
+15197,5,109000110
+15198,5,105000120
+15199,1,101000000
+15200,2,101000001
+15201,3,101000002
+15202,4,101000008
+15203,5,101000004
+15204,1,109000000
+15205,2,109000001
+15206,3,109000002
+15207,4,109000003
+15208,5,109000004
+15209,4,110024
+15210,4,110034
+15211,4,110044
+15212,4,110054
+15213,3,110060
+15214,3,110070
+15215,3,110080
+15216,3,110090
+15217,3,110100
+15218,3,110110
+15219,3,110120
+15220,3,110130
+15221,3,110140
+15222,3,110150
+15223,3,110160
+15224,3,110170
+15225,3,110180
+15226,3,110190
+15227,3,110200
+15228,3,110210
+15229,3,110220
+15230,3,110230
+15231,3,110240
+15232,3,110250
+15233,3,110260
+15234,3,110270
+15235,3,110620
+15236,3,110670
+15237,4,140000
+15238,4,150010
+15239,4,150020
+15240,4,150030
+15241,4,150040
+15243,3,102000060
+15244,3,102000070
+15245,3,102000080
+15246,3,103000050
+15247,3,105000050
+15248,3,107000060
+15249,3,107000070
+15250,3,107000080
+15251,3,108000050
+15252,3,109000050
+15253,3,103000060
+15254,3,103000070
+15255,3,103000080
+15256,3,110000050
+15257,4,102000100
+15258,4,102000110
+15259,4,102000350
+15260,4,106000090
+15261,4,109000090
+15262,4,107000100
+15263,4,103000090
+15264,4,102000090
+15265,4,103000100
+15266,5,102000120
+15267,5,107000110
+15268,5,103000120
+15269,1,102000000
+15270,2,102000001
+15271,3,102000002
+15272,4,102000003
+15273,5,102000004
+15274,1,105000000
+15275,2,105000001
+15276,3,105000002
+15277,4,105000003
+15278,5,105000004
+15279,1,112000000
+15280,2,112000001
+15281,3,112000002
+15282,4,112000003
+15283,5,112000004
+15284,4,120024
+15285,4,120034
+15286,4,120044
+15287,4,120054
+15288,3,120241
+15289,3,120251
+15290,3,120261
+15291,3,120271
+15292,3,120300
+15293,3,120310
+15294,3,120320
+15295,3,120330
+15296,3,120340
+15297,3,120350
+15298,3,120360
+15299,3,120370
+15300,3,120380
+15301,3,120390
+15302,3,120400
+15303,3,120410
+15304,3,120420
+15305,3,120430
+15306,3,120450
+15307,3,120460
+15308,3,120550
+15309,3,120560
+15310,3,120570
+15311,3,120990
+15312,3,121000
+15313,3,121010
+15314,3,121020
+15315,3,121100
+15316,4,140000
+15317,4,150010
+15318,4,150020
+15319,4,150030
+15320,4,150040
+15322,3,118000020
+15323,3,118000030
+15324,3,118000040
+15325,3,106000060
+15326,3,106000070
+15327,3,106000080
+15328,3,101000070
+15329,3,110000060
+15330,3,104000060
+15331,3,104000070
+15332,3,104000080
+15333,3,102000050
+15334,3,104000170
+15335,3,104000260
+15336,4,118000050
+15337,4,118000060
+15338,4,106000100
+15339,4,106000110
+15340,4,104000090
+15341,4,104000100
+15342,4,104000110
+15343,4,104000270
+15344,4,107000090
+15345,4,104000180
+15346,5,118000070
+15347,5,106000120
+15348,5,104000120
+15349,5,104000190
+15350,1,103000000
+15351,2,103000001
+15352,3,103000002
+15353,4,103000003
+15354,5,103000004
+15355,1,111000000
+15356,2,111000001
+15357,3,111000002
+15358,4,111000003
+15359,5,111000004
+15360,1,115000000
+15361,2,115000001
+15362,3,115000002
+15363,4,115000003
+15364,5,115000004
+15365,4,130024
+15366,4,130034
+15367,4,130044
+15368,4,130054
+15369,3,130060
+15370,3,130070
+15371,3,130080
+15372,3,130090
+15373,3,130100
+15374,3,130110
+15375,3,130120
+15376,3,130130
+15377,3,130140
+15378,3,130150
+15379,3,130160
+15380,3,130170
+15381,3,130180
+15382,3,130190
+15383,3,130200
+15384,3,130420
+15385,3,130510
+15386,3,130520
+15387,3,130531
+15388,3,130540
+15389,3,130660
+15390,3,130700
+15391,3,130790
+15392,3,130800
+15393,3,131130
+15394,4,140000
+15395,4,150010
+15396,4,150020
+15397,4,150030
+15398,4,150040
+15400,1,101000010
+15401,1,102000010
+15402,1,103000010
+15403,1,104000010
+15404,1,105000010
+15405,1,106000010
+15406,1,107000010
+15407,1,108000010
+15408,1,109000010
+15409,1,110000010
+15410,2,101000020
+15411,2,101000030
+15412,2,102000020
+15413,2,102000030
+15414,2,102000040
+15415,2,103000020
+15416,2,103000030
+15417,2,103000040
+15418,2,104000020
+15419,2,104000030
+15420,2,104000040
+15421,2,105000020
+15422,2,105000030
+15423,2,105000040
+15424,2,106000020
+15425,2,106000030
+15426,2,106000040
+15427,2,107000020
+15428,2,107000030
+15429,2,107000040
+15430,2,108000020
+15431,2,108000030
+15432,2,108000040
+15433,2,109000020
+15434,2,109000030
+15435,2,109000040
+15436,2,110000020
+15437,2,110000030
+15438,2,110000040
+15439,2,118000010
+15440,3,101000050
+15441,3,101000060
+15442,3,101000080
+15443,3,101000040
+15444,3,109000060
+15445,3,109000070
+15446,3,109000080
+15447,3,105000060
+15448,3,105000070
+15449,3,105000080
+15450,3,104000050
+15451,3,106000050
+15452,3,102000060
+15453,3,102000070
+15454,3,102000080
+15455,3,103000050
+15456,3,105000050
+15457,3,107000060
+15458,3,107000070
+15459,3,107000080
+15460,3,108000050
+15461,3,109000050
+15462,3,103000060
+15463,3,103000070
+15464,3,103000080
+15465,3,110000050
+15466,3,106000060
+15467,3,106000070
+15468,3,106000080
+15469,3,101000070
+15470,3,110000060
+15471,3,104000060
+15472,3,104000070
+15473,3,104000080
+15474,3,102000050
+15475,3,104000170
+15476,3,104000260
+15477,3,111000010
+15478,3,111000020
+15479,3,111000030
+15480,3,112000020
+15481,3,112000030
+15482,3,108000060
+15483,3,108000070
+15484,3,108000080
+15485,3,107000050
+15486,3,112000010
+15487,3,110000070
+15488,3,110000080
+15489,3,118000020
+15490,3,118000030
+15491,3,118000040
+15492,4,101000090
+15493,4,101000100
+15494,4,101000110
+15495,4,109000100
+15496,4,105000100
+15497,4,105000110
+15498,4,108000090
+15499,4,110000090
+15500,4,102000100
+15501,4,102000110
+15502,4,106000090
+15503,4,109000090
+15504,4,107000100
+15505,4,103000090
+15506,4,102000090
+15507,4,103000100
+15508,4,106000100
+15509,4,106000110
+15510,4,104000090
+15511,4,104000100
+15512,4,104000110
+15513,4,107000090
+15514,4,104000180
+15515,4,111000040
+15516,4,112000040
+15517,4,108000100
+15518,4,105000090
+15519,4,110000100
+15520,4,118000050
+15521,4,118000060
+15522,5,101000120
+15523,5,109000110
+15524,5,105000120
+15525,5,102000120
+15526,5,107000110
+15527,5,103000120
+15528,5,106000120
+15529,5,104000120
+15530,5,104000190
+15531,5,111000060
+15532,5,112000060
+15533,5,108000110
+15534,5,110000110
+15535,5,118000070
+15536,1,201000010
+15537,1,292000010
+15538,1,299000040
+15539,1,299000070
+15540,1,299000110
+15541,1,299000120
+15542,1,299000140
+15543,2,202000010
+15544,2,290000010
+15545,2,299000010
+15546,2,299000150
+15547,2,299000190
+15548,2,299000200
+15549,2,299000210
+15550,3,298000050
+15551,3,298000060
+15552,3,299000060
+15553,3,299000170
+15554,3,290000120
+15555,3,291000050
+15556,3,292000020
+15557,4,299000670
+15558,4,299000680
+15559,4,204000010
+15560,4,209000040
+15561,4,202000070
+15562,4,209000070
+15563,4,203000110
+15564,4,290000110
+15565,4,206000110
+15566,4,209000160
+15567,5,297000100
+15568,5,291000020
+15569,5,297000130
+15570,5,297000140
+15571,5,203000010
+15572,5,206000030
+15573,5,203000050
+15574,5,202000090
+15575,5,204000080
+15576,5,202000150
+15577,5,204000100
+15578,5,206000170
+15579,1,170002
+15580,1,180002
+15581,2,170003
+15582,2,180003
+15583,3,170004
+15584,3,180004
+15585,4,140000
+15586,5,150010
+15587,5,150020
+15588,5,150030
+15589,5,150040
+15591,1,101000010
+15592,1,102000010
+15593,1,103000010
+15594,1,104000010
+15595,1,105000010
+15596,1,106000010
+15597,1,107000010
+15598,1,108000010
+15599,1,109000010
+15600,1,110000010
+15601,2,101000020
+15602,2,101000030
+15603,2,102000020
+15604,2,102000030
+15605,2,102000040
+15606,2,103000020
+15607,2,103000030
+15608,2,103000040
+15609,2,104000020
+15610,2,104000030
+15611,2,104000040
+15612,2,105000020
+15613,2,105000030
+15614,2,105000040
+15615,2,106000020
+15616,2,106000030
+15617,2,106000040
+15618,2,107000020
+15619,2,107000030
+15620,2,107000040
+15621,2,108000020
+15622,2,108000030
+15623,2,108000040
+15624,2,109000020
+15625,2,109000030
+15626,2,109000040
+15627,2,110000020
+15628,2,110000030
+15629,2,110000040
+15630,2,118000010
+15631,3,101000050
+15632,3,101000060
+15633,3,101000080
+15634,3,101000040
+15635,3,109000060
+15636,3,109000070
+15637,3,109000080
+15638,3,105000060
+15639,3,105000070
+15640,3,105000080
+15641,3,104000050
+15642,3,106000050
+15643,3,102000060
+15644,3,102000070
+15645,3,102000080
+15646,3,103000050
+15647,3,105000050
+15648,3,107000060
+15649,3,107000070
+15650,3,107000080
+15651,3,108000050
+15652,3,109000050
+15653,3,103000060
+15654,3,103000070
+15655,3,103000080
+15656,3,110000050
+15657,3,106000060
+15658,3,106000070
+15659,3,106000080
+15660,3,101000070
+15661,3,110000060
+15662,3,104000060
+15663,3,104000070
+15664,3,104000080
+15665,3,102000050
+15666,3,104000170
+15667,3,104000260
+15668,3,111000010
+15669,3,111000020
+15670,3,111000030
+15671,3,112000020
+15672,3,112000030
+15673,3,108000060
+15674,3,108000070
+15675,3,108000080
+15676,3,107000050
+15677,3,112000010
+15678,3,110000070
+15679,3,110000080
+15680,3,118000020
+15681,3,118000030
+15682,3,118000040
+15683,4,101000090
+15684,4,101000100
+15685,4,101000110
+15686,4,109000100
+15687,4,105000100
+15688,4,105000110
+15689,4,108000090
+15690,4,110000090
+15691,4,102000100
+15692,4,102000110
+15693,4,106000090
+15694,4,109000090
+15695,4,107000100
+15696,4,103000090
+15697,4,102000090
+15698,4,103000100
+15699,4,106000100
+15700,4,106000110
+15701,4,104000090
+15702,4,104000100
+15703,4,104000110
+15704,4,107000090
+15705,4,104000180
+15706,4,111000040
+15707,4,112000040
+15708,4,108000100
+15709,4,105000090
+15710,4,110000100
+15711,4,118000050
+15712,4,118000060
+15713,5,101000120
+15714,5,109000110
+15715,5,105000120
+15716,5,102000120
+15717,5,107000110
+15718,5,103000120
+15719,5,106000120
+15720,5,104000120
+15721,5,104000190
+15722,5,111000060
+15723,5,112000060
+15724,5,108000110
+15725,5,110000110
+15726,5,118000070
+15727,1,201000010
+15728,1,292000010
+15729,1,299000040
+15730,1,299000070
+15731,1,299000110
+15732,1,299000120
+15733,1,299000140
+15734,2,202000010
+15735,2,290000010
+15736,2,299000010
+15737,2,299000150
+15738,2,299000190
+15739,2,299000200
+15740,2,299000210
+15741,3,298000050
+15742,3,298000060
+15743,3,299000060
+15744,3,299000170
+15745,3,290000120
+15746,3,291000050
+15747,3,292000020
+15748,4,299000670
+15749,4,299000680
+15750,4,204000010
+15751,4,209000040
+15752,4,202000070
+15753,4,209000070
+15754,4,203000110
+15755,4,290000110
+15756,4,206000110
+15757,4,209000160
+15758,5,297000100
+15759,5,291000020
+15760,5,297000130
+15761,5,297000140
+15762,5,203000010
+15763,5,206000030
+15764,5,203000050
+15765,5,202000090
+15766,5,204000080
+15767,5,202000150
+15768,5,204000100
+15769,5,206000170
+15770,2,170003
+15771,2,180003
+15772,3,170004
+15773,3,180004
+15774,4,140000
+15775,5,150010
+15776,5,150020
+15777,5,150030
+15778,5,150040
+15780,3,101000050
+15781,3,101000060
+15782,3,101000080
+15783,3,101000040
+15784,3,109000060
+15785,3,109000070
+15786,3,109000080
+15787,3,105000060
+15788,3,105000070
+15789,3,105000080
+15790,3,104000050
+15791,3,106000050
+15792,3,102000060
+15793,3,102000070
+15794,3,102000080
+15795,3,103000050
+15796,3,105000050
+15797,3,107000060
+15798,3,107000070
+15799,3,107000080
+15800,3,108000050
+15801,3,109000050
+15802,3,103000060
+15803,3,103000070
+15804,3,103000080
+15805,3,110000050
+15806,3,106000060
+15807,3,106000070
+15808,3,106000080
+15809,3,101000070
+15810,3,110000060
+15811,3,104000060
+15812,3,104000070
+15813,3,104000080
+15814,3,102000050
+15815,3,104000170
+15816,3,104000260
+15817,3,111000010
+15818,3,111000020
+15819,3,111000030
+15820,3,112000020
+15821,3,112000030
+15822,3,108000060
+15823,3,108000070
+15824,3,108000080
+15825,3,107000050
+15826,3,112000010
+15827,3,110000070
+15828,3,110000080
+15829,3,118000020
+15830,3,118000030
+15831,3,118000040
+15832,4,101000090
+15833,4,101000100
+15834,4,101000110
+15835,4,109000100
+15836,4,105000100
+15837,4,105000110
+15838,4,108000090
+15839,4,110000090
+15840,4,102000100
+15841,4,102000110
+15842,4,106000090
+15843,4,109000090
+15844,4,107000100
+15845,4,103000090
+15846,4,102000090
+15847,4,103000100
+15848,4,106000100
+15849,4,106000110
+15850,4,104000090
+15851,4,104000100
+15852,4,104000110
+15853,4,107000090
+15854,4,104000180
+15855,4,111000040
+15856,4,112000040
+15857,4,108000100
+15858,4,105000090
+15859,4,110000100
+15860,4,118000050
+15861,4,118000060
+15862,5,101000120
+15863,5,109000110
+15864,5,105000120
+15865,5,102000120
+15866,5,107000110
+15867,5,103000120
+15868,5,106000120
+15869,5,104000120
+15870,5,104000190
+15871,5,111000060
+15872,5,112000060
+15873,5,108000110
+15874,5,110000110
+15875,5,118000070
+15876,1,201000010
+15877,1,292000010
+15878,1,299000040
+15879,1,299000070
+15880,1,299000110
+15881,1,299000120
+15882,1,299000140
+15883,2,202000010
+15884,2,290000010
+15885,2,299000010
+15886,2,299000150
+15887,2,299000190
+15888,2,299000200
+15889,2,299000210
+15890,3,298000050
+15891,3,298000060
+15892,3,299000060
+15893,3,299000170
+15894,3,290000120
+15895,3,291000050
+15896,3,292000020
+15897,4,299000670
+15898,4,299000680
+15899,4,204000010
+15900,4,209000040
+15901,4,202000070
+15902,4,209000070
+15903,4,203000110
+15904,4,290000110
+15905,4,206000110
+15906,4,209000160
+15907,5,297000100
+15908,5,291000020
+15909,5,297000130
+15910,5,297000140
+15911,5,203000010
+15912,5,206000030
+15913,5,203000050
+15914,5,202000090
+15915,5,204000080
+15916,5,202000150
+15917,5,204000100
+15918,5,206000170
+15919,3,170004
+15920,3,180004
+15921,4,140000
+15922,5,150010
+15923,5,150020
+15924,5,150030
+15925,5,150040
+15927,3,101000050
+15928,3,101000060
+15929,3,101000080
+15930,3,101000040
+15931,3,109000060
+15932,3,109000070
+15933,3,109000080
+15934,3,105000060
+15935,3,105000070
+15936,3,105000080
+15937,3,104000050
+15938,3,106000050
+15939,3,102000060
+15940,3,102000070
+15941,3,102000080
+15942,3,103000050
+15943,3,105000050
+15944,3,107000060
+15945,3,107000070
+15946,3,107000080
+15947,3,108000050
+15948,3,109000050
+15949,3,103000060
+15950,3,103000070
+15951,3,103000080
+15952,3,110000050
+15953,3,106000060
+15954,3,106000070
+15955,3,106000080
+15956,3,101000070
+15957,3,110000060
+15958,3,104000060
+15959,3,104000070
+15960,3,104000080
+15961,3,102000050
+15962,3,104000170
+15963,3,104000260
+15964,3,111000010
+15965,3,111000020
+15966,3,111000030
+15967,3,112000020
+15968,3,112000030
+15969,3,108000060
+15970,3,108000070
+15971,3,108000080
+15972,3,107000050
+15973,3,112000010
+15974,3,110000070
+15975,3,110000080
+15976,3,118000020
+15977,3,118000030
+15978,3,118000040
+15979,4,101000090
+15980,4,101000100
+15981,4,101000110
+15982,4,109000100
+15983,4,105000100
+15984,4,105000110
+15985,4,108000090
+15986,4,110000090
+15987,4,102000100
+15988,4,102000110
+15989,4,106000090
+15990,4,109000090
+15991,4,107000100
+15992,4,103000090
+15993,4,102000090
+15994,4,103000100
+15995,4,106000100
+15996,4,106000110
+15997,4,104000090
+15998,4,104000100
+15999,4,104000110
+16000,4,107000090
+16001,4,104000180
+16002,4,111000040
+16003,4,112000040
+16004,4,108000100
+16005,4,105000090
+16006,4,110000100
+16007,4,118000050
+16008,4,118000060
+16009,5,101000120
+16010,5,109000110
+16011,5,105000120
+16012,5,102000120
+16013,5,107000110
+16014,5,103000120
+16015,5,106000120
+16016,5,104000120
+16017,5,104000190
+16018,5,111000060
+16019,5,112000060
+16020,5,108000110
+16021,5,110000110
+16022,5,118000070
+16023,1,201000010
+16024,1,292000010
+16025,1,299000040
+16026,1,299000070
+16027,1,299000110
+16028,1,299000120
+16029,1,299000140
+16030,2,202000010
+16031,2,290000010
+16032,2,299000010
+16033,2,299000150
+16034,2,299000190
+16035,2,299000200
+16036,2,299000210
+16037,3,298000050
+16038,3,298000060
+16039,3,299000060
+16040,3,299000170
+16041,3,290000120
+16042,3,291000050
+16043,3,292000020
+16044,4,299000670
+16045,4,299000680
+16046,4,204000010
+16047,4,209000040
+16048,4,202000070
+16049,4,209000070
+16050,4,203000110
+16051,4,290000110
+16052,4,206000110
+16053,4,209000160
+16054,5,297000100
+16055,5,291000020
+16056,5,297000130
+16057,5,297000140
+16058,5,203000010
+16059,5,206000030
+16060,5,203000050
+16061,5,202000090
+16062,5,204000080
+16063,5,202000150
+16064,5,204000100
+16065,5,206000170
+16066,3,170004
+16067,3,180004
+16068,4,140000
+16069,5,150010
+16070,5,150020
+16071,5,150030
+16072,5,150040
+16074,3,101000050
+16075,3,101000060
+16076,3,101000080
+16077,3,101000040
+16078,3,109000060
+16079,3,109000070
+16080,3,109000080
+16081,3,105000060
+16082,3,105000070
+16083,3,105000080
+16084,3,104000050
+16085,3,106000050
+16086,3,102000060
+16087,3,102000070
+16088,3,102000080
+16089,3,103000050
+16090,3,105000050
+16091,3,107000060
+16092,3,107000070
+16093,3,107000080
+16094,3,108000050
+16095,3,109000050
+16096,3,103000060
+16097,3,103000070
+16098,3,103000080
+16099,3,110000050
+16100,3,106000060
+16101,3,106000070
+16102,3,106000080
+16103,3,101000070
+16104,3,110000060
+16105,3,104000060
+16106,3,104000070
+16107,3,104000080
+16108,3,102000050
+16109,3,104000170
+16110,3,104000260
+16111,3,111000010
+16112,3,111000020
+16113,3,111000030
+16114,3,112000020
+16115,3,112000030
+16116,3,108000060
+16117,3,108000070
+16118,3,108000080
+16119,3,107000050
+16120,3,112000010
+16121,3,110000070
+16122,3,110000080
+16123,3,118000020
+16124,3,118000030
+16125,3,118000040
+16126,4,101000090
+16127,4,101000100
+16128,4,101000110
+16129,4,109000100
+16130,4,105000100
+16131,4,105000110
+16132,4,108000090
+16133,4,110000090
+16134,4,102000100
+16135,4,102000110
+16136,4,106000090
+16137,4,109000090
+16138,4,107000100
+16139,4,103000090
+16140,4,102000090
+16141,4,103000100
+16142,4,106000100
+16143,4,106000110
+16144,4,104000090
+16145,4,104000100
+16146,4,104000110
+16147,4,107000090
+16148,4,104000180
+16149,4,111000040
+16150,4,112000040
+16151,4,108000100
+16152,4,105000090
+16153,4,110000100
+16154,4,118000050
+16155,4,118000060
+16156,5,101000120
+16157,5,109000110
+16158,5,105000120
+16159,5,102000120
+16160,5,107000110
+16161,5,103000120
+16162,5,106000120
+16163,5,104000120
+16164,5,104000190
+16165,5,111000060
+16166,5,112000060
+16167,5,108000110
+16168,5,110000110
+16169,5,118000070
+16170,1,201000010
+16171,1,292000010
+16172,1,299000040
+16173,1,299000070
+16174,1,299000110
+16175,1,299000120
+16176,1,299000140
+16177,2,202000010
+16178,2,290000010
+16179,2,299000010
+16180,2,299000150
+16181,2,299000190
+16182,2,299000200
+16183,2,299000210
+16184,3,298000050
+16185,3,298000060
+16186,3,299000060
+16187,3,299000170
+16188,3,290000120
+16189,3,291000050
+16190,3,292000020
+16191,4,299000670
+16192,4,299000680
+16193,4,204000010
+16194,4,209000040
+16195,4,202000070
+16196,4,209000070
+16197,4,203000110
+16198,4,290000110
+16199,4,206000110
+16200,4,209000160
+16201,5,297000100
+16202,5,291000020
+16203,5,297000130
+16204,5,297000140
+16205,5,203000010
+16206,5,206000030
+16207,5,203000050
+16208,5,202000090
+16209,5,204000080
+16210,5,202000150
+16211,5,204000100
+16212,5,206000170
+16213,3,170004
+16214,3,180004
+16215,4,140000
+16216,5,150010
+16217,5,150020
+16218,5,150030
+16219,5,150040
+16220,5,190000
+16221,5,200000
+16222,5,210000
+16224,1,101000010
+16225,1,102000010
+16226,1,103000010
+16227,1,104000010
+16228,1,105000010
+16229,1,106000010
+16230,1,107000010
+16231,1,108000010
+16232,1,109000010
+16233,1,110000010
+16234,2,101000020
+16235,2,101000030
+16236,2,102000020
+16237,2,102000030
+16238,2,102000040
+16239,2,103000020
+16240,2,103000030
+16241,2,103000040
+16242,2,104000020
+16243,2,104000030
+16244,2,104000040
+16245,2,105000020
+16246,2,105000030
+16247,2,105000040
+16248,2,106000020
+16249,2,106000030
+16250,2,106000040
+16251,2,107000020
+16252,2,107000030
+16253,2,107000040
+16254,2,108000020
+16255,2,108000030
+16256,2,108000040
+16257,2,109000020
+16258,2,109000030
+16259,2,109000040
+16260,2,110000020
+16261,2,110000030
+16262,2,110000040
+16263,2,118000010
+16264,3,101000050
+16265,3,101000060
+16266,3,101000080
+16267,3,101000040
+16268,3,109000060
+16269,3,109000070
+16270,3,109000080
+16271,3,105000060
+16272,3,105000070
+16273,3,105000080
+16274,3,104000050
+16275,3,106000050
+16276,3,102000060
+16277,3,102000070
+16278,3,102000080
+16279,3,103000050
+16280,3,105000050
+16281,3,107000060
+16282,3,107000070
+16283,3,107000080
+16284,3,108000050
+16285,3,109000050
+16286,3,103000060
+16287,3,103000070
+16288,3,103000080
+16289,3,110000050
+16290,3,106000060
+16291,3,106000070
+16292,3,106000080
+16293,3,101000070
+16294,3,110000060
+16295,3,104000060
+16296,3,104000070
+16297,3,104000080
+16298,3,102000050
+16299,3,104000170
+16300,3,104000260
+16301,3,111000010
+16302,3,111000020
+16303,3,111000030
+16304,3,112000020
+16305,3,112000030
+16306,3,108000060
+16307,3,108000070
+16308,3,108000080
+16309,3,107000050
+16310,3,112000010
+16311,3,110000070
+16312,3,110000080
+16313,3,118000020
+16314,3,118000030
+16315,3,118000040
+16316,4,101000090
+16317,4,101000100
+16318,4,101000110
+16319,4,109000100
+16320,4,105000100
+16321,4,105000110
+16322,4,108000090
+16323,4,110000090
+16324,4,102000100
+16325,4,102000110
+16326,4,106000090
+16327,4,109000090
+16328,4,107000100
+16329,4,103000090
+16330,4,102000090
+16331,4,103000100
+16332,4,106000100
+16333,4,106000110
+16334,4,104000090
+16335,4,104000100
+16336,4,104000110
+16337,4,107000090
+16338,4,104000180
+16339,4,111000040
+16340,4,112000040
+16341,4,108000100
+16342,4,105000090
+16343,4,110000100
+16344,4,118000050
+16345,4,118000060
+16346,5,101000120
+16347,5,109000110
+16348,5,105000120
+16349,5,102000120
+16350,5,107000110
+16351,5,103000120
+16352,5,106000120
+16353,5,104000120
+16354,5,104000190
+16355,5,111000060
+16356,5,112000060
+16357,5,108000110
+16358,5,110000110
+16359,5,118000070
+16360,1,201000010
+16361,1,292000010
+16362,1,299000040
+16363,1,299000070
+16364,1,299000110
+16365,1,299000120
+16366,1,299000140
+16367,2,202000010
+16368,2,290000010
+16369,2,299000010
+16370,2,299000150
+16371,2,299000190
+16372,2,299000200
+16373,2,299000210
+16374,3,298000050
+16375,3,298000060
+16376,3,299000060
+16377,3,299000170
+16378,3,290000120
+16379,3,291000050
+16380,3,292000020
+16381,4,299000670
+16382,4,299000680
+16383,4,204000010
+16384,4,209000040
+16385,4,202000070
+16386,4,209000070
+16387,4,203000110
+16388,4,290000110
+16389,4,206000110
+16390,4,209000160
+16391,4,209000190
+16392,5,297000100
+16393,5,291000020
+16394,5,297000130
+16395,5,297000140
+16396,5,203000010
+16397,5,206000030
+16398,5,203000050
+16399,5,202000090
+16400,5,204000080
+16401,5,202000150
+16402,5,204000100
+16403,5,206000170
+16404,5,204000200
+16405,1,170002
+16406,1,180002
+16407,2,170003
+16408,2,180003
+16409,3,170004
+16410,3,180004
+16411,4,140000
+16412,5,150010
+16413,5,150020
+16414,5,150030
+16415,5,150040
+16417,1,101000010
+16418,1,102000010
+16419,1,103000010
+16420,1,104000010
+16421,1,105000010
+16422,1,106000010
+16423,1,107000010
+16424,1,108000010
+16425,1,109000010
+16426,1,110000010
+16427,2,101000020
+16428,2,101000030
+16429,2,102000020
+16430,2,102000030
+16431,2,102000040
+16432,2,103000020
+16433,2,103000030
+16434,2,103000040
+16435,2,104000020
+16436,2,104000030
+16437,2,104000040
+16438,2,105000020
+16439,2,105000030
+16440,2,105000040
+16441,2,106000020
+16442,2,106000030
+16443,2,106000040
+16444,2,107000020
+16445,2,107000030
+16446,2,107000040
+16447,2,108000020
+16448,2,108000030
+16449,2,108000040
+16450,2,109000020
+16451,2,109000030
+16452,2,109000040
+16453,2,110000020
+16454,2,110000030
+16455,2,110000040
+16456,2,118000010
+16457,3,101000050
+16458,3,101000060
+16459,3,101000080
+16460,3,101000040
+16461,3,109000060
+16462,3,109000070
+16463,3,109000080
+16464,3,105000060
+16465,3,105000070
+16466,3,105000080
+16467,3,104000050
+16468,3,106000050
+16469,3,102000060
+16470,3,102000070
+16471,3,102000080
+16472,3,103000050
+16473,3,105000050
+16474,3,107000060
+16475,3,107000070
+16476,3,107000080
+16477,3,108000050
+16478,3,109000050
+16479,3,103000060
+16480,3,103000070
+16481,3,103000080
+16482,3,110000050
+16483,3,106000060
+16484,3,106000070
+16485,3,106000080
+16486,3,101000070
+16487,3,110000060
+16488,3,104000060
+16489,3,104000070
+16490,3,104000080
+16491,3,102000050
+16492,3,104000170
+16493,3,104000260
+16494,3,111000010
+16495,3,111000020
+16496,3,111000030
+16497,3,112000020
+16498,3,112000030
+16499,3,108000060
+16500,3,108000070
+16501,3,108000080
+16502,3,107000050
+16503,3,112000010
+16504,3,110000070
+16505,3,110000080
+16506,3,118000020
+16507,3,118000030
+16508,3,118000040
+16509,4,101000090
+16510,4,101000100
+16511,4,101000110
+16512,4,109000100
+16513,4,105000100
+16514,4,105000110
+16515,4,108000090
+16516,4,110000090
+16517,4,102000100
+16518,4,102000110
+16519,4,106000090
+16520,4,109000090
+16521,4,107000100
+16522,4,103000090
+16523,4,102000090
+16524,4,103000100
+16525,4,106000100
+16526,4,106000110
+16527,4,104000090
+16528,4,104000100
+16529,4,104000110
+16530,4,107000090
+16531,4,104000180
+16532,4,111000040
+16533,4,112000040
+16534,4,108000100
+16535,4,105000090
+16536,4,110000100
+16537,4,118000050
+16538,4,118000060
+16539,5,101000120
+16540,5,109000110
+16541,5,105000120
+16542,5,102000120
+16543,5,107000110
+16544,5,103000120
+16545,5,106000120
+16546,5,104000120
+16547,5,104000190
+16548,5,111000060
+16549,5,112000060
+16550,5,108000110
+16551,5,110000110
+16552,5,118000070
+16553,1,201000010
+16554,1,292000010
+16555,1,299000040
+16556,1,299000070
+16557,1,299000110
+16558,1,299000120
+16559,1,299000140
+16560,2,202000010
+16561,2,290000010
+16562,2,299000010
+16563,2,299000150
+16564,2,299000190
+16565,2,299000200
+16566,2,299000210
+16567,3,298000050
+16568,3,298000060
+16569,3,299000060
+16570,3,299000170
+16571,3,290000120
+16572,3,291000050
+16573,3,292000020
+16574,4,299000670
+16575,4,299000680
+16576,4,204000010
+16577,4,209000040
+16578,4,202000070
+16579,4,209000070
+16580,4,203000110
+16581,4,290000110
+16582,4,206000110
+16583,4,209000160
+16584,4,209000190
+16585,5,297000100
+16586,5,291000020
+16587,5,297000130
+16588,5,297000140
+16589,5,203000010
+16590,5,206000030
+16591,5,203000050
+16592,5,202000090
+16593,5,204000080
+16594,5,202000150
+16595,5,204000100
+16596,5,206000170
+16597,5,204000200
+16598,2,170003
+16599,2,180003
+16600,3,170004
+16601,3,180004
+16602,4,140000
+16603,5,150010
+16604,5,150020
+16605,5,150030
+16606,5,150040
+16608,3,101000050
+16609,3,101000060
+16610,3,101000080
+16611,3,101000040
+16612,3,109000060
+16613,3,109000070
+16614,3,109000080
+16615,3,105000060
+16616,3,105000070
+16617,3,105000080
+16618,3,104000050
+16619,3,106000050
+16620,3,102000060
+16621,3,102000070
+16622,3,102000080
+16623,3,103000050
+16624,3,105000050
+16625,3,107000060
+16626,3,107000070
+16627,3,107000080
+16628,3,108000050
+16629,3,109000050
+16630,3,103000060
+16631,3,103000070
+16632,3,103000080
+16633,3,110000050
+16634,3,106000060
+16635,3,106000070
+16636,3,106000080
+16637,3,101000070
+16638,3,110000060
+16639,3,104000060
+16640,3,104000070
+16641,3,104000080
+16642,3,102000050
+16643,3,104000170
+16644,3,104000260
+16645,3,111000010
+16646,3,111000020
+16647,3,111000030
+16648,3,112000020
+16649,3,112000030
+16650,3,108000060
+16651,3,108000070
+16652,3,108000080
+16653,3,107000050
+16654,3,112000010
+16655,3,110000070
+16656,3,110000080
+16657,3,118000020
+16658,3,118000030
+16659,3,118000040
+16660,4,101000090
+16661,4,101000100
+16662,4,101000110
+16663,4,109000100
+16664,4,105000100
+16665,4,105000110
+16666,4,108000090
+16667,4,110000090
+16668,4,102000100
+16669,4,102000110
+16670,4,106000090
+16671,4,109000090
+16672,4,107000100
+16673,4,103000090
+16674,4,102000090
+16675,4,103000100
+16676,4,106000100
+16677,4,106000110
+16678,4,104000090
+16679,4,104000100
+16680,4,104000110
+16681,4,107000090
+16682,4,104000180
+16683,4,111000040
+16684,4,112000040
+16685,4,108000100
+16686,4,105000090
+16687,4,110000100
+16688,4,118000050
+16689,4,118000060
+16690,5,101000120
+16691,5,109000110
+16692,5,105000120
+16693,5,102000120
+16694,5,107000110
+16695,5,103000120
+16696,5,106000120
+16697,5,104000120
+16698,5,104000190
+16699,5,111000060
+16700,5,112000060
+16701,5,108000110
+16702,5,110000110
+16703,5,118000070
+16704,1,201000010
+16705,1,292000010
+16706,1,299000040
+16707,1,299000070
+16708,1,299000110
+16709,1,299000120
+16710,1,299000140
+16711,2,202000010
+16712,2,290000010
+16713,2,299000010
+16714,2,299000150
+16715,2,299000190
+16716,2,299000200
+16717,2,299000210
+16718,3,298000050
+16719,3,298000060
+16720,3,299000060
+16721,3,299000170
+16722,3,290000120
+16723,3,291000050
+16724,3,292000020
+16725,4,299000670
+16726,4,299000680
+16727,4,204000010
+16728,4,209000040
+16729,4,202000070
+16730,4,209000070
+16731,4,203000110
+16732,4,290000110
+16733,4,206000110
+16734,4,209000160
+16735,4,209000190
+16736,5,297000100
+16737,5,291000020
+16738,5,297000130
+16739,5,297000140
+16740,5,203000010
+16741,5,206000030
+16742,5,203000050
+16743,5,202000090
+16744,5,204000080
+16745,5,202000150
+16746,5,204000100
+16747,5,206000170
+16748,5,204000200
+16749,3,170004
+16750,3,180004
+16751,4,140000
+16752,5,150010
+16753,5,150020
+16754,5,150030
+16755,5,150040
+16757,3,101000050
+16758,3,101000060
+16759,3,101000080
+16760,3,101000040
+16761,3,109000060
+16762,3,109000070
+16763,3,109000080
+16764,3,105000060
+16765,3,105000070
+16766,3,105000080
+16767,3,104000050
+16768,3,106000050
+16769,3,102000060
+16770,3,102000070
+16771,3,102000080
+16772,3,103000050
+16773,3,105000050
+16774,3,107000060
+16775,3,107000070
+16776,3,107000080
+16777,3,108000050
+16778,3,109000050
+16779,3,103000060
+16780,3,103000070
+16781,3,103000080
+16782,3,110000050
+16783,3,106000060
+16784,3,106000070
+16785,3,106000080
+16786,3,101000070
+16787,3,110000060
+16788,3,104000060
+16789,3,104000070
+16790,3,104000080
+16791,3,102000050
+16792,3,104000170
+16793,3,104000260
+16794,3,111000010
+16795,3,111000020
+16796,3,111000030
+16797,3,112000020
+16798,3,112000030
+16799,3,108000060
+16800,3,108000070
+16801,3,108000080
+16802,3,107000050
+16803,3,112000010
+16804,3,110000070
+16805,3,110000080
+16806,3,118000020
+16807,3,118000030
+16808,3,118000040
+16809,4,101000090
+16810,4,101000100
+16811,4,101000110
+16812,4,109000100
+16813,4,105000100
+16814,4,105000110
+16815,4,108000090
+16816,4,110000090
+16817,4,102000100
+16818,4,102000110
+16819,4,106000090
+16820,4,109000090
+16821,4,107000100
+16822,4,103000090
+16823,4,102000090
+16824,4,103000100
+16825,4,106000100
+16826,4,106000110
+16827,4,104000090
+16828,4,104000100
+16829,4,104000110
+16830,4,107000090
+16831,4,104000180
+16832,4,111000040
+16833,4,112000040
+16834,4,108000100
+16835,4,105000090
+16836,4,110000100
+16837,4,118000050
+16838,4,118000060
+16839,5,101000120
+16840,5,109000110
+16841,5,105000120
+16842,5,102000120
+16843,5,107000110
+16844,5,103000120
+16845,5,106000120
+16846,5,104000120
+16847,5,104000190
+16848,5,111000060
+16849,5,112000060
+16850,5,108000110
+16851,5,110000110
+16852,5,118000070
+16853,1,201000010
+16854,1,292000010
+16855,1,299000040
+16856,1,299000070
+16857,1,299000110
+16858,1,299000120
+16859,1,299000140
+16860,2,202000010
+16861,2,290000010
+16862,2,299000010
+16863,2,299000150
+16864,2,299000190
+16865,2,299000200
+16866,2,299000210
+16867,3,298000050
+16868,3,298000060
+16869,3,299000060
+16870,3,299000170
+16871,3,290000120
+16872,3,291000050
+16873,3,292000020
+16874,4,299000670
+16875,4,299000680
+16876,4,204000010
+16877,4,209000040
+16878,4,202000070
+16879,4,209000070
+16880,4,203000110
+16881,4,290000110
+16882,4,206000110
+16883,4,209000160
+16884,4,209000190
+16885,5,297000100
+16886,5,291000020
+16887,5,297000130
+16888,5,297000140
+16889,5,203000010
+16890,5,206000030
+16891,5,203000050
+16892,5,202000090
+16893,5,204000080
+16894,5,202000150
+16895,5,204000100
+16896,5,206000170
+16897,5,204000200
+16898,3,170004
+16899,3,180004
+16900,4,140000
+16901,5,150010
+16902,5,150020
+16903,5,150030
+16904,5,150040
+16906,3,101000050
+16907,3,101000060
+16908,3,101000080
+16909,3,101000040
+16910,3,109000060
+16911,3,109000070
+16912,3,109000080
+16913,3,105000060
+16914,3,105000070
+16915,3,105000080
+16916,3,104000050
+16917,3,106000050
+16918,3,102000060
+16919,3,102000070
+16920,3,102000080
+16921,3,103000050
+16922,3,105000050
+16923,3,107000060
+16924,3,107000070
+16925,3,107000080
+16926,3,108000050
+16927,3,109000050
+16928,3,103000060
+16929,3,103000070
+16930,3,103000080
+16931,3,110000050
+16932,3,106000060
+16933,3,106000070
+16934,3,106000080
+16935,3,101000070
+16936,3,110000060
+16937,3,104000060
+16938,3,104000070
+16939,3,104000080
+16940,3,102000050
+16941,3,104000170
+16942,3,104000260
+16943,3,111000010
+16944,3,111000020
+16945,3,111000030
+16946,3,112000020
+16947,3,112000030
+16948,3,108000060
+16949,3,108000070
+16950,3,108000080
+16951,3,107000050
+16952,3,112000010
+16953,3,110000070
+16954,3,110000080
+16955,3,118000020
+16956,3,118000030
+16957,3,118000040
+16958,4,101000090
+16959,4,101000100
+16960,4,101000110
+16961,4,109000100
+16962,4,105000100
+16963,4,105000110
+16964,4,108000090
+16965,4,110000090
+16966,4,102000100
+16967,4,102000110
+16968,4,106000090
+16969,4,109000090
+16970,4,107000100
+16971,4,103000090
+16972,4,102000090
+16973,4,103000100
+16974,4,106000100
+16975,4,106000110
+16976,4,104000090
+16977,4,104000100
+16978,4,104000110
+16979,4,107000090
+16980,4,104000180
+16981,4,111000040
+16982,4,112000040
+16983,4,108000100
+16984,4,105000090
+16985,4,110000100
+16986,4,118000050
+16987,4,118000060
+16988,5,101000120
+16989,5,109000110
+16990,5,105000120
+16991,5,102000120
+16992,5,107000110
+16993,5,103000120
+16994,5,106000120
+16995,5,104000120
+16996,5,104000190
+16997,5,111000060
+16998,5,112000060
+16999,5,108000110
+17000,5,110000110
+17001,5,118000070
+17002,1,201000010
+17003,1,292000010
+17004,1,299000040
+17005,1,299000070
+17006,1,299000110
+17007,1,299000120
+17008,1,299000140
+17009,2,202000010
+17010,2,290000010
+17011,2,299000010
+17012,2,299000150
+17013,2,299000190
+17014,2,299000200
+17015,2,299000210
+17016,3,298000050
+17017,3,298000060
+17018,3,299000060
+17019,3,299000170
+17020,3,290000120
+17021,3,291000050
+17022,3,292000020
+17023,4,299000670
+17024,4,299000680
+17025,4,204000010
+17026,4,209000040
+17027,4,202000070
+17028,4,209000070
+17029,4,203000110
+17030,4,290000110
+17031,4,206000110
+17032,4,209000160
+17033,4,209000190
+17034,5,297000100
+17035,5,291000020
+17036,5,297000130
+17037,5,297000140
+17038,5,203000010
+17039,5,206000030
+17040,5,203000050
+17041,5,202000090
+17042,5,204000080
+17043,5,202000150
+17044,5,204000100
+17045,5,206000170
+17046,5,204000200
+17047,3,170004
+17048,3,180004
+17049,4,140000
+17050,5,150010
+17051,5,150020
+17052,5,150030
+17053,5,150040
+17054,5,190000
+17055,5,200000
+17057,3,118000020
+17058,3,118000030
+17059,3,118000040
+17060,3,106000060
+17061,3,106000070
+17062,3,106000080
+17063,3,101000070
+17064,3,110000060
+17065,3,104000060
+17066,3,104000070
+17067,3,104000080
+17068,3,102000050
+17069,3,104000170
+17070,3,104000260
+17071,4,118000050
+17072,4,118000060
+17073,4,106000100
+17074,4,106000110
+17075,4,104000090
+17076,4,104000100
+17077,4,104000110
+17078,4,104000270
+17079,4,107000090
+17080,4,104000180
+17081,5,118000070
+17082,5,106000120
+17083,5,104000120
+17084,5,104000190
+17085,1,103000000
+17086,2,103000001
+17087,3,103000002
+17088,4,103000003
+17089,5,103000004
+17090,1,111000000
+17091,2,111000001
+17092,3,111000002
+17093,4,111000003
+17094,5,111000004
+17095,1,115000000
+17096,2,115000001
+17097,3,115000002
+17098,4,115000003
+17099,5,115000004
+17100,3,170004
+17101,4,170005
+17102,3,180004
+17103,4,180005
+17104,4,140000
+17105,4,150010
+17106,4,150020
+17107,4,150030
+17108,4,150040
+17110,3,111000010
+17111,3,111000020
+17112,3,111000030
+17113,3,112000020
+17114,3,112000030
+17115,3,108000060
+17116,3,108000070
+17117,3,108000080
+17118,3,107000050
+17119,3,112000010
+17120,3,110000070
+17121,3,110000080
+17122,4,111000040
+17123,4,112000040
+17124,4,108000100
+17125,4,105000090
+17126,4,110000100
+17127,5,111000060
+17128,5,112000060
+17129,5,108000110
+17130,5,110000110
+17131,1,108000000
+17132,2,108000001
+17133,3,108000002
+17134,4,108000003
+17135,5,108000004
+17136,1,107000000
+17137,2,107000001
+17138,3,107000002
+17139,4,107000003
+17140,5,107000004
+17141,1,120000000
+17142,2,120000001
+17143,3,120000002
+17144,4,120000003
+17145,5,120000004
+17146,4,110024
+17147,4,110034
+17148,4,110044
+17149,4,110054
+17150,3,110060
+17151,3,110070
+17152,3,110080
+17153,3,110090
+17154,3,110100
+17155,3,110110
+17156,3,110120
+17157,3,110130
+17158,3,110140
+17159,3,110150
+17160,3,110160
+17161,3,110170
+17162,3,110180
+17163,3,110190
+17164,3,110200
+17165,3,110210
+17166,3,110220
+17167,3,110230
+17168,3,110240
+17169,3,110250
+17170,3,110260
+17171,3,110270
+17172,3,110620
+17173,3,110670
+17174,4,140000
+17175,4,150010
+17176,4,150020
+17177,4,150030
+17178,4,150040
+17180,3,101000050
+17181,3,101000060
+17182,3,101000080
+17183,3,101000040
+17184,3,109000060
+17185,3,109000070
+17186,3,109000080
+17187,3,105000060
+17188,3,105000070
+17189,3,105000080
+17190,3,104000050
+17191,3,106000050
+17192,4,101000090
+17193,4,101000100
+17194,4,101000110
+17195,4,109000100
+17196,4,105000100
+17197,4,105000110
+17198,4,108000090
+17199,4,110000090
+17200,5,101000120
+17201,5,109000110
+17202,5,105000120
+17203,1,101000000
+17204,2,101000001
+17205,3,101000002
+17206,4,101000008
+17207,5,101000004
+17208,1,109000000
+17209,2,109000001
+17210,3,109000002
+17211,4,109000003
+17212,5,109000004
+17213,4,120024
+17214,4,120034
+17215,4,120044
+17216,4,120054
+17217,3,120241
+17218,3,120251
+17219,3,120261
+17220,3,120271
+17221,3,120300
+17222,3,120310
+17223,3,120320
+17224,3,120330
+17225,3,120340
+17226,3,120350
+17227,3,120360
+17228,3,120370
+17229,3,120380
+17230,3,120390
+17231,3,120400
+17232,3,120410
+17233,3,120420
+17234,3,120430
+17235,3,120450
+17236,3,120460
+17237,3,120550
+17238,3,120560
+17239,3,120570
+17240,3,120990
+17241,3,121000
+17242,3,121010
+17243,3,121020
+17244,3,121100
+17245,4,140000
+17246,4,150010
+17247,4,150020
+17248,4,150030
+17249,4,150040
+17251,3,102000060
+17252,3,102000070
+17253,3,102000080
+17254,3,103000050
+17255,3,105000050
+17256,3,107000060
+17257,3,107000070
+17258,3,107000080
+17259,3,108000050
+17260,3,109000050
+17261,3,103000060
+17262,3,103000070
+17263,3,103000080
+17264,3,110000050
+17265,4,102000100
+17266,4,102000110
+17267,4,102000350
+17268,4,106000090
+17269,4,109000090
+17270,4,107000100
+17271,4,103000090
+17272,4,102000090
+17273,4,103000100
+17274,5,102000120
+17275,5,107000110
+17276,5,103000120
+17277,1,102000000
+17278,2,102000001
+17279,3,102000002
+17280,4,102000003
+17281,5,102000004
+17282,1,105000000
+17283,2,105000001
+17284,3,105000002
+17285,4,105000003
+17286,5,105000004
+17287,1,112000000
+17288,2,112000001
+17289,3,112000002
+17290,4,112000003
+17291,5,112000004
+17292,4,130024
+17293,4,130034
+17294,4,130044
+17295,4,130054
+17296,3,130060
+17297,3,130070
+17298,3,130080
+17299,3,130090
+17300,3,130100
+17301,3,130110
+17302,3,130120
+17303,3,130130
+17304,3,130140
+17305,3,130150
+17306,3,130160
+17307,3,130170
+17308,3,130180
+17309,3,130190
+17310,3,130200
+17311,3,130420
+17312,3,130510
+17313,3,130520
+17314,3,130531
+17315,3,130540
+17316,3,130660
+17317,3,130700
+17318,3,130790
+17319,3,130800
+17320,3,131130
+17321,4,140000
+17322,4,150010
+17323,4,150020
+17324,4,150030
+17325,4,150040
+17327,4,101000250
+17328,4,102000260
+17329,4,103000220
+17330,4,104000250
+17331,4,105000210
+17332,4,106000210
+17333,4,107000140
+17334,4,108000150
+17335,4,109000230
+17336,4,110000170
+17337,4,111000140
+17338,4,112000110
+17339,4,118000140
+17340,5,101000300
+17341,5,102000360
+17342,5,103000310
+17343,5,104000370
+17344,5,109000290
+17345,5,101000310
+17346,5,102000410
+17347,1,201000010
+17348,1,292000010
+17349,1,299000040
+17350,1,299000070
+17351,1,299000110
+17352,1,299000120
+17353,1,299000140
+17354,2,202000010
+17355,2,290000010
+17356,2,299000010
+17357,2,299000150
+17358,2,299000190
+17359,2,299000200
+17360,2,299000210
+17361,3,290000120
+17362,3,291000050
+17363,3,292000020
+17364,3,298000050
+17365,3,298000060
+17366,3,299000060
+17367,3,299000170
+17368,4,201000170
+17369,4,202000070
+17370,4,202000370
+17371,4,202000400
+17372,4,202000440
+17373,4,203000110
+17374,4,203000270
+17375,4,203000350
+17376,4,204000010
+17377,4,204000370
+17378,4,205000220
+17379,4,206000110
+17380,4,206000240
+17381,4,206000270
+17382,4,209000040
+17383,4,209000070
+17384,4,209000160
+17385,4,209000190
+17386,4,209000240
+17387,4,215000150
+17388,4,290000110
+17389,4,290000130
+17390,4,298000120
+17391,4,299000670
+17392,4,299000680
+17393,4,201000090
+17394,4,202000160
+17395,4,203000150
+17396,4,204000110
+17397,4,205000110
+17398,4,206000120
+17399,4,211000060
+17400,4,212000050
+17401,4,299000440
+17402,4,299000450
+17403,4,299000460
+17404,4,299000470
+17405,4,299000480
+17406,4,299000550
+17407,4,299000560
+17408,4,299000570
+17409,4,299000580
+17410,4,299000590
+17411,4,299000600
+17412,4,299000610
+17413,4,299000620
+17414,4,299000630
+17415,4,299000640
+17416,4,299000650
+17417,4,299000230
+17418,4,299000240
+17419,4,299000250
+17420,4,299000260
+17421,4,299000270
+17422,4,299000280
+17423,4,299000290
+17424,4,299000300
+17425,4,299000310
+17426,4,299000320
+17427,4,299000330
+17428,4,299000340
+17429,4,299000350
+17430,4,299000360
+17431,4,299000370
+17432,4,299000380
+17433,4,299000390
+17434,4,299000400
+17435,4,215000050
+17436,4,216000060
+17437,4,217000020
+17438,4,218000030
+17439,4,299000500
+17440,4,299000510
+17441,4,299000520
+17442,4,299000530
+17443,4,299000540
+17444,4,299000660
+17445,5,202000090
+17446,5,202000150
+17447,5,203000010
+17448,5,203000050
+17449,5,203000260
+17450,5,204000080
+17451,5,204000100
+17452,5,204000200
+17453,5,204000270
+17454,5,206000030
+17455,5,206000170
+17456,5,209000320
+17457,5,220000080
+17458,5,290000160
+17459,5,291000020
+17460,5,297000100
+17461,5,297000130
+17462,5,297000140
+17463,5,298000110
+17464,5,202000290
+17465,5,203000240
+17466,5,204000210
+17467,5,205000150
+17468,5,206000200
+17469,5,211000090
+17470,5,212000060
+17471,5,299000800
+17472,5,299000810
+17473,5,299000820
+17474,5,299000840
+17475,5,299000850
+17476,5,299000860
+17477,5,299000870
+17478,5,299000880
+17479,5,299000890
+17480,5,201000120
+17481,5,202000240
+17482,5,211000080
+17483,5,299000730
+17484,5,299000740
+17485,5,299000750
+17486,5,299000760
+17487,5,299000770
+17488,5,201000130
+17489,5,299000830
+17490,5,202000280
+17491,5,204000220
+17492,5,201000150
+17493,5,202000350
+17494,5,205000200
+17495,5,299001050
+17496,5,299001060
+17497,5,201000200
+17498,5,202000430
+17499,5,211000150
+17500,5,299001170
+17501,5,299001180
+17502,5,202000270
+17503,5,206000190
+17504,5,220000060
+17505,5,201000140
+17506,5,203000230
+17507,5,205000160
+17508,5,204000230
+17509,5,209000200
+17510,5,299000900
+17511,5,202000340
+17512,5,203000280
+17513,5,205000190
+17514,5,208000040
+17515,5,211000110
+17516,5,220000070
+17517,5,202000420
+17518,5,203000340
+17519,5,204000360
+17520,5,211000140
+17521,5,212000090
+17522,5,299000920
+17523,5,299000930
+17524,5,299000940
+17525,5,299000950
+17526,5,299000960
+17527,5,298000130
+17528,5,202000380
+17529,5,203000300
+17530,5,204000320
+17531,5,205000230
+17532,5,206000250
+17533,5,209000280
+17534,5,210000030
+17535,5,211000120
+17536,5,212000070
+17537,5,215000130
+17538,5,216000130
+17539,5,217000080
+17540,5,218000090
+17541,5,299001070
+17542,5,299001080
+17543,5,299001090
+17544,5,215000120
+17545,5,202000390
+17546,5,203000310
+17547,5,204000330
+17548,5,205000240
+17549,5,206000260
+17550,5,209000290
+17551,5,210000040
+17552,5,211000130
+17553,5,212000080
+17554,5,215000140
+17555,5,216000140
+17556,5,217000090
+17557,5,218000100
+17558,5,220000090
+17559,5,299001100
+17560,5,299001110
+17561,5,299001120
+17562,5,299001130
+17563,5,299001140
+17564,5,299001150
+17565,5,299000430
+17566,5,299000690
+17567,5,299000710
+17568,5,299000720
+17569,5,215000100
+17570,5,216000090
+17571,5,217000070
+17572,5,218000080
+17573,5,299000970
+17574,5,299000980
+17575,5,299000990
+17576,5,299001000
+17577,5,299001010
+17578,5,299001020
+17579,5,299001030
+17580,5,299001040
+17581,3,101000006
+17582,3,103000005
+17583,4,101000003
+17584,4,102000005
+17585,4,107000005
+17586,4,112000006
+17587,5,101000009
+17588,5,101000011
+17589,5,101000012
+17590,5,101000013
+17591,5,101000014
+17592,5,101000015
+17593,5,101000016
+17594,5,101000017
+17595,5,101000018
+17596,5,102000008
+17597,5,102000009
+17598,5,107000007
+17599,5,109000008
+17600,5,111000007
+17601,5,111000008
+17602,5,112000008
+17603,5,120000008
+17605,2,118000010
+17606,3,118000020
+17607,3,118000030
+17608,3,118000040
+17609,4,118000050
+17610,4,118000060
+17611,5,118000070
+17612,1,101000000
+17613,3,101000006
+17614,3,103000005
+17615,4,101000003
+17616,4,102000005
+17617,4,107000005
+17618,4,112000006
+17619,5,101000009
+17620,5,101000011
+17621,5,101000012
+17622,5,101000013
+17623,5,101000014
+17624,5,101000015
+17625,5,101000016
+17626,5,101000017
+17627,5,101000018
+17628,5,102000008
+17629,5,102000009
+17630,5,107000007
+17631,5,109000008
+17632,5,111000007
+17633,5,111000008
+17634,5,112000008
+17635,5,120000008
+17636,3,110540
+17637,3,110680
+17638,3,110790
+17639,3,110800
+17640,3,120440
+17641,5,110055
+17642,5,110241
+17643,5,110251
+17644,5,110261
+17645,5,110271
+17646,5,110730
+17647,5,111020
+17648,5,111100
+17649,5,111160
+17650,5,120551
+17651,5,121160
diff --git a/titles/sao/database.py b/titles/sao/database.py
new file mode 100644
index 0000000..463440d
--- /dev/null
+++ b/titles/sao/database.py
@@ -0,0 +1,12 @@
+from core.data import Data
+from core.config import CoreConfig
+
+from .schema import *
+
+
+class SaoData(Data):
+ def __init__(self, cfg: CoreConfig) -> None:
+ super().__init__(cfg)
+
+ self.profile = SaoProfileData(cfg, self.session)
+ self.static = SaoStaticData(cfg, self.session)
\ No newline at end of file
diff --git a/titles/sao/handlers/__init__.py b/titles/sao/handlers/__init__.py
new file mode 100644
index 0000000..90a6b4e
--- /dev/null
+++ b/titles/sao/handlers/__init__.py
@@ -0,0 +1 @@
+from titles.sao.handlers.base import *
\ No newline at end of file
diff --git a/titles/sao/handlers/base.py b/titles/sao/handlers/base.py
new file mode 100644
index 0000000..eea9850
--- /dev/null
+++ b/titles/sao/handlers/base.py
@@ -0,0 +1,2213 @@
+import struct
+from datetime import datetime
+from construct import *
+import sys
+import csv
+
+class SaoBaseRequest:
+ def __init__(self, data: bytes) -> None:
+ self.cmd = struct.unpack_from("!H", bytes)[0]
+ # TODO: The rest of the request header
+
+class SaoBaseResponse:
+ def __init__(self, cmd_id: int) -> None:
+ self.cmd = cmd_id
+ self.err_status = 0
+ self.error_type = 0
+ self.vendor_id = 5
+ self.game_id = 1
+ self.version_id = 1
+ self.length = 1
+
+ def make(self) -> bytes:
+ return struct.pack("!HHIIIII", self.cmd, self.err_status, self.error_type, self.vendor_id, self.game_id, self.version_id, self.length)
+
+class SaoNoopResponse(SaoBaseResponse):
+ def __init__(self, cmd: int) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.length = 5
+
+ def make(self) -> bytes:
+ return super().make() + struct.pack("!bI", self.result, 0)
+
+class SaoGetMaintRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+ # TODO: The rest of the mait info request
+
+class SaoGetMaintResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.maint_begin = datetime.fromtimestamp(0)
+ self.maint_begin_int_ct = 6
+ self.maint_end = datetime.fromtimestamp(0)
+ self.maint_end_int_ct = 6
+ self.dt_format = "%Y%m%d%H%M%S"
+
+ def make(self) -> bytes:
+ maint_begin_list = [x for x in datetime.strftime(self.maint_begin, self.dt_format)]
+ maint_end_list = [x for x in datetime.strftime(self.maint_end, self.dt_format)]
+ self.maint_begin_int_ct = len(maint_begin_list) * 2
+ self.maint_end_int_ct = len(maint_end_list) * 2
+
+ maint_begin_bytes = b""
+ maint_end_bytes = b""
+
+ for x in maint_begin_list:
+ maint_begin_bytes += struct.pack(" None:
+ super().__init__(data)
+
+class SaoCommonAcCabinetBootNotificationResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoMasterDataVersionCheckRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoMasterDataVersionCheckResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.update_flag = 0
+ self.data_version = 100
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "update_flag" / Int8ul, # result is either 0 or 1
+ "data_version" / Int32ub,
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ update_flag=self.update_flag,
+ data_version=self.data_version,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCommonGetAppVersionsRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCommonGetAppVersionsRequest(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.data_list_size = 1 # Number of arrays
+
+ self.version_app_id = 1
+ self.applying_start_date = "20230520193000"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "data_list_size" / Int32ub,
+
+ "version_app_id" / Int32ub,
+ "applying_start_date_size" / Int32ub, # big endian
+ "applying_start_date" / Int16ul[len(self.applying_start_date)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ data_list_size=self.data_list_size,
+
+ version_app_id=self.version_app_id,
+ applying_start_date_size=len(self.applying_start_date) * 2,
+ applying_start_date=[ord(x) for x in self.applying_start_date],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCommonPayingPlayStartRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCommonPayingPlayStartRequest(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.paying_session_id = "1"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "paying_session_id_size" / Int32ub, # big endian
+ "paying_session_id" / Int16ul[len(self.paying_session_id)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ paying_session_id_size=len(self.paying_session_id) * 2,
+ paying_session_id=[ord(x) for x in self.paying_session_id],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetAuthCardDataRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetAuthCardDataResponse(SaoBaseResponse): #GssSite.dll / GssSiteSystem / GameConnectProt / public class get_auth_card_data_R : GameConnect.GssProtocolBase
+ def __init__(self, cmd, profile_data) -> None:
+ super().__init__(cmd)
+
+ self.result = 1
+ self.unused_card_flag = ""
+ self.first_play_flag = 0
+ self.tutorial_complete_flag = 1
+ self.nick_name = profile_data['nick_name'] # nick_name field #4
+ self.personal_id = str(profile_data['user'])
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "unused_card_flag_size" / Int32ub, # big endian
+ "unused_card_flag" / Int16ul[len(self.unused_card_flag)],
+ "first_play_flag" / Int8ul, # result is either 0 or 1
+ "tutorial_complete_flag" / Int8ul, # result is either 0 or 1
+ "nick_name_size" / Int32ub, # big endian
+ "nick_name" / Int16ul[len(self.nick_name)],
+ "personal_id_size" / Int32ub, # big endian
+ "personal_id" / Int16ul[len(self.personal_id)]
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ unused_card_flag_size=len(self.unused_card_flag) * 2,
+ unused_card_flag=[ord(x) for x in self.unused_card_flag],
+ first_play_flag=self.first_play_flag,
+ tutorial_complete_flag=self.tutorial_complete_flag,
+ nick_name_size=len(self.nick_name) * 2,
+ nick_name=[ord(x) for x in self.nick_name],
+ personal_id_size=len(self.personal_id) * 2,
+ personal_id=[ord(x) for x in self.personal_id]
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoHomeCheckAcLoginBonusRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoHomeCheckAcLoginBonusResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.reward_get_flag = 1
+ self.get_ac_login_bonus_id_list_size = 2 # Array
+
+ self.get_ac_login_bonus_id_1 = 1 # "2020年7月9日~(アニメ&リコリス記念)"
+ self.get_ac_login_bonus_id_2 = 2 # "2020年10月6日~(秋のデビュー&カムバックCP)"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "reward_get_flag" / Int8ul, # result is either 0 or 1
+ "get_ac_login_bonus_id_list_size" / Int32ub,
+
+ "get_ac_login_bonus_id_1" / Int32ub,
+ "get_ac_login_bonus_id_2" / Int32ub,
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ reward_get_flag=self.reward_get_flag,
+ get_ac_login_bonus_id_list_size=self.get_ac_login_bonus_id_list_size,
+
+ get_ac_login_bonus_id_1=self.get_ac_login_bonus_id_1,
+ get_ac_login_bonus_id_2=self.get_ac_login_bonus_id_2,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetQuestSceneMultiPlayPhotonServerRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetQuestSceneMultiPlayPhotonServerResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.application_id = "7df3a2f6-d69d-4073-aafe-810ee61e1cea"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "application_id_size" / Int32ub, # big endian
+ "application_id" / Int16ul[len(self.application_id)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ application_id_size=len(self.application_id) * 2,
+ application_id=[ord(x) for x in self.application_id],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoTicketRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoTicketResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = "1"
+ self.ticket_id = "9" #up to 18
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result_size" / Int32ub, # big endian
+ "result" / Int16ul[len(self.result)],
+ "ticket_id_size" / Int32ub, # big endian
+ "ticket_id" / Int16ul[len(self.result)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result_size=len(self.result) * 2,
+ result=[ord(x) for x in self.result],
+ ticket_id_size=len(self.ticket_id) * 2,
+ ticket_id=[ord(x) for x in self.ticket_id],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCommonLoginRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCommonLoginResponse(SaoBaseResponse):
+ def __init__(self, cmd, profile_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.user_id = str(profile_data['user'])
+ self.first_play_flag = 0
+ self.grantable_free_ticket_flag = 1
+ self.login_reward_vp = 99
+ self.today_paying_flag = 1
+
+ def make(self) -> bytes:
+ # create a resp struct
+ '''
+ bool = Int8ul
+ short = Int16ub
+ int = Int32ub
+ '''
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "user_id_size" / Int32ub, # big endian
+ "user_id" / Int16ul[len(self.user_id)],
+ "first_play_flag" / Int8ul, # result is either 0 or 1
+ "grantable_free_ticket_flag" / Int8ul, # result is either 0 or 1
+ "login_reward_vp" / Int16ub,
+ "today_paying_flag" / Int8ul, # result is either 0 or 1
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ user_id_size=len(self.user_id) * 2,
+ user_id=[ord(x) for x in self.user_id],
+ first_play_flag=self.first_play_flag,
+ grantable_free_ticket_flag=self.grantable_free_ticket_flag,
+ login_reward_vp=self.login_reward_vp,
+ today_paying_flag=self.today_paying_flag,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCheckComebackEventRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCheckComebackEventRequest(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.get_flag_ = 1
+ self.get_comeback_event_id_list = "" # Array of events apparently
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "get_flag_" / Int8ul, # result is either 0 or 1
+ "get_comeback_event_id_list_size" / Int32ub, # big endian
+ "get_comeback_event_id_list" / Int16ul[len(self.get_comeback_event_id_list)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ get_flag_=self.get_flag_,
+ get_comeback_event_id_list_size=len(self.get_comeback_event_id_list) * 2,
+ get_comeback_event_id_list=[ord(x) for x in self.get_comeback_event_id_list],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetUserBasicDataRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetUserBasicDataResponse(SaoBaseResponse):
+ def __init__(self, cmd, profile_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.user_basic_data_size = 1 # Number of arrays
+ self.user_type = profile_data['user_type']
+ self.nick_name = profile_data['nick_name']
+ self.rank_num = profile_data['rank_num']
+ self.rank_exp = profile_data['rank_exp']
+ self.own_col = profile_data['own_col']
+ self.own_vp = profile_data['own_vp']
+ self.own_yui_medal = profile_data['own_yui_medal']
+ self.setting_title_id = profile_data['setting_title_id']
+ self.favorite_user_hero_log_id = ""
+ self.favorite_user_support_log_id = ""
+ self.my_store_id = "1"
+ self.my_store_name = "ARTEMiS"
+ self.user_reg_date = "20230101120000"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ '''
+ bool = Int8ul
+ short = Int16ub
+ int = Int32ub
+ '''
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "user_basic_data_size" / Int32ub,
+
+ "user_type" / Int16ub,
+ "nick_name_size" / Int32ub, # big endian
+ "nick_name" / Int16ul[len(self.nick_name)],
+ "rank_num" / Int16ub,
+ "rank_exp" / Int32ub,
+ "own_col" / Int32ub,
+ "own_vp" / Int32ub,
+ "own_yui_medal" / Int32ub,
+ "setting_title_id" / Int32ub,
+ "favorite_user_hero_log_id_size" / Int32ub, # big endian
+ "favorite_user_hero_log_id" / Int16ul[len(str(self.favorite_user_hero_log_id))],
+ "favorite_user_support_log_id_size" / Int32ub, # big endian
+ "favorite_user_support_log_id" / Int16ul[len(str(self.favorite_user_support_log_id))],
+ "my_store_id_size" / Int32ub, # big endian
+ "my_store_id" / Int16ul[len(str(self.my_store_id))],
+ "my_store_name_size" / Int32ub, # big endian
+ "my_store_name" / Int16ul[len(str(self.my_store_name))],
+ "user_reg_date_size" / Int32ub, # big endian
+ "user_reg_date" / Int16ul[len(self.user_reg_date)]
+
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ user_basic_data_size=self.user_basic_data_size,
+
+ user_type=self.user_type,
+ nick_name_size=len(self.nick_name) * 2,
+ nick_name=[ord(x) for x in self.nick_name],
+ rank_num=self.rank_num,
+ rank_exp=self.rank_exp,
+ own_col=self.own_col,
+ own_vp=self.own_vp,
+ own_yui_medal=self.own_yui_medal,
+ setting_title_id=self.setting_title_id,
+ favorite_user_hero_log_id_size=len(self.favorite_user_hero_log_id) * 2,
+ favorite_user_hero_log_id=[ord(x) for x in str(self.favorite_user_hero_log_id)],
+ favorite_user_support_log_id_size=len(self.favorite_user_support_log_id) * 2,
+ favorite_user_support_log_id=[ord(x) for x in str(self.favorite_user_support_log_id)],
+ my_store_id_size=len(self.my_store_id) * 2,
+ my_store_id=[ord(x) for x in str(self.my_store_id)],
+ my_store_name_size=len(self.my_store_name) * 2,
+ my_store_name=[ord(x) for x in str(self.my_store_name)],
+ user_reg_date_size=len(self.user_reg_date) * 2,
+ user_reg_date=[ord(x) for x in self.user_reg_date],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetHeroLogUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetHeroLogUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, hero_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ self.user_hero_log_id = []
+ self.log_level = []
+ self.max_log_level_extended_num = []
+ self.log_exp = []
+ self.last_set_skill_slot1_skill_id = []
+ self.last_set_skill_slot2_skill_id = []
+ self.last_set_skill_slot3_skill_id = []
+ self.last_set_skill_slot4_skill_id = []
+ self.last_set_skill_slot5_skill_id = []
+
+ for i in range(len(hero_data)):
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/HeroLogLevel.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ exp = hero_data[i][4]
+
+ for e in range(0,len(data)):
+ if exp>=int(data[e][1]) and exp bytes:
+ #new stuff
+
+ hero_log_user_data_list_struct = Struct(
+ "user_hero_log_id_size" / Int32ub, # big endian
+ "user_hero_log_id" / Int16ul[9], #string
+ "hero_log_id" / Int32ub, #int
+ "log_level" / Int16ub, #short
+ "max_log_level_extended_num" / Int16ub, #short
+ "log_exp" / Int32ub, #int
+ "possible_awakening_flag" / Int8ul, # result is either 0 or 1
+ "awakening_stage" / Int16ub, #short
+ "awakening_exp" / Int32ub, #int
+ "skill_slot_correction_value" / Int8ul, # result is either 0 or 1
+ "last_set_skill_slot1_skill_id" / Int16ub, #short
+ "last_set_skill_slot2_skill_id" / Int16ub, #short
+ "last_set_skill_slot3_skill_id" / Int16ub, #short
+ "last_set_skill_slot4_skill_id" / Int16ub, #short
+ "last_set_skill_slot5_skill_id" / Int16ub, #short
+ "property1_property_id" / Int32ub,
+ "property1_value1" / Int32ub,
+ "property1_value2" / Int32ub,
+ "property2_property_id" / Int32ub,
+ "property2_value1" / Int32ub,
+ "property2_value2" / Int32ub,
+ "property3_property_id" / Int32ub,
+ "property3_value1" / Int32ub,
+ "property3_value2" / Int32ub,
+ "property4_property_id" / Int32ub,
+ "property4_value1" / Int32ub,
+ "property4_value2" / Int32ub,
+ "converted_card_num" / Int16ub,
+ "shop_purchase_flag" / Int8ul, # result is either 0 or 1
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "hero_log_user_data_list_size" / Rebuild(Int32ub, len_(this.hero_log_user_data_list)), # big endian
+ "hero_log_user_data_list" / Array(this.hero_log_user_data_list_size, hero_log_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ hero_log_user_data_list_size=0,
+ hero_log_user_data_list=[],
+ )))
+
+ for i in range(len(self.hero_log_id)):
+ hero_data = dict(
+ user_hero_log_id_size=len(self.user_hero_log_id[i]) * 2,
+ user_hero_log_id=[ord(x) for x in self.user_hero_log_id[i]],
+ hero_log_id=self.hero_log_id[i],
+ log_level=self.log_level[i],
+ max_log_level_extended_num=self.max_log_level_extended_num[i],
+ log_exp=self.log_exp[i],
+ possible_awakening_flag=self.possible_awakening_flag,
+ awakening_stage=self.awakening_stage,
+ awakening_exp=self.awakening_exp,
+ skill_slot_correction_value=self.skill_slot_correction_value,
+ last_set_skill_slot1_skill_id=self.last_set_skill_slot1_skill_id[i],
+ last_set_skill_slot2_skill_id=self.last_set_skill_slot2_skill_id[i],
+ last_set_skill_slot3_skill_id=self.last_set_skill_slot3_skill_id[i],
+ last_set_skill_slot4_skill_id=self.last_set_skill_slot4_skill_id[i],
+ last_set_skill_slot5_skill_id=self.last_set_skill_slot5_skill_id[i],
+ property1_property_id=self.property1_property_id,
+ property1_value1=self.property1_value1,
+ property1_value2=self.property1_value2,
+ property2_property_id=self.property2_property_id,
+ property2_value1=self.property2_value1,
+ property2_value2=self.property2_value2,
+ property3_property_id=self.property3_property_id,
+ property3_value1=self.property3_value1,
+ property3_value2=self.property3_value2,
+ property4_property_id=self.property4_property_id,
+ property4_value1=self.property4_value1,
+ property4_value2=self.property4_value2,
+ converted_card_num=self.converted_card_num,
+ shop_purchase_flag=self.shop_purchase_flag,
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.hero_log_user_data_list.append(hero_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetEquipmentUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetEquipmentUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, equipment_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ self.user_equipment_id = []
+ self.enhancement_value = []
+ self.max_enhancement_value_extended_num = []
+ self.enhancement_exp = []
+ self.awakening_stage = []
+ self.awakening_exp = []
+ self.possible_awakening_flag = []
+ equipment_level = 0
+
+ for i in range(len(equipment_data)):
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/EquipmentLevel.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ exp = equipment_data[i][4]
+
+ for e in range(0,len(data)):
+ if exp>=int(data[e][1]) and exp bytes:
+
+ equipment_user_data_list_struct = Struct(
+ "user_equipment_id_size" / Int32ub, # big endian
+ "user_equipment_id" / Int16ul[9], #string
+ "equipment_id" / Int32ub, #int
+ "enhancement_value" / Int16ub, #short
+ "max_enhancement_value_extended_num" / Int16ub, #short
+ "enhancement_exp" / Int32ub, #int
+ "possible_awakening_flag" / Int8ul, # result is either 0 or 1
+ "awakening_stage" / Int16ub, #short
+ "awakening_exp" / Int32ub, #int
+ "property1_property_id" / Int32ub,
+ "property1_value1" / Int32ub,
+ "property1_value2" / Int32ub,
+ "property2_property_id" / Int32ub,
+ "property2_value1" / Int32ub,
+ "property2_value2" / Int32ub,
+ "property3_property_id" / Int32ub,
+ "property3_value1" / Int32ub,
+ "property3_value2" / Int32ub,
+ "property4_property_id" / Int32ub,
+ "property4_value1" / Int32ub,
+ "property4_value2" / Int32ub,
+ "converted_card_num" / Int16ub,
+ "shop_purchase_flag" / Int8ul, # result is either 0 or 1
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "equipment_user_data_list_size" / Rebuild(Int32ub, len_(this.equipment_user_data_list)), # big endian
+ "equipment_user_data_list" / Array(this.equipment_user_data_list_size, equipment_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ equipment_user_data_list_size=0,
+ equipment_user_data_list=[],
+ )))
+
+ for i in range(len(self.equipment_id)):
+ equipment_data = dict(
+ user_equipment_id_size=len(self.user_equipment_id[i]) * 2,
+ user_equipment_id=[ord(x) for x in self.user_equipment_id[i]],
+ equipment_id=self.equipment_id[i],
+ enhancement_value=self.enhancement_value[i],
+ max_enhancement_value_extended_num=self.max_enhancement_value_extended_num[i],
+ enhancement_exp=self.enhancement_exp[i],
+ possible_awakening_flag=self.possible_awakening_flag[i],
+ awakening_stage=self.awakening_stage[i],
+ awakening_exp=self.awakening_exp[i],
+ property1_property_id=self.property1_property_id,
+ property1_value1=self.property1_value1,
+ property1_value2=self.property1_value2,
+ property2_property_id=self.property2_property_id,
+ property2_value1=self.property2_value1,
+ property2_value2=self.property2_value2,
+ property3_property_id=self.property3_property_id,
+ property3_value1=self.property3_value1,
+ property3_value2=self.property3_value2,
+ property4_property_id=self.property4_property_id,
+ property4_value1=self.property4_value1,
+ property4_value2=self.property4_value2,
+ converted_card_num=self.converted_card_num,
+ shop_purchase_flag=self.shop_purchase_flag,
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.equipment_user_data_list.append(equipment_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetItemUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetItemUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, item_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ self.user_item_id = []
+
+ for i in range(len(item_data)):
+ self.user_item_id.append(item_data[i][2])
+
+ # item_user_data_list
+ self.user_item_id = list(map(str,self.user_item_id)) #str
+ self.item_id = list(map(int,self.user_item_id)) #int
+ self.protect_flag = 0 #byte
+ self.get_date = "20230101120000" #str
+
+ def make(self) -> bytes:
+ #new stuff
+
+ item_user_data_list_struct = Struct(
+ "user_item_id_size" / Int32ub, # big endian
+ "user_item_id" / Int16ul[6], #string but this will not work with 10000 IDs... only with 6 digits
+ "item_id" / Int32ub, #int
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "item_user_data_list_size" / Rebuild(Int32ub, len_(this.item_user_data_list)), # big endian
+ "item_user_data_list" / Array(this.item_user_data_list_size, item_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ item_user_data_list_size=0,
+ item_user_data_list=[],
+ )))
+
+ for i in range(len(self.item_id)):
+ item_data = dict(
+ user_item_id_size=len(self.user_item_id[i]) * 2,
+ user_item_id=[ord(x) for x in self.user_item_id[i]],
+ item_id=self.item_id[i],
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.item_user_data_list.append(item_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetSupportLogUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetSupportLogUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, supportIdsData) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ # support_log_user_data_list
+ self.user_support_log_id = list(map(str,supportIdsData)) #str
+ self.support_log_id = supportIdsData #int
+ self.possible_awakening_flag = 0
+ self.awakening_stage = 0
+ self.awakening_exp = 0
+ self.converted_card_num = 0
+ self.shop_purchase_flag = 0
+ self.protect_flag = 0 #byte
+ self.get_date = "20230101120000" #str
+
+ def make(self) -> bytes:
+ support_log_user_data_list_struct = Struct(
+ "user_support_log_id_size" / Int32ub, # big endian
+ "user_support_log_id" / Int16ul[9],
+ "support_log_id" / Int32ub, #int
+ "possible_awakening_flag" / Int8ul, # result is either 0 or 1
+ "awakening_stage" / Int16ub, #short
+ "awakening_exp" / Int32ub, # int
+ "converted_card_num" / Int16ub, #short
+ "shop_purchase_flag" / Int8ul, # result is either 0 or 1
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "support_log_user_data_list_size" / Rebuild(Int32ub, len_(this.support_log_user_data_list)), # big endian
+ "support_log_user_data_list" / Array(this.support_log_user_data_list_size, support_log_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ support_log_user_data_list_size=0,
+ support_log_user_data_list=[],
+ )))
+
+ for i in range(len(self.support_log_id)):
+ support_data = dict(
+ user_support_log_id_size=len(self.user_support_log_id[i]) * 2,
+ user_support_log_id=[ord(x) for x in self.user_support_log_id[i]],
+ support_log_id=self.support_log_id[i],
+ possible_awakening_flag=self.possible_awakening_flag,
+ awakening_stage=self.awakening_stage,
+ awakening_exp=self.awakening_exp,
+ converted_card_num=self.converted_card_num,
+ shop_purchase_flag=self.shop_purchase_flag,
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.support_log_user_data_list.append(support_data)
+
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetTitleUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetTitleUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, titleIdsData) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ # title_user_data_list
+ self.user_title_id = list(map(str,titleIdsData)) #str
+ self.title_id = titleIdsData #int
+
+ def make(self) -> bytes:
+ title_user_data_list_struct = Struct(
+ "user_title_id_size" / Int32ub, # big endian
+ "user_title_id" / Int16ul[6], #string
+ "title_id" / Int32ub, #int
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "title_user_data_list_size" / Rebuild(Int32ub, len_(this.title_user_data_list)), # big endian
+ "title_user_data_list" / Array(this.title_user_data_list_size, title_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ title_user_data_list_size=0,
+ title_user_data_list=[],
+ )))
+
+ for i in range(len(self.title_id)):
+ title_data = dict(
+ user_title_id_size=len(self.user_title_id[i]) * 2,
+ user_title_id=[ord(x) for x in self.user_title_id[i]],
+ title_id=self.title_id[i],
+ )
+
+ resp_data.title_user_data_list.append(title_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetEpisodeAppendDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetEpisodeAppendDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, profile_data) -> None:
+ super().__init__(cmd)
+ self.length = None
+ self.result = 1
+
+ self.user_episode_append_id_list = ["10001", "10002", "10003", "10004", "10005"]
+ self.user_id_list = [str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"])]
+ self.episode_append_id_list = [10001, 10002, 10003, 10004, 10005]
+ self.own_num_list = [3, 3, 3, 3 ,3]
+
+ def make(self) -> bytes:
+ episode_data_struct = Struct(
+ "user_episode_append_id_size" / Rebuild(Int32ub, len_(this.user_episode_append_id) * 2), # calculates the length of the user_episode_append_id
+ "user_episode_append_id" / PaddedString(this.user_episode_append_id_size, "utf_16_le"), # user_episode_append_id is a (zero) padded string
+ "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id
+ "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string
+ "episode_append_id" / Int32ub,
+ "own_num" / Int32ub,
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "episode_append_data_list_size" / Rebuild(Int32ub, len_(this.episode_append_data_list)), # big endian
+ "episode_append_data_list" / Array(this.episode_append_data_list_size, episode_data_struct),
+ )
+
+ # really dump to parse the build resp, but that creates a new object
+ # and is nicer to twork with
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ episode_append_data_list_size=0,
+ episode_append_data_list=[],
+ )))
+
+ if len(self.user_episode_append_id_list) != len(self.user_id_list) != len(self.episode_append_id_list) != len(self.own_num_list):
+ raise ValueError("all lists must be of the same length")
+
+ for i in range(len(self.user_id_list)):
+ # add the episode_data_struct to the resp_struct.episode_append_data_list
+ resp_data.episode_append_data_list.append(dict(
+ user_episode_append_id=self.user_episode_append_id_list[i],
+ user_id=self.user_id_list[i],
+ episode_append_id=self.episode_append_id_list[i],
+ own_num=self.own_num_list[i],
+ ))
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetPartyDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetPartyDataListResponse(SaoBaseResponse): # Default party
+ def __init__(self, cmd, hero1_data, hero2_data, hero3_data) -> None:
+ super().__init__(cmd)
+
+ self.result = 1
+ self.party_data_list_size = 1 # Number of arrays
+
+ self.user_party_id = "0"
+ self.team_no = 0
+ self.party_team_data_list_size = 3 # Number of arrays
+
+ self.user_party_team_id_1 = "0"
+ self.arrangement_num_1 = 0
+ self.user_hero_log_id_1 = str(hero1_data[2])
+ self.main_weapon_user_equipment_id_1 = str(hero1_data[5])
+ self.sub_equipment_user_equipment_id_1 = str(hero1_data[6])
+ self.skill_slot1_skill_id_1 = hero1_data[7]
+ self.skill_slot2_skill_id_1 = hero1_data[8]
+ self.skill_slot3_skill_id_1 = hero1_data[9]
+ self.skill_slot4_skill_id_1 = hero1_data[10]
+ self.skill_slot5_skill_id_1 = hero1_data[11]
+
+ self.user_party_team_id_2 = "0"
+ self.arrangement_num_2 = 0
+ self.user_hero_log_id_2 = str(hero2_data[2])
+ self.main_weapon_user_equipment_id_2 = str(hero2_data[5])
+ self.sub_equipment_user_equipment_id_2 = str(hero2_data[6])
+ self.skill_slot1_skill_id_2 = hero2_data[7]
+ self.skill_slot2_skill_id_2 = hero2_data[8]
+ self.skill_slot3_skill_id_2 = hero2_data[9]
+ self.skill_slot4_skill_id_2 = hero2_data[10]
+ self.skill_slot5_skill_id_2 = hero2_data[11]
+
+ self.user_party_team_id_3 = "0"
+ self.arrangement_num_3 = 0
+ self.user_hero_log_id_3 = str(hero3_data[2])
+ self.main_weapon_user_equipment_id_3 = str(hero3_data[5])
+ self.sub_equipment_user_equipment_id_3 = str(hero3_data[6])
+ self.skill_slot1_skill_id_3 = hero3_data[7]
+ self.skill_slot2_skill_id_3 = hero3_data[8]
+ self.skill_slot3_skill_id_3 = hero3_data[9]
+ self.skill_slot4_skill_id_3 = hero3_data[10]
+ self.skill_slot5_skill_id_3 = hero3_data[11]
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "party_data_list_size" / Int32ub, # big endian
+
+ "user_party_id_size" / Int32ub, # big endian
+ "user_party_id" / Int16ul[len(self.user_party_id)],
+ "team_no" / Int8ul, # result is either 0 or 1
+ "party_team_data_list_size" / Int32ub, # big endian
+
+ "user_party_team_id_1_size" / Int32ub, # big endian
+ "user_party_team_id_1" / Int16ul[len(self.user_party_team_id_1)],
+ "arrangement_num_1" / Int8ul, # big endian
+ "user_hero_log_id_1_size" / Int32ub, # big endian
+ "user_hero_log_id_1" / Int16ul[len(self.user_hero_log_id_1)],
+ "main_weapon_user_equipment_id_1_size" / Int32ub, # big endian
+ "main_weapon_user_equipment_id_1" / Int16ul[len(self.main_weapon_user_equipment_id_1)],
+ "sub_equipment_user_equipment_id_1_size" / Int32ub, # big endian
+ "sub_equipment_user_equipment_id_1" / Int16ul[len(self.sub_equipment_user_equipment_id_1)],
+ "skill_slot1_skill_id_1" / Int32ub,
+ "skill_slot2_skill_id_1" / Int32ub,
+ "skill_slot3_skill_id_1" / Int32ub,
+ "skill_slot4_skill_id_1" / Int32ub,
+ "skill_slot5_skill_id_1" / Int32ub,
+
+ "user_party_team_id_2_size" / Int32ub, # big endian
+ "user_party_team_id_2" / Int16ul[len(self.user_party_team_id_2)],
+ "arrangement_num_2" / Int8ul, # result is either 0 or 1
+ "user_hero_log_id_2_size" / Int32ub, # big endian
+ "user_hero_log_id_2" / Int16ul[len(self.user_hero_log_id_2)],
+ "main_weapon_user_equipment_id_2_size" / Int32ub, # big endian
+ "main_weapon_user_equipment_id_2" / Int16ul[len(self.main_weapon_user_equipment_id_2)],
+ "sub_equipment_user_equipment_id_2_size" / Int32ub, # big endian
+ "sub_equipment_user_equipment_id_2" / Int16ul[len(self.sub_equipment_user_equipment_id_2)],
+ "skill_slot1_skill_id_2" / Int32ub,
+ "skill_slot2_skill_id_2" / Int32ub,
+ "skill_slot3_skill_id_2" / Int32ub,
+ "skill_slot4_skill_id_2" / Int32ub,
+ "skill_slot5_skill_id_2" / Int32ub,
+
+ "user_party_team_id_3_size" / Int32ub, # big endian
+ "user_party_team_id_3" / Int16ul[len(self.user_party_team_id_3)],
+ "arrangement_num_3" / Int8ul, # result is either 0 or 1
+ "user_hero_log_id_3_size" / Int32ub, # big endian
+ "user_hero_log_id_3" / Int16ul[len(self.user_hero_log_id_3)],
+ "main_weapon_user_equipment_id_3_size" / Int32ub, # big endian
+ "main_weapon_user_equipment_id_3" / Int16ul[len(self.main_weapon_user_equipment_id_3)],
+ "sub_equipment_user_equipment_id_3_size" / Int32ub, # big endian
+ "sub_equipment_user_equipment_id_3" / Int16ul[len(self.sub_equipment_user_equipment_id_3)],
+ "skill_slot1_skill_id_3" / Int32ub,
+ "skill_slot2_skill_id_3" / Int32ub,
+ "skill_slot3_skill_id_3" / Int32ub,
+ "skill_slot4_skill_id_3" / Int32ub,
+ "skill_slot5_skill_id_3" / Int32ub,
+
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ party_data_list_size=self.party_data_list_size,
+
+ user_party_id_size=len(self.user_party_id) * 2,
+ user_party_id=[ord(x) for x in self.user_party_id],
+ team_no=self.team_no,
+ party_team_data_list_size=self.party_team_data_list_size,
+
+ user_party_team_id_1_size=len(self.user_party_team_id_1) * 2,
+ user_party_team_id_1=[ord(x) for x in self.user_party_team_id_1],
+ arrangement_num_1=self.arrangement_num_1,
+ user_hero_log_id_1_size=len(self.user_hero_log_id_1) * 2,
+ user_hero_log_id_1=[ord(x) for x in self.user_hero_log_id_1],
+ main_weapon_user_equipment_id_1_size=len(self.main_weapon_user_equipment_id_1) * 2,
+ main_weapon_user_equipment_id_1=[ord(x) for x in self.main_weapon_user_equipment_id_1],
+ sub_equipment_user_equipment_id_1_size=len(self.sub_equipment_user_equipment_id_1) * 2,
+ sub_equipment_user_equipment_id_1=[ord(x) for x in self.sub_equipment_user_equipment_id_1],
+ skill_slot1_skill_id_1=self.skill_slot1_skill_id_1,
+ skill_slot2_skill_id_1=self.skill_slot2_skill_id_1,
+ skill_slot3_skill_id_1=self.skill_slot3_skill_id_1,
+ skill_slot4_skill_id_1=self.skill_slot4_skill_id_1,
+ skill_slot5_skill_id_1=self.skill_slot5_skill_id_1,
+
+ user_party_team_id_2_size=len(self.user_party_team_id_2) * 2,
+ user_party_team_id_2=[ord(x) for x in self.user_party_team_id_2],
+ arrangement_num_2=self.arrangement_num_2,
+ user_hero_log_id_2_size=len(self.user_hero_log_id_2) * 2,
+ user_hero_log_id_2=[ord(x) for x in self.user_hero_log_id_2],
+ main_weapon_user_equipment_id_2_size=len(self.main_weapon_user_equipment_id_2) * 2,
+ main_weapon_user_equipment_id_2=[ord(x) for x in self.main_weapon_user_equipment_id_2],
+ sub_equipment_user_equipment_id_2_size=len(self.sub_equipment_user_equipment_id_2) * 2,
+ sub_equipment_user_equipment_id_2=[ord(x) for x in self.sub_equipment_user_equipment_id_2],
+ skill_slot1_skill_id_2=self.skill_slot1_skill_id_2,
+ skill_slot2_skill_id_2=self.skill_slot2_skill_id_2,
+ skill_slot3_skill_id_2=self.skill_slot3_skill_id_2,
+ skill_slot4_skill_id_2=self.skill_slot4_skill_id_2,
+ skill_slot5_skill_id_2=self.skill_slot5_skill_id_2,
+
+ user_party_team_id_3_size=len(self.user_party_team_id_3) * 2,
+ user_party_team_id_3=[ord(x) for x in self.user_party_team_id_3],
+ arrangement_num_3=self.arrangement_num_3,
+ user_hero_log_id_3_size=len(self.user_hero_log_id_3) * 2,
+ user_hero_log_id_3=[ord(x) for x in self.user_hero_log_id_3],
+ main_weapon_user_equipment_id_3_size=len(self.main_weapon_user_equipment_id_3) * 2,
+ main_weapon_user_equipment_id_3=[ord(x) for x in self.main_weapon_user_equipment_id_3],
+ sub_equipment_user_equipment_id_3_size=len(self.sub_equipment_user_equipment_id_3) * 2,
+ sub_equipment_user_equipment_id_3=[ord(x) for x in self.sub_equipment_user_equipment_id_3],
+ skill_slot1_skill_id_3=self.skill_slot1_skill_id_3,
+ skill_slot2_skill_id_3=self.skill_slot2_skill_id_3,
+ skill_slot3_skill_id_3=self.skill_slot3_skill_id_3,
+ skill_slot4_skill_id_3=self.skill_slot4_skill_id_3,
+ skill_slot5_skill_id_3=self.skill_slot5_skill_id_3,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetQuestScenePrevScanProfileCardRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetQuestScenePrevScanProfileCardResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.profile_card_data = 1 # number of arrays
+
+ self.profile_card_code = ""
+ self.nick_name = ""
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "profile_card_data" / Int32ub, # big endian
+
+ "profile_card_code_size" / Int32ub, # big endian
+ "profile_card_code" / Int16ul[len(self.profile_card_code)],
+ "nick_name_size" / Int32ub, # big endian
+ "nick_name" / Int16ul[len(self.nick_name)],
+ "rank_num" / Int16ub, #short
+ "setting_title_id" / Int32ub, # int
+ "skill_id" / Int16ub, # short
+ "hero_log_hero_log_id" / Int32ub, # int
+ "hero_log_log_level" / Int16ub, # short
+ "hero_log_awakening_stage" / Int16ub, # short
+ "hero_log_property1_property_id" / Int32ub, # int
+ "hero_log_property1_value1" / Int32ub, # int
+ "hero_log_property1_value2" / Int32ub, # int
+ "hero_log_property2_property_id" / Int32ub, # int
+ "hero_log_property2_value1" / Int32ub, # int
+ "hero_log_property2_value2" / Int32ub, # int
+ "hero_log_property3_property_id" / Int32ub, # int
+ "hero_log_property3_value1" / Int32ub, # int
+ "hero_log_property3_value2" / Int32ub, # int
+ "hero_log_property4_property_id" / Int32ub, # int
+ "hero_log_property4_value1" / Int32ub, # int
+ "hero_log_property4_value2" / Int32ub, # int
+ "main_weapon_equipment_id" / Int32ub, # int
+ "main_weapon_enhancement_value" / Int16ub, # short
+ "main_weapon_awakening_stage" / Int16ub, # short
+ "main_weapon_property1_property_id" / Int32ub, # int
+ "main_weapon_property1_value1" / Int32ub, # int
+ "main_weapon_property1_value2" / Int32ub, # int
+ "main_weapon_property2_property_id" / Int32ub, # int
+ "main_weapon_property2_value1" / Int32ub, # int
+ "main_weapon_property2_value2" / Int32ub, # int
+ "main_weapon_property3_property_id" / Int32ub, # int
+ "main_weapon_property3_value1" / Int32ub, # int
+ "main_weapon_property3_value2" / Int32ub, # int
+ "main_weapon_property4_property_id" / Int32ub, # int
+ "main_weapon_property4_value1" / Int32ub, # int
+ "main_weapon_property4_value2" / Int32ub, # int
+ "sub_equipment_equipment_id" / Int32ub, # int
+ "sub_equipment_enhancement_value" / Int16ub, # short
+ "sub_equipment_awakening_stage" / Int16ub, # short
+ "sub_equipment_property1_property_id" / Int32ub, # int
+ "sub_equipment_property1_value1" / Int32ub, # int
+ "sub_equipment_property1_value2" / Int32ub, # int
+ "sub_equipment_property2_property_id" / Int32ub, # int
+ "sub_equipment_property2_value1" / Int32ub, # int
+ "sub_equipment_property2_value2" / Int32ub, # int
+ "sub_equipment_property3_property_id" / Int32ub, # int
+ "sub_equipment_property3_value1" / Int32ub, # int
+ "sub_equipment_property3_value2" / Int32ub, # int
+ "sub_equipment_property4_property_id" / Int32ub, # int
+ "sub_equipment_property4_value1" / Int32ub, # int
+ "sub_equipment_property4_value2" / Int32ub, # int
+ "holographic_flag" / Int8ul, # result is either 0 or 1
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ profile_card_data=self.profile_card_data,
+
+ profile_card_code_size=len(self.profile_card_code) * 2,
+ profile_card_code=[ord(x) for x in self.profile_card_code],
+ nick_name_size=len(self.nick_name) * 2,
+ nick_name=[ord(x) for x in self.nick_name],
+ rank_num=0,
+ setting_title_id=0,
+ skill_id=0,
+ hero_log_hero_log_id=0,
+ hero_log_log_level=0,
+ hero_log_awakening_stage=0,
+ hero_log_property1_property_id=0,
+ hero_log_property1_value1=0,
+ hero_log_property1_value2=0,
+ hero_log_property2_property_id=0,
+ hero_log_property2_value1=0,
+ hero_log_property2_value2=0,
+ hero_log_property3_property_id=0,
+ hero_log_property3_value1=0,
+ hero_log_property3_value2=0,
+ hero_log_property4_property_id=0,
+ hero_log_property4_value1=0,
+ hero_log_property4_value2=0,
+ main_weapon_equipment_id=0,
+ main_weapon_enhancement_value=0,
+ main_weapon_awakening_stage=0,
+ main_weapon_property1_property_id=0,
+ main_weapon_property1_value1=0,
+ main_weapon_property1_value2=0,
+ main_weapon_property2_property_id=0,
+ main_weapon_property2_value1=0,
+ main_weapon_property2_value2=0,
+ main_weapon_property3_property_id=0,
+ main_weapon_property3_value1=0,
+ main_weapon_property3_value2=0,
+ main_weapon_property4_property_id=0,
+ main_weapon_property4_value1=0,
+ main_weapon_property4_value2=0,
+ sub_equipment_equipment_id=0,
+ sub_equipment_enhancement_value=0,
+ sub_equipment_awakening_stage=0,
+ sub_equipment_property1_property_id=0,
+ sub_equipment_property1_value1=0,
+ sub_equipment_property1_value2=0,
+ sub_equipment_property2_property_id=0,
+ sub_equipment_property2_value1=0,
+ sub_equipment_property2_value2=0,
+ sub_equipment_property3_property_id=0,
+ sub_equipment_property3_value1=0,
+ sub_equipment_property3_value2=0,
+ sub_equipment_property4_property_id=0,
+ sub_equipment_property4_value1=0,
+ sub_equipment_property4_value2=0,
+ holographic_flag=0,
+
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetResourcePathInfoRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetResourcePathInfoResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.resource_base_url = "http://localhost:9000/SDEW/100/"
+ self.gasha_base_dir = "a"
+ self.ad_base_dir = "b"
+ self.event_base_dir = "c"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "resource_base_url_size" / Int32ub, # big endian
+ "resource_base_url" / Int16ul[len(self.resource_base_url)],
+ "gasha_base_dir_size" / Int32ub, # big endian
+ "gasha_base_dir" / Int16ul[len(self.gasha_base_dir)],
+ "ad_base_dir_size" / Int32ub, # big endian
+ "ad_base_dir" / Int16ul[len(self.ad_base_dir)],
+ "event_base_dir_size" / Int32ub, # big endian
+ "event_base_dir" / Int16ul[len(self.event_base_dir)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ resource_base_url_size=len(self.resource_base_url) * 2,
+ resource_base_url=[ord(x) for x in self.resource_base_url],
+ gasha_base_dir_size=len(self.gasha_base_dir) * 2,
+ gasha_base_dir=[ord(x) for x in self.gasha_base_dir],
+ ad_base_dir_size=len(self.ad_base_dir) * 2,
+ ad_base_dir=[ord(x) for x in self.ad_base_dir],
+ event_base_dir_size=len(self.event_base_dir) * 2,
+ event_base_dir=[ord(x) for x in self.event_base_dir],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoEpisodePlayStartRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoEpisodePlayStartResponse(SaoBaseResponse):
+ def __init__(self, cmd, profile_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.play_start_response_data_size = 1 # Number of arrays (minimum 1 mandatory)
+ self.multi_play_start_response_data_size = 0 # Number of arrays (set 0 due to single play)
+
+ self.appearance_player_trace_data_list_size = 1
+
+ self.user_quest_scene_player_trace_id = "1003"
+ self.nick_name = profile_data["nick_name"]
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "play_start_response_data_size" / Int32ub,
+ "multi_play_start_response_data_size" / Int32ub,
+
+ "appearance_player_trace_data_list_size" / Int32ub,
+
+ "user_quest_scene_player_trace_id_size" / Int32ub, # big endian
+ "user_quest_scene_player_trace_id" / Int16ul[len(self.user_quest_scene_player_trace_id)],
+ "nick_name_size" / Int32ub, # big endian
+ "nick_name" / Int16ul[len(self.nick_name)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ play_start_response_data_size=self.play_start_response_data_size,
+ multi_play_start_response_data_size=self.multi_play_start_response_data_size,
+
+ appearance_player_trace_data_list_size=self.appearance_player_trace_data_list_size,
+
+ user_quest_scene_player_trace_id_size=len(self.user_quest_scene_player_trace_id) * 2,
+ user_quest_scene_player_trace_id=[ord(x) for x in self.user_quest_scene_player_trace_id],
+ nick_name_size=len(self.nick_name) * 2,
+ nick_name=[ord(x) for x in self.nick_name],
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoEpisodePlayEndRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoEpisodePlayEndResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.play_end_response_data_size = 1 # Number of arrays
+ self.multi_play_end_response_data_size = 1 # Unused on solo play
+
+ self.dummy_1 = 0
+ self.dummy_2 = 0
+ self.dummy_3 = 0
+
+ self.rarity_up_occurrence_flag = 0
+ self.adventure_ex_area_occurrences_flag = 0
+ self.ex_bonus_data_list_size = 1 # Number of arrays
+ self.play_end_player_trace_reward_data_list_size = 0 # Number of arrays
+
+ self.ex_bonus_table_id = 0 # ExBonusTable.csv values, dont care for now
+ self.achievement_status = 1
+
+ self.common_reward_data_size = 1 # Number of arrays
+
+ self.common_reward_type = 0 # dummy values from 2,101000000,1 from RewardTable.csv
+ self.common_reward_id = 0
+ self.common_reward_num = 0
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "play_end_response_data_size" / Int32ub, # big endian
+
+ "rarity_up_occurrence_flag" / Int8ul, # result is either 0 or 1
+ "adventure_ex_area_occurrences_flag" / Int8ul, # result is either 0 or 1
+ "ex_bonus_data_list_size" / Int32ub, # big endian
+ "play_end_player_trace_reward_data_list_size" / Int32ub, # big endian
+
+ # ex_bonus_data_list
+ "ex_bonus_table_id" / Int32ub,
+ "achievement_status" / Int8ul, # result is either 0 or 1
+
+ # play_end_player_trace_reward_data_list
+ "common_reward_data_size" / Int32ub,
+
+ # common_reward_data
+ "common_reward_type" / Int16ub, # short
+ "common_reward_id" / Int32ub,
+ "common_reward_num" / Int32ub,
+
+ "multi_play_end_response_data_size" / Int32ub, # big endian
+
+ # multi_play_end_response_data
+ "dummy_1" / Int8ul, # result is either 0 or 1
+ "dummy_2" / Int8ul, # result is either 0 or 1
+ "dummy_3" / Int8ul, # result is either 0 or 1
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ play_end_response_data_size=self.play_end_response_data_size,
+
+ rarity_up_occurrence_flag=self.rarity_up_occurrence_flag,
+ adventure_ex_area_occurrences_flag=self.adventure_ex_area_occurrences_flag,
+ ex_bonus_data_list_size=self.ex_bonus_data_list_size,
+ play_end_player_trace_reward_data_list_size=self.play_end_player_trace_reward_data_list_size,
+
+ ex_bonus_table_id=self.ex_bonus_table_id,
+ achievement_status=self.achievement_status,
+
+ common_reward_data_size=self.common_reward_data_size,
+
+ common_reward_type=self.common_reward_type,
+ common_reward_id=self.common_reward_id,
+ common_reward_num=self.common_reward_num,
+
+ multi_play_end_response_data_size=self.multi_play_end_response_data_size,
+
+ dummy_1=self.dummy_1,
+ dummy_2=self.dummy_2,
+ dummy_3=self.dummy_3,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoTrialTowerPlayEndRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoTrialTowerPlayEndResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.play_end_response_data_size = 1 # Number of arrays
+ self.multi_play_end_response_data_size = 1 # Unused on solo play
+ self.trial_tower_play_end_updated_notification_data_size = 1 # Number of arrays
+ self.treasure_hunt_play_end_response_data_size = 1 # Number of arrays
+
+ self.dummy_1 = 0
+ self.dummy_2 = 0
+ self.dummy_3 = 0
+
+ self.rarity_up_occurrence_flag = 0
+ self.adventure_ex_area_occurrences_flag = 0
+ self.ex_bonus_data_list_size = 1 # Number of arrays
+ self.play_end_player_trace_reward_data_list_size = 0 # Number of arrays
+
+ self.ex_bonus_table_id = 0 # ExBonusTable.csv values, dont care for now
+ self.achievement_status = 1
+
+ self.common_reward_data_size = 1 # Number of arrays
+
+ self.common_reward_type = 0 # dummy values from 2,101000000,1 from RewardTable.csv
+ self.common_reward_id = 0
+ self.common_reward_num = 0
+
+ self.store_best_score_clear_time_flag = 0
+ self.store_best_score_combo_num_flag = 0
+ self.store_best_score_total_damage_flag = 0
+ self.store_best_score_concurrent_destroying_num_flag = 0
+ self.store_reaching_trial_tower_rank = 0
+
+ self.get_event_point = 0
+ self.total_event_point = 0
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "play_end_response_data_size" / Int32ub, # big endian
+
+ "rarity_up_occurrence_flag" / Int8ul, # result is either 0 or 1
+ "adventure_ex_area_occurrences_flag" / Int8ul, # result is either 0 or 1
+ "ex_bonus_data_list_size" / Int32ub, # big endian
+ "play_end_player_trace_reward_data_list_size" / Int32ub, # big endian
+
+ # ex_bonus_data_list
+ "ex_bonus_table_id" / Int32ub,
+ "achievement_status" / Int8ul, # result is either 0 or 1
+
+ # play_end_player_trace_reward_data_list
+ "common_reward_data_size" / Int32ub,
+
+ # common_reward_data
+ "common_reward_type" / Int16ub, # short
+ "common_reward_id" / Int32ub,
+ "common_reward_num" / Int32ub,
+
+ "multi_play_end_response_data_size" / Int32ub, # big endian
+
+ # multi_play_end_response_data
+ "dummy_1" / Int8ul, # result is either 0 or 1
+ "dummy_2" / Int8ul, # result is either 0 or 1
+ "dummy_3" / Int8ul, # result is either 0 or 1
+
+ "trial_tower_play_end_updated_notification_data_size" / Int32ub, # big endian
+
+ #trial_tower_play_end_updated_notification_data
+ "store_best_score_clear_time_flag" / Int8ul, # result is either 0 or 1
+ "store_best_score_combo_num_flag" / Int8ul, # result is either 0 or 1
+ "store_best_score_total_damage_flag" / Int8ul, # result is either 0 or 1
+ "store_best_score_concurrent_destroying_num_flag" / Int8ul, # result is either 0 or 1
+ "store_reaching_trial_tower_rank" / Int32ub,
+
+ "treasure_hunt_play_end_response_data_size" / Int32ub, # big endian
+
+ #treasure_hunt_play_end_response_data
+ "get_event_point" / Int32ub,
+ "total_event_point" / Int32ub,
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ play_end_response_data_size=self.play_end_response_data_size,
+
+ rarity_up_occurrence_flag=self.rarity_up_occurrence_flag,
+ adventure_ex_area_occurrences_flag=self.adventure_ex_area_occurrences_flag,
+ ex_bonus_data_list_size=self.ex_bonus_data_list_size,
+ play_end_player_trace_reward_data_list_size=self.play_end_player_trace_reward_data_list_size,
+
+ ex_bonus_table_id=self.ex_bonus_table_id,
+ achievement_status=self.achievement_status,
+
+ common_reward_data_size=self.common_reward_data_size,
+
+ common_reward_type=self.common_reward_type,
+ common_reward_id=self.common_reward_id,
+ common_reward_num=self.common_reward_num,
+
+ multi_play_end_response_data_size=self.multi_play_end_response_data_size,
+
+ dummy_1=self.dummy_1,
+ dummy_2=self.dummy_2,
+ dummy_3=self.dummy_3,
+
+ trial_tower_play_end_updated_notification_data_size=self.trial_tower_play_end_updated_notification_data_size,
+ store_best_score_clear_time_flag=self.store_best_score_clear_time_flag,
+ store_best_score_combo_num_flag=self.store_best_score_combo_num_flag,
+ store_best_score_total_damage_flag=self.store_best_score_total_damage_flag,
+ store_best_score_concurrent_destroying_num_flag=self.store_best_score_concurrent_destroying_num_flag,
+ store_reaching_trial_tower_rank=self.store_reaching_trial_tower_rank,
+
+ treasure_hunt_play_end_response_data_size=self.treasure_hunt_play_end_response_data_size,
+
+ get_event_point=self.get_event_point,
+ total_event_point=self.total_event_point,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoEpisodePlayEndUnanalyzedLogFixedRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoEpisodePlayEndUnanalyzedLogFixedResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.play_end_unanalyzed_log_reward_data_list_size = 1 # Number of arrays
+
+ self.unanalyzed_log_grade_id = 3 # RewardTable.csv
+ self.common_reward_data_size = 1
+
+ self.common_reward_type_1 = 1
+ self.common_reward_id_1 = 102000070
+ self.common_reward_num_1 = 1
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "play_end_unanalyzed_log_reward_data_list_size" / Int32ub, # big endian
+
+ "unanalyzed_log_grade_id" / Int32ub,
+ "common_reward_data_size" / Int32ub,
+
+ "common_reward_type_1" / Int16ub,
+ "common_reward_id_1" / Int32ub,
+ "common_reward_num_1" / Int32ub,
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ play_end_unanalyzed_log_reward_data_list_size=self.play_end_unanalyzed_log_reward_data_list_size,
+
+ unanalyzed_log_grade_id=self.unanalyzed_log_grade_id,
+ common_reward_data_size=self.common_reward_data_size,
+
+ common_reward_type_1=self.common_reward_type_1,
+ common_reward_id_1=self.common_reward_id_1,
+ common_reward_num_1=self.common_reward_num_1,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetQuestSceneUserDataListRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetQuestSceneUserDataListResponse(SaoBaseResponse):
+ def __init__(self, cmd, quest_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ # quest_scene_user_data_list_size
+ self.quest_type = []
+ self.quest_scene_id = []
+ self.clear_flag = []
+
+ # quest_scene_best_score_user_data
+ self.clear_time = []
+ self.combo_num = []
+ self.total_damage = [] #string
+ self.concurrent_destroying_num = []
+
+ for i in range(len(quest_data)):
+ self.quest_type.append(1)
+ self.quest_scene_id.append(quest_data[i][2])
+ self.clear_flag.append(int(quest_data[i][3]))
+
+ self.clear_time.append(quest_data[i][4])
+ self.combo_num.append(quest_data[i][5])
+ self.total_damage.append(0) #totally absurd but Int16ul[1] is a big problem due to different lenghts...
+ self.concurrent_destroying_num.append(quest_data[i][7])
+
+ # quest_scene_ex_bonus_user_data_list
+ self.achievement_flag = [[1, 1, 1],[1, 1, 1]]
+ self.ex_bonus_table_id = [[1, 2, 3],[4, 5, 6]]
+
+
+ self.quest_type = list(map(int,self.quest_type)) #int
+ self.quest_scene_id = list(map(int,self.quest_scene_id)) #int
+ self.clear_flag = list(map(int,self.clear_flag)) #int
+ self.clear_time = list(map(int,self.clear_time)) #int
+ self.combo_num = list(map(int,self.combo_num)) #int
+ self.total_damage = list(map(str,self.total_damage)) #string
+ self.concurrent_destroying_num = list(map(int,self.combo_num)) #int
+
+ def make(self) -> bytes:
+ #new stuff
+ quest_scene_ex_bonus_user_data_list_struct = Struct(
+ "achievement_flag" / Int32ub, # big endian
+ "ex_bonus_table_id" / Int32ub, # big endian
+ )
+
+ quest_scene_best_score_user_data_struct = Struct(
+ "clear_time" / Int32ub, # big endian
+ "combo_num" / Int32ub, # big endian
+ "total_damage_size" / Int32ub, # big endian
+ "total_damage" / Int16ul[1],
+ "concurrent_destroying_num" / Int16ub,
+ )
+
+ quest_scene_user_data_list_struct = Struct(
+ "quest_type" / Int8ul, # result is either 0 or 1
+ "quest_scene_id" / Int16ub, #short
+ "clear_flag" / Int8ul, # result is either 0 or 1
+ "quest_scene_best_score_user_data_size" / Rebuild(Int32ub, len_(this.quest_scene_best_score_user_data)), # big endian
+ "quest_scene_best_score_user_data" / Array(this.quest_scene_best_score_user_data_size, quest_scene_best_score_user_data_struct),
+ "quest_scene_ex_bonus_user_data_list_size" / Rebuild(Int32ub, len_(this.quest_scene_ex_bonus_user_data_list)), # big endian
+ "quest_scene_ex_bonus_user_data_list" / Array(this.quest_scene_ex_bonus_user_data_list_size, quest_scene_ex_bonus_user_data_list_struct),
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "quest_scene_user_data_list_size" / Rebuild(Int32ub, len_(this.quest_scene_user_data_list)), # big endian
+ "quest_scene_user_data_list" / Array(this.quest_scene_user_data_list_size, quest_scene_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ quest_scene_user_data_list_size=0,
+ quest_scene_user_data_list=[],
+ )))
+
+ for i in range(len(self.quest_scene_id)):
+ quest_resp_data = dict(
+ quest_type=self.quest_type[i],
+ quest_scene_id=self.quest_scene_id[i],
+ clear_flag=self.clear_flag[i],
+
+ quest_scene_best_score_user_data_size=0,
+ quest_scene_best_score_user_data=[],
+ quest_scene_ex_bonus_user_data_list_size=0,
+ quest_scene_ex_bonus_user_data_list=[],
+ )
+
+ quest_resp_data["quest_scene_best_score_user_data"].append(dict(
+ clear_time=self.clear_time[i],
+ combo_num=self.combo_num[i],
+ total_damage_size=len(self.total_damage[i]) * 2,
+ total_damage=[ord(x) for x in self.total_damage[i]],
+ concurrent_destroying_num=self.concurrent_destroying_num[i],
+ ))
+
+
+ resp_data.quest_scene_user_data_list.append(quest_resp_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCheckYuiMedalGetConditionRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCheckYuiMedalGetConditionResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.get_flag = 1
+ self.elapsed_days = 1
+ self.get_yui_medal_num = 1
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "get_flag" / Int8ul, # result is either 0 or 1
+ "elapsed_days" / Int16ub, #short
+ "get_yui_medal_num" / Int16ub, #short
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ get_flag=self.get_flag,
+ elapsed_days=self.elapsed_days,
+ get_yui_medal_num=self.get_yui_medal_num,
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoGetYuiMedalBonusUserDataRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoGetYuiMedalBonusUserDataResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.data_size = 1 # number of arrays
+
+ self.elapsed_days = 1
+ self.loop_num = 1
+ self.last_check_date = "20230520193000"
+ self.last_get_date = "20230520193000"
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "data_size" / Int32ub, # big endian
+
+ "elapsed_days" / Int32ub, # big endian
+ "loop_num" / Int32ub, # big endian
+ "last_check_date_size" / Int32ub, # big endian
+ "last_check_date" / Int16ul[len(self.last_check_date)],
+ "last_get_date_size" / Int32ub, # big endian
+ "last_get_date" / Int16ul[len(self.last_get_date)],
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ data_size=self.data_size,
+
+ elapsed_days=self.elapsed_days,
+ loop_num=self.loop_num,
+ last_check_date_size=len(self.last_check_date) * 2,
+ last_check_date=[ord(x) for x in self.last_check_date],
+ last_get_date_size=len(self.last_get_date) * 2,
+ last_get_date=[ord(x) for x in self.last_get_date],
+
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoCheckProfileCardUsedRewardRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoCheckProfileCardUsedRewardResponse(SaoBaseResponse):
+ def __init__(self, cmd) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ self.get_flag = 1
+ self.used_num = 0
+ self.get_vp = 1
+
+ def make(self) -> bytes:
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "get_flag" / Int8ul, # result is either 0 or 1
+ "used_num" / Int32ub, # big endian
+ "get_vp" / Int32ub, # big endian
+ )
+
+ resp_data = resp_struct.build(dict(
+ result=self.result,
+ get_flag=self.get_flag,
+ used_num=self.used_num,
+ get_vp=self.get_vp,
+
+ ))
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoSynthesizeEnhancementHeroLogRequest(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoSynthesizeEnhancementHeroLogResponse(SaoBaseResponse):
+ def __init__(self, cmd, hero_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/HeroLogLevel.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ exp = hero_data[4]
+
+ for e in range(0,len(data)):
+ if exp>=int(data[e][1]) and exp bytes:
+ #new stuff
+
+ hero_log_user_data_list_struct = Struct(
+ "user_hero_log_id_size" / Int32ub, # big endian
+ "user_hero_log_id" / Int16ul[9], #string
+ "hero_log_id" / Int32ub, #int
+ "log_level" / Int16ub, #short
+ "max_log_level_extended_num" / Int16ub, #short
+ "log_exp" / Int32ub, #int
+ "possible_awakening_flag" / Int8ul, # result is either 0 or 1
+ "awakening_stage" / Int16ub, #short
+ "awakening_exp" / Int32ub, #int
+ "skill_slot_correction_value" / Int8ul, # result is either 0 or 1
+ "last_set_skill_slot1_skill_id" / Int16ub, #short
+ "last_set_skill_slot2_skill_id" / Int16ub, #short
+ "last_set_skill_slot3_skill_id" / Int16ub, #short
+ "last_set_skill_slot4_skill_id" / Int16ub, #short
+ "last_set_skill_slot5_skill_id" / Int16ub, #short
+ "property1_property_id" / Int32ub,
+ "property1_value1" / Int32ub,
+ "property1_value2" / Int32ub,
+ "property2_property_id" / Int32ub,
+ "property2_value1" / Int32ub,
+ "property2_value2" / Int32ub,
+ "property3_property_id" / Int32ub,
+ "property3_value1" / Int32ub,
+ "property3_value2" / Int32ub,
+ "property4_property_id" / Int32ub,
+ "property4_value1" / Int32ub,
+ "property4_value2" / Int32ub,
+ "converted_card_num" / Int16ub,
+ "shop_purchase_flag" / Int8ul, # result is either 0 or 1
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "hero_log_user_data_list_size" / Rebuild(Int32ub, len_(this.hero_log_user_data_list)), # big endian
+ "hero_log_user_data_list" / Array(this.hero_log_user_data_list_size, hero_log_user_data_list_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ hero_log_user_data_list_size=0,
+ hero_log_user_data_list=[],
+ )))
+
+ hero_data = dict(
+ user_hero_log_id_size=len(self.user_hero_log_id) * 2,
+ user_hero_log_id=[ord(x) for x in self.user_hero_log_id],
+ hero_log_id=self.hero_log_id,
+ log_level=self.log_level,
+ max_log_level_extended_num=self.max_log_level_extended_num,
+ log_exp=self.log_exp,
+ possible_awakening_flag=self.possible_awakening_flag,
+ awakening_stage=self.awakening_stage,
+ awakening_exp=self.awakening_exp,
+ skill_slot_correction_value=self.skill_slot_correction_value,
+ last_set_skill_slot1_skill_id=self.last_set_skill_slot1_skill_id,
+ last_set_skill_slot2_skill_id=self.last_set_skill_slot2_skill_id,
+ last_set_skill_slot3_skill_id=self.last_set_skill_slot3_skill_id,
+ last_set_skill_slot4_skill_id=self.last_set_skill_slot4_skill_id,
+ last_set_skill_slot5_skill_id=self.last_set_skill_slot5_skill_id,
+ property1_property_id=self.property1_property_id,
+ property1_value1=self.property1_value1,
+ property1_value2=self.property1_value2,
+ property2_property_id=self.property2_property_id,
+ property2_value1=self.property2_value1,
+ property2_value2=self.property2_value2,
+ property3_property_id=self.property3_property_id,
+ property3_value1=self.property3_value1,
+ property3_value2=self.property3_value2,
+ property4_property_id=self.property4_property_id,
+ property4_value1=self.property4_value1,
+ property4_value2=self.property4_value2,
+ converted_card_num=self.converted_card_num,
+ shop_purchase_flag=self.shop_purchase_flag,
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.hero_log_user_data_list.append(hero_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
+
+class SaoSynthesizeEnhancementEquipment(SaoBaseRequest):
+ def __init__(self, data: bytes) -> None:
+ super().__init__(data)
+
+class SaoSynthesizeEnhancementEquipmentResponse(SaoBaseResponse):
+ def __init__(self, cmd, synthesize_equipment_data) -> None:
+ super().__init__(cmd)
+ self.result = 1
+ equipment_level = 0
+
+ # Calculate level based off experience and the CSV list
+ with open(r'titles/sao/data/EquipmentLevel.csv') as csv_file:
+ csv_reader = csv.reader(csv_file, delimiter=',')
+ line_count = 0
+ data = []
+ rowf = False
+ for row in csv_reader:
+ if rowf==False:
+ rowf=True
+ else:
+ data.append(row)
+
+ exp = synthesize_equipment_data[4]
+
+ for e in range(0,len(data)):
+ if exp>=int(data[e][1]) and exp bytes:
+
+ after_equipment_user_data_struct = Struct(
+ "user_equipment_id_size" / Int32ub, # big endian
+ "user_equipment_id" / Int16ul[9], #string
+ "equipment_id" / Int32ub, #int
+ "enhancement_value" / Int16ub, #short
+ "max_enhancement_value_extended_num" / Int16ub, #short
+ "enhancement_exp" / Int32ub, #int
+ "possible_awakening_flag" / Int8ul, # result is either 0 or 1
+ "awakening_stage" / Int16ub, #short
+ "awakening_exp" / Int32ub, #int
+ "property1_property_id" / Int32ub,
+ "property1_value1" / Int32ub,
+ "property1_value2" / Int32ub,
+ "property2_property_id" / Int32ub,
+ "property2_value1" / Int32ub,
+ "property2_value2" / Int32ub,
+ "property3_property_id" / Int32ub,
+ "property3_value1" / Int32ub,
+ "property3_value2" / Int32ub,
+ "property4_property_id" / Int32ub,
+ "property4_value1" / Int32ub,
+ "property4_value2" / Int32ub,
+ "converted_card_num" / Int16ub,
+ "shop_purchase_flag" / Int8ul, # result is either 0 or 1
+ "protect_flag" / Int8ul, # result is either 0 or 1
+ "get_date_size" / Int32ub, # big endian
+ "get_date" / Int16ul[len(self.get_date)],
+ )
+
+ # create a resp struct
+ resp_struct = Struct(
+ "result" / Int8ul, # result is either 0 or 1
+ "after_equipment_user_data_size" / Rebuild(Int32ub, len_(this.after_equipment_user_data)), # big endian
+ "after_equipment_user_data" / Array(this.after_equipment_user_data_size, after_equipment_user_data_struct),
+ )
+
+ resp_data = resp_struct.parse(resp_struct.build(dict(
+ result=self.result,
+ after_equipment_user_data_size=0,
+ after_equipment_user_data=[],
+ )))
+
+ synthesize_equipment_data = dict(
+ user_equipment_id_size=len(self.user_equipment_id) * 2,
+ user_equipment_id=[ord(x) for x in self.user_equipment_id],
+ equipment_id=self.equipment_id,
+ enhancement_value=self.enhancement_value,
+ max_enhancement_value_extended_num=self.max_enhancement_value_extended_num,
+ enhancement_exp=self.enhancement_exp,
+ possible_awakening_flag=self.possible_awakening_flag,
+ awakening_stage=self.awakening_stage,
+ awakening_exp=self.awakening_exp,
+ property1_property_id=self.property1_property_id,
+ property1_value1=self.property1_value1,
+ property1_value2=self.property1_value2,
+ property2_property_id=self.property2_property_id,
+ property2_value1=self.property2_value1,
+ property2_value2=self.property2_value2,
+ property3_property_id=self.property3_property_id,
+ property3_value1=self.property3_value1,
+ property3_value2=self.property3_value2,
+ property4_property_id=self.property4_property_id,
+ property4_value1=self.property4_value1,
+ property4_value2=self.property4_value2,
+ converted_card_num=self.converted_card_num,
+ shop_purchase_flag=self.shop_purchase_flag,
+ protect_flag=self.protect_flag,
+ get_date_size=len(self.get_date) * 2,
+ get_date=[ord(x) for x in self.get_date],
+
+ )
+
+ resp_data.after_equipment_user_data.append(synthesize_equipment_data)
+
+ # finally, rebuild the resp_data
+ resp_data = resp_struct.build(resp_data)
+
+ self.length = len(resp_data)
+ return super().make() + resp_data
\ No newline at end of file
diff --git a/titles/sao/index.py b/titles/sao/index.py
new file mode 100644
index 0000000..69a3db5
--- /dev/null
+++ b/titles/sao/index.py
@@ -0,0 +1,116 @@
+from typing import Tuple
+from twisted.web.http import Request
+from twisted.web import resource
+import json, ast
+from datetime import datetime
+import yaml
+import logging, coloredlogs
+from logging.handlers import TimedRotatingFileHandler
+import inflection
+from os import path
+
+from core import CoreConfig, Utils
+from titles.sao.config import SaoConfig
+from titles.sao.const import SaoConstants
+from titles.sao.base import SaoBase
+from titles.sao.handlers.base import *
+
+
+class SaoServlet(resource.Resource):
+ def __init__(self, core_cfg: CoreConfig, cfg_dir: str) -> None:
+ self.isLeaf = True
+ self.core_cfg = core_cfg
+ self.config_dir = cfg_dir
+ self.game_cfg = SaoConfig()
+ if path.exists(f"{cfg_dir}/sao.yaml"):
+ self.game_cfg.update(yaml.safe_load(open(f"{cfg_dir}/sao.yaml")))
+
+ self.logger = logging.getLogger("sao")
+ if not hasattr(self.logger, "inited"):
+ log_fmt_str = "[%(asctime)s] SAO | %(levelname)s | %(message)s"
+ log_fmt = logging.Formatter(log_fmt_str)
+ fileHandler = TimedRotatingFileHandler(
+ "{0}/{1}.log".format(self.core_cfg.server.log_dir, "sao"),
+ encoding="utf8",
+ when="d",
+ backupCount=10,
+ )
+
+ fileHandler.setFormatter(log_fmt)
+
+ consoleHandler = logging.StreamHandler()
+ consoleHandler.setFormatter(log_fmt)
+
+ self.logger.addHandler(fileHandler)
+ self.logger.addHandler(consoleHandler)
+
+ self.logger.setLevel(self.game_cfg.server.loglevel)
+ coloredlogs.install(
+ level=self.game_cfg.server.loglevel, logger=self.logger, fmt=log_fmt_str
+ )
+ self.logger.inited = True
+
+ self.base = SaoBase(core_cfg, self.game_cfg)
+
+ @classmethod
+ def get_allnet_info(
+ cls, game_code: str, core_cfg: CoreConfig, cfg_dir: str
+ ) -> Tuple[bool, str, str]:
+ game_cfg = SaoConfig()
+
+ if path.exists(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}"):
+ game_cfg.update(
+ yaml.safe_load(open(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}"))
+ )
+
+ if not game_cfg.server.enable:
+ return (False, "", "")
+
+ return (
+ True,
+ f"http://{game_cfg.server.hostname}:{game_cfg.server.port}/{game_code}/$v/",
+ f"{game_cfg.server.hostname}/SDEW/$v/",
+ )
+
+ @classmethod
+ def get_mucha_info(
+ cls, core_cfg: CoreConfig, cfg_dir: str
+ ) -> Tuple[bool, str, str]:
+ game_cfg = SaoConfig()
+
+ if path.exists(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}"):
+ game_cfg.update(
+ yaml.safe_load(open(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}"))
+ )
+
+ if not game_cfg.server.enable:
+ return (False, "")
+
+ return (True, "SAO1")
+
+ def setup(self) -> None:
+ pass
+
+ def render_POST(
+ self, request: Request, version: int = 0, endpoints: str = ""
+ ) -> bytes:
+ req_url = request.uri.decode()
+ if req_url == "/matching":
+ self.logger.info("Matching request")
+
+ request.responseHeaders.addRawHeader(b"content-type", b"text/html; charset=utf-8")
+
+ sao_request = request.content.getvalue().hex()
+
+ handler = getattr(self.base, f"handle_{sao_request[:4]}", None)
+ if handler is None:
+ self.logger.info(f"Generic Handler for {req_url} - {sao_request[:4]}")
+ self.logger.debug(f"Request: {request.content.getvalue().hex()}")
+ resp = SaoNoopResponse(int.from_bytes(bytes.fromhex(sao_request[:4]), "big")+1)
+ self.logger.debug(f"Response: {resp.make().hex()}")
+ return resp.make()
+
+ self.logger.info(f"Handler {req_url} - {sao_request[:4]} request")
+ self.logger.debug(f"Request: {request.content.getvalue().hex()}")
+ self.logger.debug(f"Response: {handler(sao_request).hex()}")
+ return handler(sao_request)
\ No newline at end of file
diff --git a/titles/sao/read.py b/titles/sao/read.py
new file mode 100644
index 0000000..d70c275
--- /dev/null
+++ b/titles/sao/read.py
@@ -0,0 +1,254 @@
+from typing import Optional, Dict, List
+from os import walk, path
+import urllib
+import csv
+
+from read import BaseReader
+from core.config import CoreConfig
+from titles.sao.database import SaoData
+from titles.sao.const import SaoConstants
+
+
+class SaoReader(BaseReader):
+ def __init__(
+ self,
+ config: CoreConfig,
+ version: int,
+ bin_arg: Optional[str],
+ opt_arg: Optional[str],
+ extra: Optional[str],
+ ) -> None:
+ super().__init__(config, version, bin_arg, opt_arg, extra)
+ self.data = SaoData(config)
+
+ try:
+ self.logger.info(
+ f"Start importer for {SaoConstants.game_ver_to_string(version)}"
+ )
+ except IndexError:
+ self.logger.error(f"Invalid project SAO version {version}")
+ exit(1)
+
+ def read(self) -> None:
+ pull_bin_ram = True
+
+ if not path.exists(f"{self.bin_dir}"):
+ self.logger.warn(f"Couldn't find csv file in {self.bin_dir}, skipping")
+ pull_bin_ram = False
+
+ if pull_bin_ram:
+ self.read_csv(f"{self.bin_dir}")
+
+ def read_csv(self, bin_dir: str) -> None:
+ self.logger.info(f"Read csv from {bin_dir}")
+
+ self.logger.info("Now reading QuestScene.csv")
+ try:
+ fullPath = bin_dir + "/QuestScene.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ questSceneId = row["QuestSceneId"]
+ sortNo = row["SortNo"]
+ name = row["Name"]
+ enabled = True
+
+ self.logger.info(f"Added quest {questSceneId} | Name: {name}")
+
+ try:
+ self.data.static.put_quest(
+ questSceneId,
+ 0,
+ sortNo,
+ name,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading HeroLog.csv")
+ try:
+ fullPath = bin_dir + "/HeroLog.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ heroLogId = row["HeroLogId"]
+ name = row["Name"]
+ nickname = row["Nickname"]
+ rarity = row["Rarity"]
+ skillTableSubId = row["SkillTableSubId"]
+ awakeningExp = row["AwakeningExp"]
+ flavorText = row["FlavorText"]
+ enabled = True
+
+ self.logger.info(f"Added hero {heroLogId} | Name: {name}")
+
+ try:
+ self.data.static.put_hero(
+ 0,
+ heroLogId,
+ name,
+ nickname,
+ rarity,
+ skillTableSubId,
+ awakeningExp,
+ flavorText,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading Equipment.csv")
+ try:
+ fullPath = bin_dir + "/Equipment.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ equipmentId = row["EquipmentId"]
+ equipmentType = row["EquipmentType"]
+ weaponTypeId = row["WeaponTypeId"]
+ name = row["Name"]
+ rarity = row["Rarity"]
+ flavorText = row["FlavorText"]
+ enabled = True
+
+ self.logger.info(f"Added equipment {equipmentId} | Name: {name}")
+
+ try:
+ self.data.static.put_equipment(
+ 0,
+ equipmentId,
+ name,
+ equipmentType,
+ weaponTypeId,
+ rarity,
+ flavorText,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading Item.csv")
+ try:
+ fullPath = bin_dir + "/Item.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ itemId = row["ItemId"]
+ itemTypeId = row["ItemTypeId"]
+ name = row["Name"]
+ rarity = row["Rarity"]
+ flavorText = row["FlavorText"]
+ enabled = True
+
+ self.logger.info(f"Added item {itemId} | Name: {name}")
+
+ try:
+ self.data.static.put_item(
+ 0,
+ itemId,
+ name,
+ itemTypeId,
+ rarity,
+ flavorText,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading SupportLog.csv")
+ try:
+ fullPath = bin_dir + "/SupportLog.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ supportLogId = row["SupportLogId"]
+ charaId = row["CharaId"]
+ name = row["Name"]
+ rarity = row["Rarity"]
+ salePrice = row["SalePrice"]
+ skillName = row["SkillName"]
+ enabled = True
+
+ self.logger.info(f"Added support log {supportLogId} | Name: {name}")
+
+ try:
+ self.data.static.put_support_log(
+ 0,
+ supportLogId,
+ charaId,
+ name,
+ rarity,
+ salePrice,
+ skillName,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading Title.csv")
+ try:
+ fullPath = bin_dir + "/Title.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ titleId = row["TitleId"]
+ displayName = row["DisplayName"]
+ requirement = row["Requirement"]
+ rank = row["Rank"]
+ imageFilePath = row["ImageFilePath"]
+ enabled = True
+
+ self.logger.info(f"Added title {titleId} | Name: {displayName}")
+
+ if len(titleId) > 5:
+ try:
+ self.data.static.put_title(
+ 0,
+ titleId,
+ displayName,
+ requirement,
+ rank,
+ imageFilePath,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ elif len(titleId) < 6: # current server code cannot have multiple lengths for the id
+ continue
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
+
+ self.logger.info("Now reading RareDropTable.csv")
+ try:
+ fullPath = bin_dir + "/RareDropTable.csv"
+ with open(fullPath, encoding="UTF-8") as fp:
+ reader = csv.DictReader(fp)
+ for row in reader:
+ questRareDropId = row["QuestRareDropId"]
+ commonRewardId = row["CommonRewardId"]
+ enabled = True
+
+ self.logger.info(f"Added rare drop {questRareDropId} | Reward: {commonRewardId}")
+
+ try:
+ self.data.static.put_rare_drop(
+ 0,
+ questRareDropId,
+ commonRewardId,
+ enabled
+ )
+ except Exception as err:
+ print(err)
+ except:
+ self.logger.warn(f"Couldn't read csv file in {self.bin_dir}, skipping")
diff --git a/titles/sao/schema/__init__.py b/titles/sao/schema/__init__.py
new file mode 100644
index 0000000..3e75fc0
--- /dev/null
+++ b/titles/sao/schema/__init__.py
@@ -0,0 +1,3 @@
+from .profile import SaoProfileData
+from .static import SaoStaticData
+from .item import SaoItemData
\ No newline at end of file
diff --git a/titles/sao/schema/item.py b/titles/sao/schema/item.py
new file mode 100644
index 0000000..8b46723
--- /dev/null
+++ b/titles/sao/schema/item.py
@@ -0,0 +1,458 @@
+from typing import Optional, Dict, List
+from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, case
+from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean
+from sqlalchemy.schema import ForeignKey
+from sqlalchemy.sql import func, select, update, delete
+from sqlalchemy.engine import Row
+from sqlalchemy.dialects.mysql import insert
+
+from core.data.schema import BaseData, metadata
+
+equipment_data = Table(
+ "sao_equipment_data",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("equipment_id", Integer, nullable=False),
+ Column("enhancement_value", Integer, nullable=False),
+ Column("enhancement_exp", Integer, nullable=False),
+ Column("awakening_exp", Integer, nullable=False),
+ Column("awakening_stage", Integer, nullable=False),
+ Column("possible_awakening_flag", Integer, nullable=False),
+ Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()),
+ UniqueConstraint("user", "equipment_id", name="sao_equipment_data_uk"),
+ mysql_charset="utf8mb4",
+)
+
+item_data = Table(
+ "sao_item_data",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("item_id", Integer, nullable=False),
+ Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()),
+ UniqueConstraint("user", "item_id", name="sao_item_data_uk"),
+ mysql_charset="utf8mb4",
+)
+
+hero_log_data = Table(
+ "sao_hero_log_data",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("user_hero_log_id", Integer, nullable=False),
+ Column("log_level", Integer, nullable=False),
+ Column("log_exp", Integer, nullable=False),
+ Column("main_weapon", Integer, nullable=False),
+ Column("sub_equipment", Integer, nullable=False),
+ Column("skill_slot1_skill_id", Integer, nullable=False),
+ Column("skill_slot2_skill_id", Integer, nullable=False),
+ Column("skill_slot3_skill_id", Integer, nullable=False),
+ Column("skill_slot4_skill_id", Integer, nullable=False),
+ Column("skill_slot5_skill_id", Integer, nullable=False),
+ Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()),
+ UniqueConstraint("user", "user_hero_log_id", name="sao_hero_log_data_uk"),
+ mysql_charset="utf8mb4",
+)
+
+hero_party = Table(
+ "sao_hero_party",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("user_party_team_id", Integer, nullable=False),
+ Column("user_hero_log_id_1", Integer, nullable=False),
+ Column("user_hero_log_id_2", Integer, nullable=False),
+ Column("user_hero_log_id_3", Integer, nullable=False),
+ UniqueConstraint("user", "user_party_team_id", name="sao_hero_party_uk"),
+ mysql_charset="utf8mb4",
+)
+
+quest = Table(
+ "sao_player_quest",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("episode_id", Integer, nullable=False),
+ Column("quest_clear_flag", Boolean, nullable=False),
+ Column("clear_time", Integer, nullable=False),
+ Column("combo_num", Integer, nullable=False),
+ Column("total_damage", Integer, nullable=False),
+ Column("concurrent_destroying_num", Integer, nullable=False),
+ Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()),
+ UniqueConstraint("user", "episode_id", name="sao_player_quest_uk"),
+ mysql_charset="utf8mb4",
+)
+
+sessions = Table(
+ "sao_play_sessions",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ ),
+ Column("user_party_team_id", Integer, nullable=False),
+ Column("episode_id", Integer, nullable=False),
+ Column("play_mode", Integer, nullable=False),
+ Column("quest_drop_boost_apply_flag", Integer, nullable=False),
+ Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()),
+ UniqueConstraint("user", "user_party_team_id", "play_date", name="sao_play_sessions_uk"),
+ mysql_charset="utf8mb4",
+)
+
+class SaoItemData(BaseData):
+ def create_session(self, user_id: int, user_party_team_id: int, episode_id: int, play_mode: int, quest_drop_boost_apply_flag: int) -> Optional[int]:
+ sql = insert(sessions).values(
+ user=user_id,
+ user_party_team_id=user_party_team_id,
+ episode_id=episode_id,
+ play_mode=play_mode,
+ quest_drop_boost_apply_flag=quest_drop_boost_apply_flag
+ )
+
+ conflict = sql.on_duplicate_key_update(user=user_id)
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(f"Failed to create SAO session for user {user_id}!")
+ return None
+ return result.lastrowid
+
+ def put_item(self, user_id: int, item_id: int) -> Optional[int]:
+ sql = insert(item_data).values(
+ user=user_id,
+ item_id=item_id,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ item_id=item_id,
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert item! user: {user_id}, item_id: {item_id}"
+ )
+ return None
+
+ return result.lastrowid
+
+ def put_equipment_data(self, user_id: int, equipment_id: int, enhancement_value: int, enhancement_exp: int, awakening_exp: int, awakening_stage: int, possible_awakening_flag: int) -> Optional[int]:
+ sql = insert(equipment_data).values(
+ user=user_id,
+ equipment_id=equipment_id,
+ enhancement_value=enhancement_value,
+ enhancement_exp=enhancement_exp,
+ awakening_exp=awakening_exp,
+ awakening_stage=awakening_stage,
+ possible_awakening_flag=possible_awakening_flag,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ enhancement_value=enhancement_value,
+ enhancement_exp=enhancement_exp,
+ awakening_exp=awakening_exp,
+ awakening_stage=awakening_stage,
+ possible_awakening_flag=possible_awakening_flag,
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert equipment! user: {user_id}, equipment_id: {equipment_id}"
+ )
+ return None
+
+ return result.lastrowid
+
+ def put_hero_log(self, user_id: int, user_hero_log_id: int, log_level: int, log_exp: int, main_weapon: int, sub_equipment: int, skill_slot1_skill_id: int, skill_slot2_skill_id: int, skill_slot3_skill_id: int, skill_slot4_skill_id: int, skill_slot5_skill_id: int) -> Optional[int]:
+ sql = insert(hero_log_data).values(
+ user=user_id,
+ user_hero_log_id=user_hero_log_id,
+ log_level=log_level,
+ log_exp=log_exp,
+ main_weapon=main_weapon,
+ sub_equipment=sub_equipment,
+ skill_slot1_skill_id=skill_slot1_skill_id,
+ skill_slot2_skill_id=skill_slot2_skill_id,
+ skill_slot3_skill_id=skill_slot3_skill_id,
+ skill_slot4_skill_id=skill_slot4_skill_id,
+ skill_slot5_skill_id=skill_slot5_skill_id,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ log_level=log_level,
+ log_exp=log_exp,
+ main_weapon=main_weapon,
+ sub_equipment=sub_equipment,
+ skill_slot1_skill_id=skill_slot1_skill_id,
+ skill_slot2_skill_id=skill_slot2_skill_id,
+ skill_slot3_skill_id=skill_slot3_skill_id,
+ skill_slot4_skill_id=skill_slot4_skill_id,
+ skill_slot5_skill_id=skill_slot5_skill_id,
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert hero! user: {user_id}, user_hero_log_id: {user_hero_log_id}"
+ )
+ return None
+
+ return result.lastrowid
+
+ def put_hero_party(self, user_id: int, user_party_team_id: int, user_hero_log_id_1: int, user_hero_log_id_2: int, user_hero_log_id_3: int) -> Optional[int]:
+ sql = insert(hero_party).values(
+ user=user_id,
+ user_party_team_id=user_party_team_id,
+ user_hero_log_id_1=user_hero_log_id_1,
+ user_hero_log_id_2=user_hero_log_id_2,
+ user_hero_log_id_3=user_hero_log_id_3,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ user_hero_log_id_1=user_hero_log_id_1,
+ user_hero_log_id_2=user_hero_log_id_2,
+ user_hero_log_id_3=user_hero_log_id_3,
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert hero party! user: {user_id}, user_party_team_id: {user_party_team_id}"
+ )
+ return None
+
+ return result.lastrowid
+
+ def put_player_quest(self, user_id: int, episode_id: int, quest_clear_flag: bool, clear_time: int, combo_num: int, total_damage: int, concurrent_destroying_num: int) -> Optional[int]:
+ sql = insert(quest).values(
+ user=user_id,
+ episode_id=episode_id,
+ quest_clear_flag=quest_clear_flag,
+ clear_time=clear_time,
+ combo_num=combo_num,
+ total_damage=total_damage,
+ concurrent_destroying_num=concurrent_destroying_num
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ quest_clear_flag=quest_clear_flag,
+ clear_time=clear_time,
+ combo_num=combo_num,
+ total_damage=total_damage,
+ concurrent_destroying_num=concurrent_destroying_num
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert quest! user: {user_id}, episode_id: {episode_id}"
+ )
+ return None
+
+ return result.lastrowid
+
+ def get_user_equipment(self, user_id: int, equipment_id: int) -> Optional[Dict]:
+ sql = equipment_data.select(equipment_data.c.user == user_id and equipment_data.c.equipment_id == equipment_id)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_user_equipments(
+ self, user_id: int
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all equipments lookup given a profile
+ """
+ sql = equipment_data.select(
+ and_(
+ equipment_data.c.user == user_id,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
+ def get_user_items(
+ self, user_id: int
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all items lookup given a profile
+ """
+ sql = item_data.select(
+ and_(
+ item_data.c.user == user_id,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
+ def get_hero_log(
+ self, user_id: int, user_hero_log_id: int = None
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all hero lookup given a profile and user_party_team_id and ID specifiers
+ """
+ sql = hero_log_data.select(
+ and_(
+ hero_log_data.c.user == user_id,
+ hero_log_data.c.user_hero_log_id == user_hero_log_id if user_hero_log_id is not None else True,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_hero_logs(
+ self, user_id: int
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all hero lookup given a profile
+ """
+ sql = hero_log_data.select(
+ and_(
+ hero_log_data.c.user == user_id,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
+ def get_hero_party(
+ self, user_id: int, user_party_team_id: int = None
+ ) -> Optional[List[Row]]:
+ sql = hero_party.select(
+ and_(
+ hero_party.c.user == user_id,
+ hero_party.c.user_party_team_id == user_party_team_id if user_party_team_id is not None else True,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_quest_log(
+ self, user_id: int, episode_id: int = None
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all quest lookup given a profile and episode_id
+ """
+ sql = quest.select(
+ and_(
+ quest.c.user == user_id,
+ quest.c.episode_id == episode_id if episode_id is not None else True,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_quest_logs(
+ self, user_id: int
+ ) -> Optional[List[Row]]:
+ """
+ A catch-all quest lookup given a profile
+ """
+ sql = quest.select(
+ and_(
+ quest.c.user == user_id,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchall()
+
+ def get_session(
+ self, user_id: int = None
+ ) -> Optional[List[Row]]:
+ sql = sessions.select(
+ and_(
+ sessions.c.user == user_id,
+ )
+ ).order_by(
+ sessions.c.play_date.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def remove_hero_log(self, user_id: int, user_hero_log_id: int) -> None:
+ sql = hero_log_data.delete(
+ and_(
+ hero_log_data.c.user == user_id,
+ hero_log_data.c.user_hero_log_id == user_hero_log_id,
+ )
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to remove hero log! profile: {user_id}, user_hero_log_id: {user_hero_log_id}"
+ )
+ return None
+
+ def remove_equipment(self, user_id: int, equipment_id: int) -> None:
+ sql = equipment_data.delete(
+ and_(equipment_data.c.user == user_id, equipment_data.c.equipment_id == equipment_id)
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to remove equipment! profile: {user_id}, equipment_id: {equipment_id}"
+ )
+ return None
+
+ def remove_item(self, user_id: int, item_id: int) -> None:
+ sql = item_data.delete(
+ and_(item_data.c.user == user_id, item_data.c.item_id == item_id)
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to remove item! profile: {user_id}, item_id: {item_id}"
+ )
+ return None
\ No newline at end of file
diff --git a/titles/sao/schema/profile.py b/titles/sao/schema/profile.py
new file mode 100644
index 0000000..b125717
--- /dev/null
+++ b/titles/sao/schema/profile.py
@@ -0,0 +1,80 @@
+from typing import Optional, Dict, List
+from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, case
+from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON
+from sqlalchemy.schema import ForeignKey
+from sqlalchemy.sql import func, select, update, delete
+from sqlalchemy.engine import Row
+from sqlalchemy.dialects.mysql import insert
+
+from core.data.schema import BaseData, metadata
+from ..const import SaoConstants
+
+profile = Table(
+ "sao_profile",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column(
+ "user",
+ ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"),
+ nullable=False,
+ unique=True,
+ ),
+ Column("user_type", Integer, server_default="1"),
+ Column("nick_name", String(16), server_default="PLAYER"),
+ Column("rank_num", Integer, server_default="1"),
+ Column("rank_exp", Integer, server_default="0"),
+ Column("own_col", Integer, server_default="0"),
+ Column("own_vp", Integer, server_default="0"),
+ Column("own_yui_medal", Integer, server_default="0"),
+ Column("setting_title_id", Integer, server_default="20005"),
+)
+
+class SaoProfileData(BaseData):
+ def create_profile(self, user_id: int) -> Optional[int]:
+ sql = insert(profile).values(user=user_id)
+ conflict = sql.on_duplicate_key_update(user=user_id)
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(f"Failed to create SAO profile for user {user_id}!")
+ return None
+ return result.lastrowid
+
+ def put_profile(self, user_id: int, user_type: int, nick_name: str, rank_num: int, rank_exp: int, own_col: int, own_vp: int, own_yui_medal: int, setting_title_id: int) -> Optional[int]:
+ sql = insert(profile).values(
+ user=user_id,
+ user_type=user_type,
+ nick_name=nick_name,
+ rank_num=rank_num,
+ rank_exp=rank_exp,
+ own_col=own_col,
+ own_vp=own_vp,
+ own_yui_medal=own_yui_medal,
+ setting_title_id=setting_title_id
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ rank_num=rank_num,
+ rank_exp=rank_exp,
+ own_col=own_col,
+ own_vp=own_vp,
+ own_yui_medal=own_yui_medal,
+ setting_title_id=setting_title_id
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ self.logger.error(
+ f"{__name__} failed to insert profile! user: {user_id}"
+ )
+ return None
+
+ print(result.lastrowid)
+ return result.lastrowid
+
+ def get_profile(self, user_id: int) -> Optional[Row]:
+ sql = profile.select(profile.c.user == user_id)
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
\ No newline at end of file
diff --git a/titles/sao/schema/static.py b/titles/sao/schema/static.py
new file mode 100644
index 0000000..670e3b2
--- /dev/null
+++ b/titles/sao/schema/static.py
@@ -0,0 +1,360 @@
+from typing import Dict, List, Optional
+from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_
+from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, Float
+from sqlalchemy.engine.base import Connection
+from sqlalchemy.engine import Row
+from sqlalchemy.schema import ForeignKey
+from sqlalchemy.sql import func, select
+from sqlalchemy.dialects.mysql import insert
+
+from core.data.schema import BaseData, metadata
+
+quest = Table(
+ "sao_static_quest",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("questSceneId", Integer),
+ Column("sortNo", Integer),
+ Column("name", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "questSceneId", name="sao_static_quest_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+hero = Table(
+ "sao_static_hero_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("heroLogId", Integer),
+ Column("name", String(255)),
+ Column("nickname", String(255)),
+ Column("rarity", Integer),
+ Column("skillTableSubId", Integer),
+ Column("awakeningExp", Integer),
+ Column("flavorText", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "heroLogId", name="sao_static_hero_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+equipment = Table(
+ "sao_static_equipment_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("equipmentId", Integer),
+ Column("equipmentType", Integer),
+ Column("weaponTypeId", Integer),
+ Column("name", String(255)),
+ Column("rarity", Integer),
+ Column("flavorText", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "equipmentId", name="sao_static_equipment_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+item = Table(
+ "sao_static_item_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("itemId", Integer),
+ Column("itemTypeId", Integer),
+ Column("name", String(255)),
+ Column("rarity", Integer),
+ Column("flavorText", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "itemId", name="sao_static_item_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+support = Table(
+ "sao_static_support_log_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("supportLogId", Integer),
+ Column("charaId", Integer),
+ Column("name", String(255)),
+ Column("rarity", Integer),
+ Column("salePrice", Integer),
+ Column("skillName", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "supportLogId", name="sao_static_support_log_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+rare_drop = Table(
+ "sao_static_rare_drop_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("questRareDropId", Integer),
+ Column("commonRewardId", Integer),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "questRareDropId", "commonRewardId", name="sao_static_rare_drop_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+title = Table(
+ "sao_static_title_list",
+ metadata,
+ Column("id", Integer, primary_key=True, nullable=False),
+ Column("version", Integer),
+ Column("titleId", Integer),
+ Column("displayName", String(255)),
+ Column("requirement", Integer),
+ Column("rank", Integer),
+ Column("imageFilePath", String(255)),
+ Column("enabled", Boolean),
+ UniqueConstraint(
+ "version", "titleId", name="sao_static_title_list_uk"
+ ),
+ mysql_charset="utf8mb4",
+)
+
+class SaoStaticData(BaseData):
+ def put_quest( self, questSceneId: int, version: int, sortNo: int, name: str, enabled: bool ) -> Optional[int]:
+ sql = insert(quest).values(
+ questSceneId=questSceneId,
+ version=version,
+ sortNo=sortNo,
+ name=name,
+ tutorial=tutorial,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ name=name, questSceneId=questSceneId, version=version
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_hero( self, version: int, heroLogId: int, name: str, nickname: str, rarity: int, skillTableSubId: int, awakeningExp: int, flavorText: str, enabled: bool ) -> Optional[int]:
+ sql = insert(hero).values(
+ version=version,
+ heroLogId=heroLogId,
+ name=name,
+ nickname=nickname,
+ rarity=rarity,
+ skillTableSubId=skillTableSubId,
+ awakeningExp=awakeningExp,
+ flavorText=flavorText,
+ enabled=enabled
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ name=name, heroLogId=heroLogId
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_equipment( self, version: int, equipmentId: int, name: str, equipmentType: int, weaponTypeId:int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
+ sql = insert(equipment).values(
+ version=version,
+ equipmentId=equipmentId,
+ name=name,
+ equipmentType=equipmentType,
+ weaponTypeId=weaponTypeId,
+ rarity=rarity,
+ flavorText=flavorText,
+ enabled=enabled
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ name=name, equipmentId=equipmentId
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_item( self, version: int, itemId: int, name: str, itemTypeId: int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]:
+ sql = insert(item).values(
+ version=version,
+ itemId=itemId,
+ name=name,
+ itemTypeId=itemTypeId,
+ rarity=rarity,
+ flavorText=flavorText,
+ enabled=enabled
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ name=name, itemId=itemId
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_support_log( self, version: int, supportLogId: int, charaId: int, name: str, rarity: int, salePrice: int, skillName: str, enabled: bool ) -> Optional[int]:
+ sql = insert(support).values(
+ version=version,
+ supportLogId=supportLogId,
+ charaId=charaId,
+ name=name,
+ rarity=rarity,
+ salePrice=salePrice,
+ skillName=skillName,
+ enabled=enabled
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ name=name, supportLogId=supportLogId
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_rare_drop( self, version: int, questRareDropId: int, commonRewardId: int, enabled: bool ) -> Optional[int]:
+ sql = insert(rare_drop).values(
+ version=version,
+ questRareDropId=questRareDropId,
+ commonRewardId=commonRewardId,
+ enabled=enabled,
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ questRareDropId=questRareDropId, commonRewardId=commonRewardId, version=version
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def put_title( self, version: int, titleId: int, displayName: str, requirement: int, rank: int, imageFilePath: str, enabled: bool ) -> Optional[int]:
+ sql = insert(title).values(
+ version=version,
+ titleId=titleId,
+ displayName=displayName,
+ requirement=requirement,
+ rank=rank,
+ imageFilePath=imageFilePath,
+ enabled=enabled
+ )
+
+ conflict = sql.on_duplicate_key_update(
+ displayName=displayName, titleId=titleId
+ )
+
+ result = self.execute(conflict)
+ if result is None:
+ return None
+ return result.lastrowid
+
+ def get_quests_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = quest.select(quest.c.version == version and quest.c.enabled == enabled).order_by(
+ quest.c.questSceneId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
+
+ def get_hero_id(self, heroLogId: int) -> Optional[Dict]:
+ sql = hero.select(hero.c.heroLogId == heroLogId)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_hero_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = hero.select(hero.c.version == version and hero.c.enabled == enabled).order_by(
+ hero.c.heroLogId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
+
+ def get_equipment_id(self, equipmentId: int) -> Optional[Dict]:
+ sql = equipment.select(equipment.c.equipmentId == equipmentId)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_equipment_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = equipment.select(equipment.c.version == version and equipment.c.enabled == enabled).order_by(
+ equipment.c.equipmentId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
+
+ def get_item_id(self, itemId: int) -> Optional[Dict]:
+ sql = item.select(item.c.itemId == itemId)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_rare_drop_id(self, questRareDropId: int) -> Optional[Dict]:
+ sql = rare_drop.select(rare_drop.c.questRareDropId == questRareDropId)
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return result.fetchone()
+
+ def get_item_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = item.select(item.c.version == version and item.c.enabled == enabled).order_by(
+ item.c.itemId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
+
+ def get_support_log_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = support.select(support.c.version == version and support.c.enabled == enabled).order_by(
+ support.c.supportLogId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
+
+ def get_title_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]:
+ sql = title.select(title.c.version == version and title.c.enabled == enabled).order_by(
+ title.c.titleId.asc()
+ )
+
+ result = self.execute(sql)
+ if result is None:
+ return None
+ return [list[2] for list in result.fetchall()]
\ No newline at end of file
diff --git a/titles/wacca/base.py b/titles/wacca/base.py
index ada40c6..cca6aa5 100644
--- a/titles/wacca/base.py
+++ b/titles/wacca/base.py
@@ -624,10 +624,10 @@ class WaccaBase:
current_wp = profile["wp"]
tickets = self.data.item.get_tickets(user_id)
- new_tickets = []
+ new_tickets: List[TicketItem] = []
for ticket in tickets:
- new_tickets.append([ticket["id"], ticket["ticket_id"], 9999999999])
+ new_tickets.append(TicketItem(ticket["id"], ticket["ticket_id"], 9999999999))
for item in req.itemsUsed:
if (
@@ -645,11 +645,11 @@ class WaccaBase:
and not self.game_config.mods.infinite_tickets
):
for x in range(len(new_tickets)):
- if new_tickets[x][1] == item.itemId:
+ if new_tickets[x].ticketId == item.itemId:
self.logger.debug(
- f"Remove ticket ID {new_tickets[x][0]} type {new_tickets[x][1]} from {user_id}"
+ f"Remove ticket ID {new_tickets[x].userTicketId} type {new_tickets[x].ticketId} from {user_id}"
)
- self.data.item.spend_ticket(new_tickets[x][0])
+ self.data.item.spend_ticket(new_tickets[x].userTicketId)
new_tickets.pop(x)
break
@@ -1074,17 +1074,17 @@ class WaccaBase:
old_score = self.data.score.get_best_score(
user_id, item.itemId, item.quantity
)
- if not old_score:
- self.data.score.put_best_score(
- user_id,
- item.itemId,
- item.quantity,
- 0,
- [0] * 5,
- [0] * 13,
- 0,
- 0,
- )
+ if not old_score:
+ self.data.score.put_best_score(
+ user_id,
+ item.itemId,
+ item.quantity,
+ 0,
+ [0] * 5,
+ [0] * 13,
+ 0,
+ 0,
+ )
if item.quantity == 0:
item.quantity = WaccaConstants.Difficulty.HARD.value
diff --git a/titles/wacca/frontend.py b/titles/wacca/frontend.py
index 69ab1ee..cc40644 100644
--- a/titles/wacca/frontend.py
+++ b/titles/wacca/frontend.py
@@ -2,8 +2,9 @@ import yaml
import jinja2
from twisted.web.http import Request
from os import path
+from twisted.web.server import Session
-from core.frontend import FE_Base
+from core.frontend import FE_Base, IUserSession
from core.config import CoreConfig
from titles.wacca.database import WaccaData
from titles.wacca.config import WaccaConfig
@@ -27,7 +28,11 @@ class WaccaFrontend(FE_Base):
template = self.environment.get_template(
"titles/wacca/frontend/wacca_index.jinja"
)
+ sesh: Session = request.getSession()
+ usr_sesh = IUserSession(sesh)
+
return template.render(
title=f"{self.core_config.server.name} | {self.nav_name}",
game_list=self.environment.globals["game_list"],
+ sesh=vars(usr_sesh)
).encode("utf-16")
diff --git a/titles/wacca/handlers/user_music.py b/titles/wacca/handlers/user_music.py
index a8c80bf..26c2167 100644
--- a/titles/wacca/handlers/user_music.py
+++ b/titles/wacca/handlers/user_music.py
@@ -93,13 +93,10 @@ class UserMusicUnlockRequest(BaseRequest):
class UserMusicUnlockResponse(BaseResponse):
- def __init__(self, current_wp: int = 0, tickets_remaining: List = []) -> None:
+ def __init__(self, current_wp: int = 0, tickets_remaining: List[TicketItem] = []) -> None:
super().__init__()
self.wp = current_wp
- self.tickets: List[TicketItem] = []
-
- for ticket in tickets_remaining:
- self.tickets.append(TicketItem(ticket[0], ticket[1], ticket[2]))
+ self.tickets = tickets_remaining
def make(self) -> Dict:
tickets = []