diff --git a/SVSim.Bootstrap/Data/build-deck/build_deck_package_master.csv b/SVSim.Bootstrap/Data/build-deck/build_deck_package_master.csv
new file mode 100644
index 0000000..3514786
--- /dev/null
+++ b/SVSim.Bootstrap/Data/build-deck/build_deck_package_master.csv
@@ -0,0 +1,1885 @@
+product_id,card_id,number,is_spot
+1,701141011,1,0
+1,102141010,1,0
+1,101131020,1,0
+1,102131030,1,0
+1,101131050,1,0
+1,102131020,1,0
+1,102131010,1,0
+1,101121020,2,0
+1,101121010,2,0
+1,101121080,3,0
+1,102121010,2,0
+1,102121030,2,0
+1,101121110,2,0
+1,101111010,3,0
+1,101114050,3,0
+1,101114010,2,0
+1,102111060,2,0
+1,100111010,2,0
+1,100114010,3,0
+1,100111020,3,0
+1,100111070,2,0
+2,701241011,1,0
+2,101241020,1,0
+2,102231010,1,0
+2,101231050,1,0
+2,101234020,1,0
+2,101231040,1,0
+2,101231020,1,0
+2,102221010,3,0
+2,102224040,2,0
+2,101221010,2,0
+2,101221070,2,0
+2,101221100,2,0
+2,101221060,2,0
+2,101211110,2,0
+2,101211090,2,0
+2,101211060,2,0
+2,101211070,2,0
+2,102211050,2,0
+2,100211010,3,0
+2,100211020,3,0
+2,100211040,2,0
+2,100221020,2,0
+3,701341011,1,0
+3,101341010,1,0
+3,102331010,1,0
+3,101334040,1,0
+3,101334030,1,0
+3,102334020,1,0
+3,101334020,1,0
+3,101024010,3,0
+3,101321040,2,0
+3,102324040,2,0
+3,101324040,2,0
+3,101324050,2,0
+3,101321070,2,0
+3,101314010,3,0
+3,101311010,2,0
+3,101311050,2,0
+3,101314020,3,0
+3,100314010,2,0
+3,100314040,2,0
+3,100314020,2,0
+3,100314030,2,0
+3,100321010,2,0
+4,701441011,1,0
+4,101441010,1,0
+4,101431040,1,0
+4,101431030,1,0
+4,102431010,1,0
+4,101431050,1,0
+4,101431020,1,0
+4,101424010,2,0
+4,101421080,3,0
+4,101421020,2,0
+4,102421020,2,0
+4,102021030,2,0
+4,101421070,2,0
+4,101411110,2,0
+4,102411020,3,0
+4,101411030,3,0
+4,101411070,2,0
+4,100414020,3,0
+4,100414010,3,0
+4,100411040,2,0
+4,100421020,2,0
+5,701541011,1,0
+5,102541010,1,0
+5,101534020,1,0
+5,101534010,1,0
+5,102531010,1,0
+5,101534030,1,0
+5,101531050,1,0
+5,101521010,2,0
+5,101521020,2,0
+5,102521040,3,0
+5,101521030,2,0
+5,102521010,2,0
+5,101521060,2,0
+5,101514010,2,0
+5,101511120,3,0
+5,102511010,3,0
+5,102514050,2,0
+5,100511010,3,0
+5,100514010,2,0
+5,100511040,3,0
+5,100521030,2,0
+6,701641011,1,0
+6,102641010,1,0
+6,102631030,1,0
+6,101633010,1,0
+6,101631040,1,0
+6,101634020,1,0
+6,101631050,1,0
+6,101621070,2,0
+6,101621030,2,0
+6,102621010,2,0
+6,101624010,3,0
+6,101021040,2,0
+6,101621050,2,0
+6,101611040,2,0
+6,101611050,1,0
+6,101614020,3,0
+6,102614050,2,0
+6,101611140,2,0
+6,100614010,2,0
+6,100614020,3,0
+6,100614030,2,0
+6,100611040,3,0
+7,701741011,1,0
+7,101741020,1,0
+7,101733020,1,0
+7,102731030,1,0
+7,102731010,1,0
+7,101734010,1,0
+7,101731010,1,0
+7,102723010,3,0
+7,102021020,2,0
+7,101721020,2,0
+7,101721040,2,0
+7,101721100,2,0
+7,101721050,2,0
+7,101713020,2,0
+7,101713010,2,0
+7,101711090,2,0
+7,102711010,2,0
+7,101713050,2,0
+7,100714020,3,0
+7,100714010,3,0
+7,100713010,2,0
+7,100713030,2,0
+201,703141011,1,0
+201,104141010,1,0
+201,104131030,1,0
+201,104131020,1,0
+201,104123010,2,0
+201,104121040,2,0
+201,104121030,3,0
+201,104114010,2,0
+201,104111040,2,0
+201,104111020,2,0
+201,103134010,1,0
+201,103131030,1,0
+201,103121030,2,0
+201,103121020,2,0
+201,103114020,2,0
+201,103111030,2,0
+201,103031020,1,0
+201,103021020,2,0
+201,100114010,3,0
+201,100111060,2,0
+201,100111020,3,0
+201,100111010,2,0
+202,703241011,1,0
+202,104241020,1,0
+202,104232010,1,0
+202,104231030,1,0
+202,104231020,1,0
+202,104221040,2,0
+202,104221030,3,0
+202,104221020,2,0
+202,104211040,2,0
+202,104211020,3,0
+202,103231030,1,0
+202,103231020,1,0
+202,103224010,2,0
+202,103221040,2,0
+202,103221020,2,0
+202,103211050,3,0
+202,103211030,2,0
+202,100211040,2,0
+202,100211030,2,0
+202,100211020,3,0
+202,100211010,3,0
+203,703341011,1,0
+203,104334010,1,0
+203,104331020,1,0
+203,104324010,2,0
+203,104321040,2,0
+203,104321020,2,0
+203,103341010,1,0
+203,103334010,1,0
+203,103331030,1,0
+203,103331020,1,0
+203,103324010,2,0
+203,103321040,2,0
+203,103321030,3,0
+203,103314010,2,0
+203,103311060,2,0
+203,103311050,3,0
+203,103311030,3,0
+203,100321010,2,0
+203,100314030,2,0
+203,100314020,3,0
+203,100314010,3,0
+204,703441011,1,0
+204,104441020,1,0
+204,104431030,1,0
+204,104431020,1,0
+204,104424010,2,0
+204,104421040,2,0
+204,104412010,2,0
+204,104411040,2,0
+204,104411030,3,0
+204,104031020,1,0
+204,103434010,1,0
+204,103431030,1,0
+204,103424010,3,0
+204,103421030,2,0
+204,103421020,2,0
+204,103411030,3,0
+204,103021030,2,0
+204,100421020,2,0
+204,100414020,3,0
+204,100414010,3,0
+204,100411040,2,0
+205,703541011,1,0
+205,104541020,1,0
+205,104533010,1,0
+205,104531030,1,0
+205,104531020,1,0
+205,104521030,2,0
+205,104521020,2,0
+205,104514010,2,0
+205,104021020,2,0
+205,103534010,1,0
+205,103531020,1,0
+205,103521040,2,0
+205,103521030,2,0
+205,103514020,3,0
+205,103511050,3,0
+205,103511030,2,0
+205,103021040,3,0
+205,100521030,2,0
+205,100514010,2,0
+205,100511050,3,0
+205,100511010,3,0
+206,703641011,1,0
+206,104641020,1,0
+206,104633010,1,0
+206,104631030,1,0
+206,104631020,1,0
+206,104623010,2,0
+206,104621040,2,0
+206,104621020,3,0
+206,104614010,2,0
+206,104611030,2,0
+206,104611020,2,0
+206,103634010,1,0
+206,103631030,1,0
+206,103624010,3,0
+206,103621020,3,0
+206,103611030,2,0
+206,103011030,2,0
+206,100614030,2,0
+206,100614020,2,0
+206,100611050,3,0
+206,100611040,3,0
+207,703741011,1,0
+207,104741010,1,0
+207,104733010,1,0
+207,104731030,1,0
+207,104731020,1,0
+207,104723010,2,0
+207,104721030,2,0
+207,104721020,2,0
+207,104711040,2,0
+207,104711020,2,0
+207,103733010,1,0
+207,103731020,1,0
+207,103721040,3,0
+207,103721030,2,0
+207,103721020,2,0
+207,103711060,2,0
+207,103711040,2,0
+207,103011050,2,0
+207,100714030,2,0
+207,100714020,3,0
+207,100713030,2,0
+207,100711010,3,0
+301,106141010,1,0
+301,106141020,1,0
+301,105131020,2,0
+301,105131010,2,0
+301,106131020,2,0
+301,106133010,2,0
+301,106121020,3,0
+301,105123010,3,0
+301,106124010,3,0
+301,105121010,2,0
+301,106021010,3,0
+301,106114010,3,0
+301,105111020,2,0
+301,106111010,3,0
+301,106111030,2,0
+301,100111020,2,0
+301,100114010,1,0
+301,100111010,3,0
+302,106241010,1,0
+302,105241020,1,0
+302,106231020,3,0
+302,106231010,2,0
+302,106234010,3,0
+302,105224010,2,0
+302,105221030,3,0
+302,106221010,2,0
+302,106221020,3,0
+302,106221030,2,0
+302,104221020,2,0
+302,104211040,2,0
+302,105211010,2,0
+302,104211020,3,0
+302,105011020,3,0
+302,100211010,3,0
+302,100221020,3,0
+303,105341010,1,0
+303,106341010,1,0
+303,106331020,2,0
+303,105331020,3,0
+303,105334010,3,0
+303,106324010,2,0
+303,106321030,3,0
+303,106321010,2,0
+303,105322010,2,0
+303,105321010,2,0
+303,104321030,3,0
+303,106312010,3,0
+303,105312010,3,0
+303,104311040,3,0
+303,104311030,1,0
+303,100314020,2,0
+303,100314030,2,0
+303,100311010,2,0
+304,106441010,1,0
+304,105041020,1,0
+304,106031020,2,0
+304,106434010,2,0
+304,106431020,2,0
+304,106033010,2,0
+304,106021020,3,0
+304,106421020,3,0
+304,104421040,2,0
+304,104424010,2,0
+304,105421020,2,0
+304,105021030,2,0
+304,106411010,3,0
+304,105411010,3,0
+304,104411020,1,0
+304,104411030,3,0
+304,100414010,3,0
+304,100414020,3,0
+305,106541020,1,0
+305,106541010,1,0
+305,106531020,3,0
+305,106531010,3,0
+305,105531010,2,0
+305,105521010,3,0
+305,104521030,3,0
+305,104521020,2,0
+305,104021020,3,0
+305,106521010,3,0
+305,104514010,3,0
+305,106511010,1,0
+305,105511010,3,0
+305,106511030,3,0
+305,100511010,3,0
+305,100514010,3,0
+306,105641020,1,0
+306,106641010,1,0
+306,106634010,3,0
+306,106631010,2,0
+306,105631010,3,0
+306,106624010,3,0
+306,106621020,3,0
+306,105621010,3,0
+306,104621020,3,0
+306,104623010,2,0
+306,105611010,3,0
+306,104611020,3,0
+306,106011020,1,0
+306,106611020,3,0
+306,100611050,2,0
+306,100614020,2,0
+306,100614010,2,0
+307,106741010,1,0
+307,105741010,1,0
+307,105731020,2,0
+307,106733010,3,0
+307,106731020,3,0
+307,106721020,2,0
+307,106721030,2,0
+307,105723010,3,0
+307,105021010,2,0
+307,106724010,3,0
+307,105721020,2,0
+307,106713010,3,0
+307,104011040,1,0
+307,105711030,3,0
+307,105711010,3,0
+307,100714020,3,0
+307,100713010,3,0
+401,705114011,3,0
+401,109141010,1,0
+401,107141020,1,0
+401,109131020,1,0
+401,107131010,3,0
+401,108131010,2,0
+401,108131030,3,0
+401,109121010,1,0
+401,106124010,3,0
+401,108121010,3,0
+401,108121020,3,0
+401,108124010,3,0
+401,109111030,1,0
+401,107111030,3,0
+401,108111010,3,0
+401,108113010,3,0
+401,100111010,3,0
+402,705214011,3,0
+402,109241010,1,0
+402,108241010,1,0
+402,109234010,1,0
+402,107231010,3,0
+402,108231010,2,0
+402,108234010,3,0
+402,109221010,1,0
+402,106221010,3,0
+402,107221010,3,0
+402,107221020,3,0
+402,108221030,3,0
+402,109211010,1,0
+402,107211020,3,0
+402,107214010,3,0
+402,108211030,3,0
+402,100211020,3,0
+403,705314011,3,0
+403,109341010,1,0
+403,108341010,1,0
+403,109331020,1,0
+403,107334010,2,0
+403,107334020,3,0
+403,108334010,3,0
+403,109321020,1,0
+403,106324010,3,0
+403,107322010,3,0
+403,107324010,3,0
+403,108321020,3,0
+403,109311010,1,0
+403,107314020,3,0
+403,108311010,3,0
+403,108311020,3,0
+403,100314030,3,0
+404,705414011,3,0
+404,109441010,1,0
+404,107441020,1,0
+404,109431010,1,0
+404,107431010,3,0
+404,108431010,3,0
+404,108434010,2,0
+404,109421010,1,0
+404,106423010,3,0
+404,107021020,3,0
+404,108421020,3,0
+404,108424010,3,0
+404,109411020,1,0
+404,107411010,3,0
+404,107411020,3,0
+404,108411040,3,0
+404,100414020,3,0
+405,705514011,3,0
+405,109541010,1,0
+405,107541010,1,0
+405,109531010,1,0
+405,107531020,3,0
+405,108531010,2,0
+405,108531020,3,0
+405,109521020,1,0
+405,106524010,3,0
+405,107021010,3,0
+405,108521010,3,0
+405,108521020,3,0
+405,109511020,1,0
+405,107511010,3,0
+405,107513010,3,0
+405,108511030,3,0
+405,100511010,3,0
+406,705614021,3,0
+406,109641010,1,0
+406,108641010,1,0
+406,109631020,1,0
+406,107634010,3,0
+406,108631020,3,0
+406,108634010,2,0
+406,109621020,1,0
+406,106624010,3,0
+406,107621020,3,0
+406,108621010,3,0
+406,108621020,3,0
+406,109611020,1,0
+406,107611020,3,0
+406,107614010,3,0
+406,108614010,3,0
+406,100611050,3,0
+407,705714011,3,0
+407,109741010,1,0
+407,107741010,1,0
+407,109731010,1,0
+407,107732010,2,0
+407,108731010,3,0
+407,108733010,3,0
+407,109721020,1,0
+407,106724010,3,0
+407,107723010,3,0
+407,107724010,3,0
+407,108721010,3,0
+407,109711020,1,0
+407,107713010,3,0
+407,108713010,3,0
+407,108714010,3,0
+407,100713010,3,0
+408,705814011,3,0
+408,109841010,1,0
+408,107841030,1,0
+408,109831010,1,0
+408,107831010,2,0
+408,107831020,3,0
+408,107834020,3,0
+408,109821020,1,0
+408,107821030,3,0
+408,107821040,3,0
+408,107824020,3,0
+408,108821010,3,0
+408,109811010,1,0
+408,107811090,3,0
+408,107811100,3,0
+408,107813030,3,0
+408,100811070,3,0
+501,111141020,1,0
+501,110141020,2,0
+501,110141030,2,0
+501,109131020,3,0
+501,110131010,3,0
+501,110131030,3,0
+501,108121010,3,0
+501,110121010,3,0
+501,109023010,3,0
+501,108113010,3,0
+501,108111030,3,0
+501,110114010,3,0
+501,100111010,3,0
+501,100111020,3,0
+501,100114010,2,0
+502,111241020,1,0
+502,109241020,2,0
+502,110241010,2,0
+502,109234010,3,0
+502,110231020,3,0
+502,110231010,3,0
+502,108221030,3,0
+502,110221030,3,0
+502,110221010,3,0
+502,110214010,3,0
+502,110211030,3,0
+502,108211030,3,0
+502,100211010,3,0
+502,100211020,3,0
+502,100221020,2,0
+503,111341020,1,0
+503,109341030,2,0
+503,110341030,2,0
+503,109331010,3,0
+503,110331010,3,0
+503,110331030,3,0
+503,108321020,3,0
+503,110324010,3,0
+503,111321020,3,0
+503,110311010,3,0
+503,109314010,3,0
+503,111311030,3,0
+503,100314010,3,0
+503,100314030,3,0
+503,100314020,2,0
+504,111441020,1,0
+504,110441010,2,0
+504,110441030,2,0
+504,109431030,3,0
+504,110434010,3,0
+504,110431020,3,0
+504,108424010,3,0
+504,109421010,3,0
+504,110421030,3,0
+504,108411040,3,0
+504,110411010,3,0
+504,110411030,3,0
+504,100414020,3,0
+504,100414010,3,0
+504,100411040,2,0
+505,111541020,1,0
+505,110541010,2,0
+505,110041020,2,0
+505,109031010,3,0
+505,110531010,3,0
+505,110531030,3,0
+505,109521020,3,0
+505,109521010,3,0
+505,110521010,3,0
+505,108511030,3,0
+505,109514010,3,0
+505,110511020,3,0
+505,100514010,3,0
+505,100511010,3,0
+505,100511020,2,0
+506,111641020,1,0
+506,109641010,2,0
+506,110641010,2,0
+506,109631020,3,0
+506,109631010,3,0
+506,110631020,3,0
+506,109623010,3,0
+506,109621010,3,0
+506,110621020,3,0
+506,109611010,3,0
+506,110611020,3,0
+506,110611030,3,0
+506,100614020,3,0
+506,100614010,3,0
+506,100611050,2,0
+507,111741020,1,0
+507,110741030,2,0
+507,109041020,2,0
+507,109731010,3,0
+507,109734010,3,0
+507,110731020,3,0
+507,108721010,3,0
+507,108722010,3,0
+507,109724010,3,0
+507,108713010,3,0
+507,108714010,3,0
+507,109713010,3,0
+507,100713010,3,0
+507,100714020,3,0
+507,100714010,2,0
+508,111841020,1,0
+508,109841020,2,0
+508,110841010,2,0
+508,109831010,3,0
+508,110834010,3,0
+508,110831020,3,0
+508,109821010,3,0
+508,110821010,3,0
+508,110821020,3,0
+508,108811030,3,0
+508,110811020,3,0
+508,110811030,3,0
+508,100824010,3,0
+508,100811030,3,0
+508,100811020,2,0
+601,111141010,2,0
+601,112041020,2,0
+601,112141010,1,0
+601,112031020,3,0
+601,112131020,3,0
+601,110131020,3,0
+601,112021020,3,0
+601,112122010,3,0
+601,111124010,3,0
+601,112011020,3,0
+601,112111010,3,0
+601,110114010,3,0
+601,100111010,3,0
+601,100111020,2,0
+601,100114010,3,0
+602,112241010,2,0
+602,112241020,2,0
+602,111241010,1,0
+602,112231030,3,0
+602,112231010,3,0
+602,111231010,3,0
+602,111221020,3,0
+602,112222010,3,0
+602,112224010,3,0
+602,113011010,3,0
+602,112011030,3,0
+602,112211010,3,0
+602,100211010,3,0
+602,100211020,3,0
+602,100211050,2,0
+603,112341020,2,0
+603,112341030,2,0
+603,110341010,1,0
+603,112331020,3,0
+603,111331020,3,0
+603,111331010,3,0
+603,112322010,3,0
+603,110324010,3,0
+603,110024010,3,0
+603,111311020,3,0
+603,111314010,3,0
+603,112314010,3,0
+603,100314010,3,0
+603,100314020,3,0
+603,100314070,2,0
+604,112441010,2,0
+604,112441020,2,0
+604,111441010,1,0
+604,111431020,3,0
+604,112431010,3,0
+604,112433010,3,0
+604,111421010,3,0
+604,111421020,3,0
+604,112422010,3,0
+604,112411010,3,0
+604,111411030,3,0
+604,111414010,3,0
+604,100414020,3,0
+604,100414010,3,0
+604,100411040,2,0
+605,112541020,2,0
+605,112541030,2,0
+605,112541010,1,0
+605,111531010,3,0
+605,112531010,3,0
+605,111031020,3,0
+605,110521020,3,0
+605,112521010,3,0
+605,112521020,3,0
+605,112511020,3,0
+605,112511030,3,0
+605,111514010,3,0
+605,100514010,3,0
+605,100511010,3,0
+605,100511020,2,0
+606,112641020,2,0
+606,112641030,2,0
+606,112041010,1,0
+606,112631020,3,0
+606,112631010,3,0
+606,112634010,3,0
+606,112621010,3,0
+606,112621020,3,0
+606,111624010,3,0
+606,113611010,3,0
+606,112611030,3,0
+606,111611010,3,0
+606,100614010,3,0
+606,100614020,3,0
+606,100611050,2,0
+607,111741030,2,0
+607,112741020,2,0
+607,111741020,1,0
+607,112731020,3,0
+607,112731010,3,0
+607,111031010,3,0
+607,113721010,3,0
+607,112721020,3,0
+607,110721010,3,0
+607,113711020,3,0
+607,112711010,3,0
+607,111711020,3,0
+607,100713010,3,0
+607,100714020,3,0
+607,100714030,2,0
+608,112841030,2,0
+608,111841010,2,0
+608,112841020,1,0
+608,111831030,3,0
+608,111831020,3,0
+608,112834010,3,0
+608,112821010,3,0
+608,112821020,3,0
+608,111824010,3,0
+608,112811030,3,0
+608,110811010,3,0
+608,111814010,3,0
+608,100811070,3,0
+608,100811040,3,0
+608,100811050,2,0
+701,115141020,1,0
+701,114141020,2,0
+701,113141010,2,0
+701,113131030,3,0
+701,114131020,3,0
+701,114131010,3,0
+701,114124010,3,0
+701,114121020,3,0
+701,113121010,3,0
+701,114111030,3,0
+701,114114010,3,0
+701,113114010,3,0
+701,100114010,3,0
+701,100111010,2,0
+701,100111020,3,0
+702,115241020,1,0
+702,114241020,2,0
+702,113241020,2,0
+702,114231010,3,0
+702,113234010,3,0
+702,114234010,3,0
+702,114224010,3,0
+702,114221010,3,0
+702,114221020,3,0
+702,114211030,3,0
+702,114211010,3,0
+702,113211020,3,0
+702,100211010,3,0
+702,100211060,2,0
+702,100211020,3,0
+703,115341020,1,0
+703,114341010,2,0
+703,114041010,2,0
+703,113334010,3,0
+703,114331020,3,0
+703,114331010,3,0
+703,114324010,3,0
+703,114321010,3,0
+703,114021010,3,0
+703,114311010,3,0
+703,114311020,3,0
+703,115311020,3,0
+703,100314010,3,0
+703,100314020,2,0
+703,100314070,3,0
+704,115441020,1,0
+704,114441020,2,0
+704,114441030,2,0
+704,114434010,3,0
+704,113431020,3,0
+704,114431010,3,0
+704,114424010,3,0
+704,114421020,3,0
+704,113421030,3,0
+704,114411030,3,0
+704,114411020,3,0
+704,113414010,3,0
+704,100414020,3,0
+704,100411040,2,0
+704,100414010,3,0
+705,115541020,1,0
+705,114541010,2,0
+705,114541020,2,0
+705,114531010,3,0
+705,113531020,3,0
+705,113531010,3,0
+705,114524010,3,0
+705,114521020,3,0
+705,114521010,3,0
+705,114511030,3,0
+705,113511020,3,0
+705,112511030,3,0
+705,100514010,3,0
+705,100511050,2,0
+705,100511010,3,0
+706,115641020,1,0
+706,114641010,2,0
+706,114641020,2,0
+706,113631010,3,0
+706,114631010,3,0
+706,114631020,3,0
+706,114624010,3,0
+706,113621010,3,0
+706,114621020,3,0
+706,113614010,3,0
+706,114611030,3,0
+706,114611010,3,0
+706,100614020,3,0
+706,100611050,2,0
+706,100614010,3,0
+707,115741020,1,0
+707,114741010,2,0
+707,114741030,2,0
+707,113733010,3,0
+707,113731010,3,0
+707,114731020,3,0
+707,114724010,3,0
+707,112722010,3,0
+707,114721020,3,0
+707,114713010,3,0
+707,114711030,3,0
+707,114011010,3,0
+707,100714020,3,0
+707,100714030,2,0
+707,100713010,3,0
+708,115841020,1,0
+708,114841010,2,0
+708,114844010,2,0
+708,114031020,3,0
+708,114831020,3,0
+708,114831010,3,0
+708,114821010,3,0
+708,114821020,3,0
+708,113821010,3,0
+708,113811020,3,0
+708,113814010,3,0
+708,114811030,3,0
+708,100811030,3,0
+708,100811020,2,0
+708,100824010,3,0
+10001,113131010,3,1
+10001,113131030,3,1
+10001,115141030,3,1
+10001,112114010,3,1
+10001,114114010,3,1
+10001,114124010,3,1
+10001,114014010,3,1
+10001,113131020,3,1
+10001,115141020,3,1
+10001,112134010,3,1
+10001,114011010,3,1
+10001,113114010,2,1
+10001,114141030,3,1
+10001,116141010,2,1
+10002,115241010,3,1
+10002,113234010,3,1
+10002,114234020,3,1
+10002,113211020,3,1
+10002,113221020,2,1
+10002,115231010,3,1
+10002,114214010,2,1
+10002,115031020,3,1
+10002,116041010,3,1
+10002,115241020,3,1
+10002,116221010,3,1
+10002,116234010,2,1
+10002,115231020,3,1
+10002,113241020,3,1
+10002,114241010,1,1
+10003,115024010,3,1
+10003,114324010,3,1
+10003,114031010,3,1
+10003,114014010,3,1
+10003,114311010,3,1
+10003,115311020,3,1
+10003,114314010,1,1
+10003,116041010,1,1
+10003,114311020,3,1
+10003,114321010,3,1
+10003,116331010,3,1
+10003,115341020,3,1
+10003,114341010,3,1
+10003,115341030,2,1
+10003,114331010,3,1
+10004,114424010,3,1
+10004,113011010,2,1
+10004,116031010,3,1
+10004,114014010,3,1
+10004,114411030,3,1
+10004,116411030,3,1
+10004,100414010,3,0
+10004,114421020,3,1
+10004,116431010,3,1
+10004,112422010,2,1
+10004,114441020,3,1
+10004,116441020,3,1
+10004,116041020,3,1
+10004,114441030,3,1
+10005,114521020,3,1
+10005,114524010,3,1
+10005,115514010,2,1
+10005,114031010,3,1
+10005,114014010,3,1
+10005,114511030,3,1
+10005,114541020,3,1
+10005,114541030,3,1
+10005,115521010,2,1
+10005,115531030,2,1
+10005,116541010,2,1
+10005,116521010,3,1
+10005,114541010,3,1
+10005,116534010,2,1
+10005,115541010,3,1
+10006,115621030,3,1
+10006,114624010,2,1
+10006,115634010,3,1
+10006,114611030,3,1
+10006,115631020,3,1
+10006,116611010,3,1
+10006,116621020,3,1
+10006,100614020,3,0
+10006,116634010,3,1
+10006,114011010,1,1
+10006,113641020,3,1
+10006,115641020,3,1
+10006,112634010,3,1
+10006,116641010,3,1
+10006,114641020,1,1
+10007,112011030,1,1
+10007,113011010,3,1
+10007,116031010,3,1
+10007,114014010,3,1
+10007,112721020,3,1
+10007,113721010,3,1
+10007,116731020,3,1
+10007,114011010,3,1
+10007,112711010,3,1
+10007,112741020,3,1
+10007,113741020,3,1
+10007,116741010,3,1
+10007,116741020,3,1
+10007,116041020,3,1
+10008,115814010,3,1
+10008,116821020,3,1
+10008,112834010,3,1
+10008,116814010,3,1
+10008,113811010,1,1
+10008,116811010,3,1
+10008,116811020,3,1
+10008,114841020,3,1
+10008,116831010,3,1
+10008,116834010,3,1
+10008,113831010,3,1
+10008,113841010,3,1
+10008,112841020,3,1
+10008,115841030,3,1
+11901,118011010,3,1
+11901,118111030,3,1
+11901,118011020,3,1
+11901,118031010,3,1
+11901,118111020,3,1
+11901,118131020,3,1
+11901,119111010,3,1
+11901,116041010,2,1
+11901,118021010,3,1
+11901,115111030,3,1
+11901,116141030,1,1
+11901,118121020,3,1
+11901,119141010,1,1
+11901,118021020,3,1
+11901,118131010,3,1
+11902,100211010,3,0
+11902,117214010,3,1
+11902,115231010,3,1
+11902,116211010,3,1
+11902,117211030,3,1
+11902,117224010,3,1
+11902,119224010,3,1
+11902,116221010,3,1
+11902,119211020,3,1
+11902,115234010,3,1
+11902,118214010,3,1
+11902,118241030,3,1
+11902,119231020,3,1
+11902,119241010,1,1
+11905,115531010,3,1
+11905,118511020,3,1
+11905,118011020,3,1
+11905,118511030,3,1
+11905,118541010,2,1
+11905,119511030,3,1
+11905,119541010,1,1
+11905,117534010,3,1
+11905,118511010,3,1
+11905,119511020,3,1
+11905,118521020,3,1
+11905,118524010,3,1
+11905,117541010,1,1
+11905,116534010,3,1
+11905,118521010,3,1
+11906,117611020,3,1
+11906,119611010,3,1
+11906,117634010,3,1
+11906,115611020,3,1
+11906,116611010,3,1
+11906,117621020,3,1
+11906,117631020,3,1
+11906,118611010,3,1
+11906,100614020,3,0
+11906,117621010,3,1
+11906,119624010,3,1
+11906,115641010,1,1
+11906,117641020,2,1
+11906,119631020,1,1
+11906,119641010,1,1
+11906,117631010,2,1
+12003,100314010,3,1
+12003,120324010,3,1
+12003,119031010,3,1
+12003,117014010,2,1
+12003,118341030,2,1
+12003,100314020,3,1
+12003,116334010,3,1
+12003,117324010,3,1
+12003,118324010,3,1
+12003,119334010,1,1
+12003,120314010,3,1
+12003,119011010,3,1
+12003,120331010,3,1
+12003,120341010,2,1
+12003,116314010,3,1
+12004,119424010,2,1
+12004,118431010,3,1
+12004,120411010,3,1
+12004,120421020,3,1
+12004,100414010,3,1
+12004,117434010,2,1
+12004,118424010,3,1
+12004,120414010,3,1
+12004,116434010,3,1
+12004,118441030,1,1
+12004,119441030,1,1
+12004,120421010,3,1
+12004,119044010,1,1
+12004,120411030,2,1
+12004,120431020,2,1
+12004,120441020,1,1
+12004,118411030,3,1
+12004,119421020,1,1
+12007,117724010,3,1
+12007,119713010,3,1
+12007,119021020,3,1
+12007,116714010,3,1
+12007,117721010,2,1
+12007,117731020,3,1
+12007,120711010,1,1
+12007,120741010,1,1
+12007,120714010,3,1
+12007,118732010,3,1
+12007,117031020,1,1
+12007,117741030,2,1
+12007,119731020,3,1
+12007,100714030,1,1
+12007,118714010,3,1
+12007,117041010,1,1
+12007,117721020,1,1
+12007,118721020,3,1
+12008,116821020,3,1
+12008,117811020,3,1
+12008,116814010,3,1
+12008,117824010,3,1
+12008,116811010,3,1
+12008,120821020,3,1
+12008,116811020,3,1
+12008,119811020,3,1
+12008,116831010,1,1
+12008,118831010,1,1
+12008,116834010,1,1
+12008,117841030,2,1
+12008,120811020,2,1
+12008,120831010,1,1
+12008,120841010,1,1
+12008,120831020,3,1
+12008,119041010,1,1
+12008,119831020,3,1
+12104,121034010,3,1
+12104,118411020,3,1
+12104,119424010,3,1
+12104,121424010,3,1
+12104,118011020,3,1
+12104,121421010,3,1
+12104,100414010,3,1
+12104,117434010,1,1
+12104,118424010,1,1
+12104,121414010,3,1
+12104,121434010,2,1
+12104,121411010,3,1
+12104,121431010,3,1
+12104,119441030,1,1
+12104,121044010,1,1
+12104,120431010,1,1
+12104,121441010,2,1
+12104,119421020,1,1
+12106,121023010,3,1
+12106,121634010,3,1
+12106,121613010,3,1
+12106,118011020,3,1
+12106,118611010,3,1
+12106,118631010,3,1
+12106,119621020,3,1
+12106,120641020,1,1
+12106,120641030,1,1
+12106,121641010,2,1
+12106,120624010,3,1
+12106,121624010,2,1
+12106,118021010,3,1
+12106,119621010,3,1
+12106,119631020,1,1
+12106,118633010,3,1
+12108,120014010,3,1
+12108,121023010,3,1
+12108,118811020,3,1
+12108,121824010,3,1
+12108,117811010,3,1
+12108,120821020,3,1
+12108,121821010,3,1
+12108,121821020,3,1
+12108,121841010,1,1
+12108,121814010,2,1
+12108,121831010,3,1
+12108,121834010,3,1
+12108,121031010,1,1
+12108,119831030,3,1
+12108,120841020,1,1
+12108,121841020,2,1
+12201,120014010,2,1
+12201,120141020,1,1
+12201,122131010,3,1
+12201,122131020,3,1
+12201,119111010,3,1
+12201,120121020,3,1
+12201,122121030,3,1
+12201,120134010,2,1
+12201,120123010,3,1
+12201,120111040,3,1
+12201,121131010,2,1
+12201,122121020,3,1
+12201,120141010,2,1
+12201,122111010,3,1
+12201,122141010,1,1
+12201,119111040,3,1
+12204,122421010,2,1
+12204,120434010,2,1
+12204,122414010,3,1
+12204,120421020,3,1
+12204,122411010,3,1
+12204,122441020,1,1
+12204,100414010,3,1
+12204,120414010,3,1
+12204,121411020,3,1
+12204,119431010,3,1
+12204,120421010,3,1
+12204,121441020,1,1
+12204,119431020,2,1
+12204,120441020,1,1
+12204,121421020,3,1
+12204,122441010,1,1
+12204,121431020,3,1
+12206,119611010,3,1
+12206,122613010,3,1
+12206,118611010,3,1
+12206,120621010,3,1
+12206,122634010,3,1
+12206,121641030,1,1
+12206,122641020,1,1
+12206,119624010,2,1
+12206,118631020,2,1
+12206,119631020,2,1
+12206,121631010,3,1
+12206,122621010,3,1
+12206,121611030,3,1
+12206,121641020,1,1
+12206,122621020,3,1
+12206,122641010,1,1
+12206,122611030,3,1
+12302,123211030,3,1
+12302,122214010,3,1
+12302,123224010,3,1
+12302,120231020,2,1
+12302,121211030,3,1
+12302,121221020,3,1
+12302,122231010,3,1
+12302,120021020,2,1
+12302,123211010,3,1
+12302,123241010,2,1
+12302,122244010,1,1
+12302,122221030,3,1
+12302,123221010,3,1
+12302,123244010,1,1
+12302,121231010,2,1
+12302,123231010,3,1
+12307,121731020,2,1
+12307,122031020,2,1
+12307,122721020,3,1
+12307,122731020,3,1
+12307,123711020,3,1
+12307,123741010,2,1
+12307,123723010,3,1
+12307,119011010,3,1
+12307,120741030,1,1
+12307,121711010,3,1
+12307,122741020,1,1
+12307,123721010,3,1
+12307,123713010,2,1
+12307,120721020,3,1
+12307,120711030,3,1
+12307,123731010,3,1
+12308,123824010,3,1
+12308,120014010,3,1
+12308,120821020,3,1
+12308,122821020,2,1
+12308,122821030,2,1
+12308,123841010,2,1
+12308,122834010,3,1
+12308,123814010,3,1
+12308,119811020,2,1
+12308,119824010,2,1
+12308,122841010,1,1
+12308,120811020,3,1
+12308,120831010,2,1
+12308,120841010,1,1
+12308,121811020,3,1
+12308,120831020,2,1
+12308,119831020,3,1
+12403,124341020,2,1
+12403,122341030,1,1
+12403,122341020,1,1
+12403,124331010,3,1
+12403,123331010,3,1
+12403,123331020,3,1
+12403,122331020,1,1
+12403,124321020,3,1
+12403,123321010,3,1
+12403,122321010,3,1
+12403,122321020,2,1
+12403,124314010,3,1
+12403,124314020,3,1
+12403,122311010,3,1
+12403,122311020,3,1
+12403,122314010,3,1
+12406,124641010,1,1
+12406,124641020,2,1
+12406,123641020,1,1
+12406,124631010,3,1
+12406,124634010,3,1
+12406,123631010,3,1
+12406,121631020,1,1
+12406,124621010,3,1
+12406,124621020,3,1
+12406,124624010,3,1
+12406,123621010,3,1
+12406,124611010,3,1
+12406,124611020,3,1
+12406,124614010,3,1
+12406,123614010,2,1
+12406,122613010,3,1
+12408,124841010,2,1
+12408,123841030,1,1
+12408,121841010,1,1
+12408,124831010,3,1
+12408,124834010,2,1
+12408,123831010,3,1
+12408,122831010,2,1
+12408,124821010,3,1
+12408,124824010,3,1
+12408,121821010,3,1
+12408,121824010,3,1
+12408,124811010,3,1
+12408,124814010,3,1
+12408,123811020,2,1
+12408,122811020,3,1
+12408,121814010,3,1
+12501,125141020,2,1
+12501,123141020,1,1
+12501,122141020,1,1
+12501,125131010,3,1
+12501,125134010,3,1
+12501,122131020,2,1
+12501,122134010,2,1
+12501,125121020,3,1
+12501,125121010,3,1
+12501,124121020,3,1
+12501,122121030,3,1
+12501,125111010,3,1
+12501,125114010,2,1
+12501,122111010,3,1
+12501,121111010,3,1
+12501,100111010,3,1
+12504,125441020,2,1
+12504,124441010,1,1
+12504,122441010,1,1
+12504,125431010,3,1
+12504,125434010,3,1
+12504,123434010,1,1
+12504,122031020,3,1
+12504,125421010,3,1
+12504,125421030,3,1
+12504,124024010,3,1
+12504,123421030,3,1
+12504,125011020,3,1
+12504,125411010,3,1
+12504,124411030,3,1
+12504,123414010,2,1
+12504,100414010,3,1
+12506,125641020,2,1
+12506,122641020,1,1
+12506,121641030,1,1
+12506,125631010,3,1
+12506,125633010,3,1
+12506,122634010,3,1
+12506,121631010,1,1
+12506,125621020,3,1
+12506,123621030,3,1
+12506,122621010,3,1
+12506,122621020,3,1
+12506,125611010,3,1
+12506,125614010,2,1
+12506,123611010,3,1
+12506,122613010,3,1
+12506,121611030,3,1
+12603,126341010,2,1
+12603,126341020,1,1
+12603,123341020,1,1
+12603,126331010,3,1
+12603,126334010,3,1
+12603,124334010,2,1
+12603,123334010,2,1
+12603,126321010,3,1
+12603,126321020,3,1
+12603,124024010,3,1
+12603,122324010,3,1
+12603,126311010,3,1
+12603,126311020,3,1
+12603,126314010,3,1
+12603,125314020,2,1
+12603,124311020,3,1
+12604,126441010,2,1
+12604,126441020,1,1
+12604,125441020,1,1
+12604,126431020,3,1
+12604,126431010,3,1
+12604,125431020,2,1
+12604,122031010,2,1
+12604,126421010,3,1
+12604,126424010,3,1
+12604,125421010,3,1
+12604,125421020,3,1
+12604,126014010,2,1
+12604,126411010,3,1
+12604,126411020,3,1
+12604,125011020,3,1
+12604,124411030,3,1
+12607,126741010,2,1
+12607,126741020,1,1
+12607,125741030,1,1
+12607,126731010,3,1
+12607,126732010,3,1
+12607,124731020,1,1
+12607,123031020,3,1
+12607,126721010,3,1
+12607,126721020,3,1
+12607,125723010,3,1
+12607,124721020,2,1
+12607,122721010,3,1
+12607,126711010,3,1
+12607,126711020,3,1
+12607,123711030,3,1
+12607,122714010,3,1
+12702,127241010,2,1
+12702,126241020,1,1
+12702,123241020,1,1
+12702,127231010,3,1
+12702,126231020,2,1
+12702,123231020,2,1
+12702,123234010,3,1
+12702,127221010,3,1
+12702,125221010,2,1
+12702,124221020,3,1
+12702,123221030,3,1
+12702,127211010,3,1
+12702,127211020,3,1
+12702,124214010,3,1
+12702,123211020,3,1
+12702,123211010,3,1
+12705,127541010,2,1
+12705,126541010,1,1
+12705,125541020,1,1
+12705,127531010,3,1
+12705,127033010,3,1
+12705,123031020,1,1
+12705,123531010,3,1
+12705,127521010,3,1
+12705,126521020,3,1
+12705,125521010,3,1
+12705,125524010,3,1
+12705,123524010,2,1
+12705,127511010,3,1
+12705,127511030,3,1
+12705,123511030,3,1
+12705,123514010,3,1
+12708,127841010,2,1
+12708,126041020,1,1
+12708,125844010,1,1
+12708,127033010,3,1
+12708,127831010,3,1
+12708,126031020,1,1
+12708,124031020,1,1
+12708,124031010,1,1
+12708,123831020,1,1
+12708,127821010,3,1
+12708,127821030,1,1
+12708,127821020,1,1
+12708,126824010,1,1
+12708,125021010,1,1
+12708,125821020,1,1
+12708,125821010,1,1
+12708,124024010,1,1
+12708,124821020,1,1
+12708,124824010,1,1
+12708,123821030,1,1
+12708,127014010,1,1
+12708,127811010,3,1
+12708,127811020,1,1
+12708,127814010,1,1
+12708,126011010,1,1
+12708,126011020,1,1
+12708,126014010,1,1
+12708,125814010,1,1
+12708,124014010,1,1
+12708,124814010,1,1
+12708,123814010,1,1
+12801,128141010,1,1
+12801,128141020,1,1
+12801,127141030,1,1
+12801,126141020,1,1
+12801,128131010,3,1
+12801,127134010,3,1
+12801,125131010,2,1
+12801,125131020,2,1
+12801,128121010,3,1
+12801,126121030,3,1
+12801,125121010,3,1
+12801,124121020,3,1
+12801,128111010,3,1
+12801,128111020,3,1
+12801,128114010,3,1
+12801,126111030,3,1
+12801,125111010,2,1
+12802,128241010,1,1
+12802,128241020,1,1
+12802,126241020,1,1
+12802,126241030,1,1
+12802,128231010,3,1
+12802,127231020,3,1
+12802,127231030,3,1
+12802,125231020,1,1
+12802,128221020,3,1
+12802,128224010,3,1
+12802,126221030,3,1
+12802,125221030,3,1
+12802,124221020,3,1
+12802,128211020,3,1
+12802,127211020,3,1
+12802,127214010,2,1
+12802,125011010,3,1
+12806,128641010,1,1
+12806,127641010,1,1
+12806,126641010,1,1
+12806,125641020,1,1
+12806,127631010,3,1
+12806,127634010,3,1
+12806,126631020,3,1
+12806,125633010,1,1
+12806,128624010,2,1
+12806,127621010,3,1
+12806,127621020,3,1
+12806,127621030,3,1
+12806,126621010,3,1
+12806,128611020,3,1
+12806,128614010,3,1
+12806,127611010,3,1
+12806,127614010,3,1
+12807,128741010,1,1
+12807,128741020,1,1
+12807,127741010,1,1
+12807,127741030,1,1
+12807,128032010,1,1
+12807,128731010,3,1
+12807,128733010,3,1
+12807,127731010,3,1
+12807,128721010,3,1
+12807,128721020,3,1
+12807,127721010,3,1
+12807,124024010,2,1
+12807,128711010,3,1
+12807,128713010,3,1
+12807,127713010,3,1
+12807,126711010,3,1
+12807,126713010,3,1
+12901,129141010,2,1
+12901,128141010,1,1
+12901,127141030,1,1
+12901,126141020,2,1
+12901,125141010,1,1
+12901,129131010,3,1
+12901,127134010,2,1
+12901,125131020,2,1
+12901,129124010,3,1
+12901,128121010,3,1
+12901,126121030,3,1
+12901,125121010,3,1
+12901,128111010,3,1
+12901,128111020,3,1
+12901,128114010,3,1
+12901,126111030,3,1
+12901,125111010,2,1
+12902,129241010,2,1
+12902,128241010,1,1
+12902,128241020,1,1
+12902,128241030,2,1
+12902,126241030,1,1
+12902,129234010,3,1
+12902,128231010,2,1
+12902,127231030,2,1
+12902,129221010,3,1
+12902,128224010,3,1
+12902,125221020,3,1
+12902,125221010,3,1
+12902,129214010,3,1
+12902,128211020,3,1
+12902,127211020,3,1
+12902,125211020,2,1
+12902,125011010,3,1
+12903,129341010,2,1
+12903,129341020,1,1
+12903,128341030,2,1
+12903,126341030,2,1
+12903,129031010,1,1
+12903,127334010,3,1
+12903,125331010,3,1
+12903,129321010,3,1
+12903,129322010,3,1
+12903,128321020,3,1
+12903,127321020,3,1
+12903,125321010,2,1
+12903,129311020,3,1
+12903,129311010,3,1
+12903,129314020,3,1
+12903,127311020,3,1
+12904,129441020,2,1
+12904,129441010,1,1
+12904,127441020,2,1
+12904,126441020,2,1
+12904,129431010,2,1
+12904,129434010,3,1
+12904,125431020,2,1
+12904,129421010,3,1
+12904,129421020,3,1
+12904,128424010,3,1
+12904,127421020,3,1
+12904,129411010,2,1
+12904,129411020,3,1
+12904,127414010,3,1
+12904,125411010,3,1
+12904,100414010,3,1
+12905,129541010,2,1
+12905,128041010,1,1
+12905,128041020,1,1
+12905,126541010,2,1
+12905,125541020,1,1
+12905,129531010,2,1
+12905,129534010,2,1
+12905,126531010,3,1
+12905,129521010,3,1
+12905,127524010,3,1
+12905,126521020,3,1
+12905,125524010,3,1
+12905,129511020,3,1
+12905,128514010,3,1
+12905,127511030,3,1
+12905,126511030,3,1
+12905,126514010,2,1
+12906,129641020,2,1
+12906,128641010,1,1
+12906,128641020,2,1
+12906,125641030,2,1
+12906,129631010,3,1
+12906,128032010,3,1
+12906,128634010,1,1
+12906,129624010,3,1
+12906,128621010,3,1
+12906,127621020,3,1
+12906,126621020,3,1
+12906,129611010,3,1
+12906,129614010,2,1
+12906,128611020,3,1
+12906,127614010,3,1
+12906,126611020,3,1
+12907,129741020,2,1
+12907,129741010,1,1
+12907,128741010,2,1
+12907,128741020,2,1
+12907,129731010,3,1
+12907,128731010,2,1
+12907,128733010,2,1
+12907,129721010,3,1
+12907,128721010,3,1
+12907,128721020,3,1
+12907,127721010,3,1
+12907,129711010,3,1
+12907,129713020,3,1
+12907,128711010,3,1
+12907,126711020,3,1
+12907,126713010,2,1
+12908,129841020,2,1
+12908,128841030,2,1
+12908,126841010,2,1
+12908,125844010,1,1
+12908,129831010,3,1
+12908,129834010,2,1
+12908,125834010,2,1
+12908,129024010,3,1
+12908,129821010,3,1
+12908,129821020,3,1
+12908,125821020,3,1
+12908,129811020,3,1
+12908,129811030,3,1
+12908,127814010,2,1
+12908,126811010,3,1
+12908,125811030,3,1
+13001,130141020,1,1
+13001,129141010,1,1
+13001,128141010,1,1
+13001,127141030,1,1
+13001,130131010,3,1
+13001,129131010,2,1
+13001,129131030,3,1
+13001,127131010,2,1
+13001,130124010,3,1
+13001,129024010,2,1
+13001,128121010,3,1
+13001,126121030,3,1
+13001,130111020,2,1
+13001,130114010,3,1
+13001,128111010,3,1
+13001,128111020,3,1
+13001,128114010,3,1
+13001,127111010,1,1
+13002,130241010,1,1
+13002,130241020,1,1
+13002,129241010,1,1
+13002,128041020,1,1
+13002,130234010,3,1
+13002,129234010,2,1
+13002,128231010,3,1
+13002,127231030,2,1
+13002,130221010,3,1
+13002,130221020,3,1
+13002,130224010,3,1
+13002,129024010,2,1
+13002,128224010,3,1
+13002,129214010,3,1
+13002,128211020,3,1
+13002,127211010,3,1
+13002,127211020,3,1
+13003,130341020,1,1
+13003,129341010,1,1
+13003,129341020,1,1
+13003,129341030,1,1
+13003,130331010,3,1
+13003,130334010,3,1
+13003,129031010,1,1
+13003,127334010,3,1
+13003,130321010,3,1
+13003,129321010,3,1
+13003,129322010,3,1
+13003,128321020,3,1
+13003,127321020,2,1
+13003,130311020,3,1
+13003,129311020,3,1
+13003,129314020,3,1
+13003,127311020,3,1
+13006,130641020,1,1
+13006,127641010,2,1
+13006,126641010,1,1
+13006,130634010,3,1
+13006,127631010,3,1
+13006,126631020,3,1
+13006,126631030,1,1
+13006,130621020,3,1
+13006,130624010,3,1
+13006,128624010,2,1
+13006,127621020,3,1
+13006,127621030,3,1
+13006,130611010,3,1
+13006,128611020,3,1
+13006,127611010,3,1
+13006,127614010,3,1
+13103,131341020,2,1
+13103,128341010,1,1
+13103,128341020,1,1
+13103,131331020,3,1
+13103,129334010,1,1
+13103,128331010,3,1
+13103,128334010,3,1
+13103,131321010,3,1
+13103,131321020,3,1
+13103,131324010,2,1
+13103,128321010,3,1
+13103,131311010,3,1
+13103,131311020,3,1
+13103,130314020,3,1
+13103,128314010,3,1
+13103,127314010,3,1
+13105,131541020,2,1
+13105,128041020,1,1
+13105,127541010,1,1
+13105,131534010,3,1
+13105,129531020,2,1
+13105,127033010,2,1
+13105,127531010,3,1
+13105,131021010,3,1
+13105,131521010,3,1
+13105,131521020,3,1
+13105,128521010,2,1
+13105,131011010,3,1
+13105,131011020,3,1
+13105,131012010,3,1
+13105,128514010,3,1
+13105,128511030,3,1
+13108,131841020,2,1
+13108,130841010,1,1
+13108,129841020,1,1
+13108,131834010,3,1
+13108,129831010,2,1
+13108,129831020,2,1
+13108,129834010,3,1
+13108,131821020,3,1
+13108,131821030,3,1
+13108,130821020,2,1
+13108,130824010,3,1
+13108,129821010,3,1
+13108,129821020,3,1
+13108,131813010,3,1
+13108,129811020,3,1
+13108,129811030,3,1
+13204,132441010,1,1
+13204,132441020,1,1
+13204,131441030,1,1
+13204,130441010,1,1
+13204,132031010,2,1
+13204,132034010,2,1
+13204,132431010,3,1
+13204,132434010,3,1
+13204,132421010,3,1
+13204,132421020,3,1
+13204,132424010,3,1
+13204,128424010,3,1
+13204,132411010,3,1
+13204,132411030,3,1
+13204,132414010,3,1
+13204,131411020,2,1
+13204,100414010,3,1
+13205,132041020,1,1
+13205,132541020,1,1
+13205,131541030,1,1
+13205,130041010,1,1
+13205,132531010,3,1
+13205,132534010,3,1
+13205,130531020,1,1
+13205,129534010,3,1
+13205,132023010,3,1
+13205,132521010,3,1
+13205,132524010,3,1
+13205,129024010,3,1
+13205,132011010,3,1
+13205,132511030,2,1
+13205,132511020,3,1
+13205,132514010,3,1
+13205,128514010,3,1
+13206,132041010,1,1
+13206,132641010,1,1
+13206,130641030,1,1
+13206,130641020,1,1
+13206,132634010,3,1
+13206,131631020,3,1
+13206,130634010,3,1
+13206,129031020,1,1
+13206,132621020,3,1
+13206,130624010,3,1
+13206,130621020,2,1
+13206,128624010,3,1
+13206,132611020,3,1
+13206,132611030,3,1
+13206,131611030,3,1
+13206,130611010,3,1
+13206,128611020,3,1
\ No newline at end of file
diff --git a/SVSim.Bootstrap/Data/build-deck/build_deck_series_master.csv b/SVSim.Bootstrap/Data/build-deck/build_deck_series_master.csv
new file mode 100644
index 0000000..c5456bb
--- /dev/null
+++ b/SVSim.Bootstrap/Data/build-deck/build_deck_series_master.csv
@@ -0,0 +1,23 @@
+series_id,series_name,introduction,title_path,drumroll_path
+13200,BDSSN_トライアル_32,BDSI_トライアル_32,build_deck_13200_logo_02,build_deck_13200_logo_01
+13100,BDSSN_トライアル_31,BDSI_トライアル_31,build_deck_13100_logo_02,build_deck_13100_logo_01
+13000,BDSSN_トライアル_30,BDSI_トライアル_30,build_deck_13000_logo_02,build_deck_13000_logo_01
+12900,BDSSN_トライアル_29,BDSI_トライアル_29,build_deck_12900_logo_02,build_deck_12900_logo_01
+12800,BDSSN_トライアル_28,BDSI_トライアル_28,build_deck_12800_logo_02,build_deck_12800_logo_01
+12700,BDSSN_トライアル_27,BDSI_トライアル_27,build_deck_12700_logo_02,build_deck_12700_logo_01
+12600,BDSSN_トライアル_26,BDSI_トライアル_26,build_deck_12600_logo_02,build_deck_12600_logo_01
+12500,BDSSN_トライアル_25,BDSI_トライアル_25,build_deck_12500_logo_02,build_deck_12500_logo_01
+12400,BDSSN_トライアル_24,BDSI_トライアル_24,build_deck_12400_logo_02,build_deck_12400_logo_01
+12300,BDSSN_トライアル_23,BDSI_トライアル_23,build_deck_12300_logo_02,build_deck_12300_logo_01
+12200,BDSSN_トライアル_22,BDSI_トライアル_22,build_deck_12200_logo_02,build_deck_12200_logo_01
+12100,BDSSN_トライアル_21,BDSI_トライアル_21,build_deck_12100_logo_02,build_deck_12100_logo_01
+12000,BDSSN_トライアル_20,BDSI_トライアル_20,build_deck_12000_logo_02,build_deck_12000_logo_01
+11900,BDSSN_トライアル_19,BDSI_トライアル_19,build_deck_11900_logo_02,build_deck_11900_logo_01
+10100,BDSSN_テンポラリーデッキ,BDSI_テンポラリーデッキ,build_deck_10100_logo_02,build_deck_10100_logo_01
+107,BDSSN_構築済みデッキ7弾,BDSI_構築済みデッキ7弾,build_deck_107_logo_02,build_deck_107_logo_01
+106,BDSSN_構築済みデッキ6弾,BDSI_構築済みデッキ6弾,build_deck_106_logo_02,build_deck_106_logo_01
+105,BDSSN_構築済みデッキ5弾,BDSI_構築済みデッキ5弾,build_deck_105_logo_02,build_deck_105_logo_01
+104,BDSSN_構築済みデッキ4弾,BDSI_構築済みデッキ4弾,build_deck_104_logo_02,build_deck_104_logo_01
+103,BDSSN_構築済みデッキ3弾,BDSI_構築済みデッキ3弾,build_deck_103_logo_02,build_deck_103_logo_01
+102,BDSSN_構築済みデッキ2弾,BDSI_構築済みデッキ2弾,build_deck_102_logo_02,build_deck_102_logo_01
+101,BDSSN_構築済みデッキ1弾,BDSI_構築済みデッキ1弾,build_deck_101_logo_02,build_deck_101_logo_01
diff --git a/SVSim.Bootstrap/Data/prod-captures/build_deck-info-2026-05-26.json b/SVSim.Bootstrap/Data/prod-captures/build_deck-info-2026-05-26.json
new file mode 100644
index 0000000..9b294c6
--- /dev/null
+++ b/SVSim.Bootstrap/Data/prod-captures/build_deck-info-2026-05-26.json
@@ -0,0 +1 @@
+{"data_headers":{"sid":"8f8942b22bd297c23e28a416a5dca7a21779591266","short_udid":411054851,"viewer_id":906243102,"servertime":1779591266,"result_code":1},"data":{"15":{"series_id":"107","order_id":"16","is_new":false,"products":[{"product_id":"701","product_name":"BDPN_構築済みデッキ7弾_エルフ","leader_id":"1","deck_code":"pd0107","featured_card_id":"115141020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1151410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"702","product_name":"BDPN_構築済みデッキ7弾_ロイヤル","leader_id":"2","deck_code":"pd0207","featured_card_id":"115241020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1152410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"703","product_name":"BDPN_構築済みデッキ7弾_ウィッチ","leader_id":"3","deck_code":"pd0307","featured_card_id":"115341020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1153410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"704","product_name":"BDPN_構築済みデッキ7弾_ドラゴン","leader_id":"4","deck_code":"pd0407","featured_card_id":"115441020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1154410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"705","product_name":"BDPN_構築済みデッキ7弾_ネクロマンサー","leader_id":"5","deck_code":"pd0507","featured_card_id":"115541020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1155410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"706","product_name":"BDPN_構築済みデッキ7弾_ヴァンパイア","leader_id":"6","deck_code":"pd0607","featured_card_id":"115641020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1156410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"707","product_name":"BDPN_構築済みデッキ7弾_ビショップ","leader_id":"7","deck_code":"pd0707","featured_card_id":"115741020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1157410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"708","product_name":"BDPN_構築済みデッキ7弾_ネメシス","leader_id":"8","deck_code":"pd0807","featured_card_id":"115841020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1158410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"}],"series_rewards":{"1":{"reward_list":[{"reward_type":"5","reward_detail_id":"712014010","reward_number":"3","message_id":51004}],"is_get":false},"2":{"reward_list":[{"reward_type":"5","reward_detail_id":"712031010","reward_number":"3","message_id":51004}],"is_get":false},"3":{"reward_list":[{"reward_type":"6","reward_detail_id":"712014010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"712014015","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"712014016","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"712014017","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"712014018","reward_number":"1","message_id":51004}],"is_get":false},"4":{"reward_list":[{"reward_type":"6","reward_detail_id":"712031010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"712031010","reward_number":"1","message_id":51004}],"is_get":false},"5":{"reward_list":[{"reward_type":"5","reward_detail_id":"712014011","reward_number":"3","message_id":51004}],"is_get":false},"6":{"reward_list":[{"reward_type":"5","reward_detail_id":"712031011","reward_number":"3","message_id":51004}],"is_get":false},"7":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false},"8":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false}}},"16":{"series_id":"106","order_id":"17","is_new":false,"products":[{"product_id":"601","product_name":"BDPN_構築済みデッキ6弾_エルフ","leader_id":"1","deck_code":"pd0106","featured_card_id":"111141010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1111410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"602","product_name":"BDPN_構築済みデッキ6弾_ロイヤル","leader_id":"2","deck_code":"pd0206","featured_card_id":"112241010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1122410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"603","product_name":"BDPN_構築済みデッキ6弾_ウィッチ","leader_id":"3","deck_code":"pd0306","featured_card_id":"112341020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1123410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"604","product_name":"BDPN_構築済みデッキ6弾_ドラゴン","leader_id":"4","deck_code":"pd0406","featured_card_id":"112441010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1124410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"605","product_name":"BDPN_構築済みデッキ6弾_ネクロマンサー","leader_id":"5","deck_code":"pd0506","featured_card_id":"112541020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1125410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"606","product_name":"BDPN_構築済みデッキ6弾_ヴァンパイア","leader_id":"6","deck_code":"pd0606","featured_card_id":"112641020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1126410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"607","product_name":"BDPN_構築済みデッキ6弾_ビショップ","leader_id":"7","deck_code":"pd0706","featured_card_id":"111741030","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1117410300","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"608","product_name":"BDPN_構築済みデッキ6弾_ネメシス","leader_id":"8","deck_code":"pd0806","featured_card_id":"112841030","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1128410300","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"}],"series_rewards":{"1":{"reward_list":[{"reward_type":"5","reward_detail_id":"710034010","reward_number":"3","message_id":51004}],"is_get":false},"2":{"reward_list":[{"reward_type":"5","reward_detail_id":"710031010","reward_number":"3","message_id":51004}],"is_get":false},"3":{"reward_list":[{"reward_type":"6","reward_detail_id":"710034010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"710034010","reward_number":"1","message_id":51004}],"is_get":false},"4":{"reward_list":[{"reward_type":"6","reward_detail_id":"710031010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"710031010","reward_number":"1","message_id":51004}],"is_get":false},"5":{"reward_list":[{"reward_type":"5","reward_detail_id":"710034011","reward_number":"3","message_id":51004}],"is_get":false},"6":{"reward_list":[{"reward_type":"5","reward_detail_id":"710031011","reward_number":"3","message_id":51004}],"is_get":false},"7":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false},"8":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false}}},"17":{"series_id":"105","order_id":"18","is_new":false,"products":[{"product_id":"501","product_name":"BDPN_構築済みデッキ5弾_エルフ","leader_id":"1","deck_code":"pd0105","featured_card_id":"111141020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1111410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"502","product_name":"BDPN_構築済みデッキ5弾_ロイヤル","leader_id":"2","deck_code":"pd0205","featured_card_id":"111241020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1112410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"503","product_name":"BDPN_構築済みデッキ5弾_ウィッチ","leader_id":"3","deck_code":"pd0305","featured_card_id":"111341020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1113410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"504","product_name":"BDPN_構築済みデッキ5弾_ドラゴン","leader_id":"4","deck_code":"pd0405","featured_card_id":"111441020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1114410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"505","product_name":"BDPN_構築済みデッキ5弾_ネクロマンサー","leader_id":"5","deck_code":"pd0505","featured_card_id":"111541020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1115410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"506","product_name":"BDPN_構築済みデッキ5弾_ヴァンパイア","leader_id":"6","deck_code":"pd0605","featured_card_id":"111641020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1116410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"507","product_name":"BDPN_構築済みデッキ5弾_ビショップ","leader_id":"7","deck_code":"pd0705","featured_card_id":"111741020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1117410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"},{"product_id":"508","product_name":"BDPN_構築済みデッキ5弾_ネメシス","leader_id":"8","deck_code":"pd0805","featured_card_id":"111841020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1118410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"1200"}],"series_rewards":{"1":{"reward_list":[{"reward_type":"5","reward_detail_id":"707034010","reward_number":"3","message_id":51004}],"is_get":false},"2":{"reward_list":[{"reward_type":"5","reward_detail_id":"707031010","reward_number":"3","message_id":51004}],"is_get":false},"3":{"reward_list":[{"reward_type":"6","reward_detail_id":"707034010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"707034010","reward_number":"1","message_id":51004}],"is_get":false},"4":{"reward_list":[{"reward_type":"6","reward_detail_id":"707031010","reward_number":"1","message_id":51004},{"reward_type":"7","reward_detail_id":"707031010","reward_number":"1","message_id":51004}],"is_get":false},"5":{"reward_list":[{"reward_type":"5","reward_detail_id":"707034011","reward_number":"3","message_id":51004}],"is_get":false},"6":{"reward_list":[{"reward_type":"5","reward_detail_id":"707031011","reward_number":"3","message_id":51004}],"is_get":false},"7":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false},"8":{"reward_list":[{"reward_type":"4","reward_detail_id":"1000","reward_number":"1","message_id":51004}],"is_get":false}}},"18":{"series_id":"104","order_id":"19","is_new":false,"products":[{"product_id":"401","product_name":"BDPN_構築済みデッキ4弾_エルフ","leader_id":"1","deck_code":"pd0104","featured_card_id":"705114010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705114010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705114010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705114010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"402","product_name":"BDPN_構築済みデッキ4弾_ロイヤル","leader_id":"2","deck_code":"pd0204","featured_card_id":"705214010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705214010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705214010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705214010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"403","product_name":"BDPN_構築済みデッキ4弾_ウィッチ","leader_id":"3","deck_code":"pd0304","featured_card_id":"705314010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705314010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705314010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705314010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"404","product_name":"BDPN_構築済みデッキ4弾_ドラゴン","leader_id":"4","deck_code":"pd0404","featured_card_id":"705414010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705414010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705414010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705414010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"405","product_name":"BDPN_構築済みデッキ4弾_ネクロマンサー","leader_id":"5","deck_code":"pd0504","featured_card_id":"705514010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705514010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705514010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705514010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"406","product_name":"BDPN_構築済みデッキ4弾_ヴァンパイア","leader_id":"6","deck_code":"pd0604","featured_card_id":"705614020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705614020","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705614020","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705614020","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"407","product_name":"BDPN_構築済みデッキ4弾_ビショップ","leader_id":"7","deck_code":"pd0704","featured_card_id":"705714010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705714010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705714010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705714010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"408","product_name":"BDPN_構築済みデッキ4弾_ネメシス","leader_id":"8","deck_code":"pd0804","featured_card_id":"705814010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"705814010","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"705814010","reward_number":"1","message_id":"51004"},"3":{"reward_type":"5","reward_detail_id":"705814010","reward_number":"3","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"}],"series_rewards":[]},"19":{"series_id":"103","order_id":"20","is_new":false,"products":[{"product_id":"301","product_name":"BDPN_構築済みデッキ3弾_エルフ","leader_id":"1","deck_code":"pd0103","featured_card_id":"106141010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1061410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"302","product_name":"BDPN_構築済みデッキ3弾_ロイヤル","leader_id":"2","deck_code":"pd0203","featured_card_id":"106241010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1062410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"303","product_name":"BDPN_構築済みデッキ3弾_ウィッチ","leader_id":"3","deck_code":"pd0303","featured_card_id":"105341010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1053410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"304","product_name":"BDPN_構築済みデッキ3弾_ドラゴン","leader_id":"4","deck_code":"pd0403","featured_card_id":"106441010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1064410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"305","product_name":"BDPN_構築済みデッキ3弾_ネクロマンサー","leader_id":"5","deck_code":"pd0503","featured_card_id":"106541020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1065410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"306","product_name":"BDPN_構築済みデッキ3弾_ヴァンパイア","leader_id":"6","deck_code":"pd0603","featured_card_id":"105641020","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1056410200","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"},{"product_id":"307","product_name":"BDPN_構築済みデッキ3弾_ビショップ","leader_id":"7","deck_code":"pd0703","featured_card_id":"106741010","purchase_num_max":1,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"6","reward_detail_id":"1067410100","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"800"}],"series_rewards":[]},"20":{"series_id":"102","order_id":"21","is_new":false,"products":[{"product_id":"201","product_name":"BDPN_構築済みデッキ2弾_エルフ","leader_id":"1","deck_code":"pd0102","featured_card_id":"703141011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703141011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703141011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"202","product_name":"BDPN_構築済みデッキ2弾_ロイヤル","leader_id":"2","deck_code":"pd0202","featured_card_id":"703241011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703241011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703241011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"203","product_name":"BDPN_構築済みデッキ2弾_ウィッチ","leader_id":"3","deck_code":"pd0302","featured_card_id":"703341011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703341011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703341011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"204","product_name":"BDPN_構築済みデッキ2弾_ドラゴン","leader_id":"4","deck_code":"pd0402","featured_card_id":"703441011","purchase_num_max":3,"purchase_num_current":3,"is_first_price":false,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703441011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703441011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"750"},{"product_id":"205","product_name":"BDPN_構築済みデッキ2弾_ネクロマンサー","leader_id":"5","deck_code":"pd0502","featured_card_id":"703541011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703541011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703541011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"206","product_name":"BDPN_構築済みデッキ2弾_ヴァンパイア","leader_id":"6","deck_code":"pd0602","featured_card_id":"703641011","purchase_num_max":3,"purchase_num_current":3,"is_first_price":false,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703641011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703641011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"750"},{"product_id":"207","product_name":"BDPN_構築済みデッキ2弾_ビショップ","leader_id":"7","deck_code":"pd0702","featured_card_id":"703741011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"703741011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"703741011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"}],"series_rewards":[]},"21":{"series_id":"101","order_id":"22","is_new":false,"products":[{"product_id":"1","product_name":"BDPN_構築済みデッキ1弾_エルフ","leader_id":"1","deck_code":"pd0101","featured_card_id":"701141011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701141011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701141011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"2","product_name":"BDPN_構築済みデッキ1弾_ロイヤル","leader_id":"2","deck_code":"pd0201","featured_card_id":"701241011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701241011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701241011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"3","product_name":"BDPN_構築済みデッキ1弾_ウィッチ","leader_id":"3","deck_code":"pd0301","featured_card_id":"701341011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701341011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701341011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"4","product_name":"BDPN_構築済みデッキ1弾_ドラゴン","leader_id":"4","deck_code":"pd0401","featured_card_id":"701441011","purchase_num_max":3,"purchase_num_current":3,"is_first_price":false,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701441011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701441011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"750"},{"product_id":"5","product_name":"BDPN_構築済みデッキ1弾_ネクロマンサー","leader_id":"5","deck_code":"pd0501","featured_card_id":"701541011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701541011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701541011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"6","product_name":"BDPN_構築済みデッキ1弾_ヴァンパイア","leader_id":"6","deck_code":"pd0601","featured_card_id":"701641011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701641011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701641011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"},{"product_id":"7","product_name":"BDPN_構築済みデッキ1弾_ビショップ","leader_id":"7","deck_code":"pd0701","featured_card_id":"701741011","purchase_num_max":3,"purchase_num_current":0,"is_first_price":true,"rewards":{"1":{"reward_type":"7","reward_detail_id":"701741011","reward_number":"1","message_id":"51004"},"2":{"reward_type":"6","reward_detail_id":"701741011","reward_number":"1","message_id":"51004"}},"sales_period_info":[],"price_crystal":"500"}],"series_rewards":[]}}}
diff --git a/SVSim.Bootstrap/Data/prod-captures/deck-info-2026-05-23.json b/SVSim.Bootstrap/Data/prod-captures/deck-info-2026-05-23.json
index 07e23cb..d22023c 100644
--- a/SVSim.Bootstrap/Data/prod-captures/deck-info-2026-05-23.json
+++ b/SVSim.Bootstrap/Data/prod-captures/deck-info-2026-05-23.json
@@ -457,7 +457,7 @@
"4": {
"class_id": 4,
"is_random_leader_skin": 0,
- "leader_skin_id": 104
+ "leader_skin_id": 4
},
"5": {
"class_id": 5,
@@ -467,7 +467,7 @@
"6": {
"class_id": 6,
"is_random_leader_skin": 0,
- "leader_skin_id": 106
+ "leader_skin_id": 6
},
"7": {
"class_id": 7,
diff --git a/SVSim.Bootstrap/Importers/BuildDeckImporter.cs b/SVSim.Bootstrap/Importers/BuildDeckImporter.cs
new file mode 100644
index 0000000..9e11a89
--- /dev/null
+++ b/SVSim.Bootstrap/Importers/BuildDeckImporter.cs
@@ -0,0 +1,366 @@
+using System.Text.Json;
+using Microsoft.EntityFrameworkCore;
+using SVSim.Database;
+using SVSim.Database.Models;
+using static SVSim.Bootstrap.Importers.ImporterBase;
+
+namespace SVSim.Bootstrap.Importers;
+
+///
+/// Loads the prebuilt-deck catalog from a mix of client-master CSVs and one prod-capture JSON.
+/// Three methods run in dependency order (see Bootstrap/Program.cs):
+/// 1. ImportSeriesAsync — build_deck_series_master.csv → 22 series rows (all IsEnabled=false initially)
+/// 2. ImportCatalogAsync — prod-captures/build_deck-info-*.json → enriches 7 series + 53 products (Task 15)
+/// 3. ImportPackageAsync — build_deck_package_master.csv → card lists for all 112 products,
+/// creates disabled stubs for products not seeded by the catalog importer
+/// Idempotent — re-runnable on the same files.
+///
+public class BuildDeckImporter
+{
+ private const string BuildDeckSubdir = "build-deck";
+
+ public async Task ImportSeriesAsync(SVSimDbContext db, string dataDir)
+ {
+ string csvPath = Path.Combine(dataDir, BuildDeckSubdir, "build_deck_series_master.csv");
+ if (!File.Exists(csvPath))
+ {
+ Console.Error.WriteLine($"[BuildDeckImporter] series CSV missing: {csvPath}");
+ return 0;
+ }
+
+ var rows = ReadCsv(csvPath).Skip(1).ToList(); // skip header
+ int created = 0, updated = 0;
+
+ var existing = await db.BuildDeckSeries.ToDictionaryAsync(s => s.Id);
+ foreach (var cols in rows)
+ {
+ if (cols.Length < 5) continue;
+ if (!int.TryParse(cols[0], out int id)) continue;
+
+ if (existing.TryGetValue(id, out var row))
+ {
+ // Update CSV-derived fields; do not flip IsEnabled or OrderIndex (catalog importer owns those)
+ bool changed = false;
+ if (row.NameKey != cols[1]) { row.NameKey = cols[1]; changed = true; }
+ if (row.IntroKey != cols[2]) { row.IntroKey = cols[2]; changed = true; }
+ if (row.TitlePath != cols[3]) { row.TitlePath = cols[3]; changed = true; }
+ if (row.DrumrollPath != cols[4]) { row.DrumrollPath = cols[4]; changed = true; }
+ if (changed) updated++;
+ }
+ else
+ {
+ db.BuildDeckSeries.Add(new BuildDeckSeriesEntry
+ {
+ Id = id,
+ NameKey = cols[1],
+ IntroKey = cols[2],
+ TitlePath = cols[3],
+ DrumrollPath = cols[4],
+ OrderIndex = 0,
+ IsNew = false,
+ IsEnabled = false,
+ });
+ created++;
+ }
+ }
+ await db.SaveChangesAsync();
+ Console.WriteLine($"[BuildDeckImporter] Series: created={created}, updated={updated}");
+ return created + updated;
+ }
+
+ public async Task ImportPackageAsync(SVSimDbContext db, string dataDir)
+ {
+ string csvPath = Path.Combine(dataDir, BuildDeckSubdir, "build_deck_package_master.csv");
+ if (!File.Exists(csvPath))
+ {
+ Console.Error.WriteLine($"[BuildDeckImporter] package CSV missing: {csvPath}");
+ return 0;
+ }
+
+ var rows = ReadCsv(csvPath).Skip(1).ToList(); // header: product_id,card_id,number,is_spot
+ var byProduct = rows
+ .Where(c => c.Length >= 4)
+ .GroupBy(c => int.Parse(c[0]))
+ .ToDictionary(g => g.Key, g => g.Select(c => new BuildDeckProductCardEntry
+ {
+ CardId = long.Parse(c[1]),
+ Number = int.Parse(c[2]),
+ IsSpot = int.Parse(c[3]) != 0,
+ }).ToList());
+
+ // Load existing products (we may have stubs from a prior run or rows created by catalog importer)
+ var existing = await db.BuildDeckProducts.Include(p => p.Cards).ToDictionaryAsync(p => p.Id);
+ int created = 0, updated = 0;
+
+ foreach (var (productId, cardEntries) in byProduct)
+ {
+ if (existing.TryGetValue(productId, out var product))
+ {
+ // Replace card list wholesale — CSV is authoritative.
+ product.Cards.Clear();
+ foreach (var c in cardEntries) product.Cards.Add(c);
+ updated++;
+ }
+ else
+ {
+ int? seriesId = InferSeriesId(productId);
+ if (seriesId is null)
+ {
+ Console.Error.WriteLine($"[BuildDeckImporter] product {productId} has no inferable series; skipping");
+ continue;
+ }
+ db.BuildDeckProducts.Add(new BuildDeckProductEntry
+ {
+ Id = productId,
+ SeriesId = seriesId.Value,
+ LeaderId = 0,
+ DeckCode = string.Empty,
+ ProductNameKey = string.Empty,
+ FeaturedCardId = 0,
+ PurchaseNumMax = 1,
+ IntroPriceCrystal = null,
+ RegularPriceCrystal = null,
+ IntroPriceRupy = null,
+ RegularPriceRupy = null,
+ IsEnabled = false,
+ Cards = cardEntries,
+ });
+ created++;
+ }
+ }
+ await db.SaveChangesAsync();
+ Console.WriteLine($"[BuildDeckImporter] Package: created={created}, updated={updated}");
+ return created + updated;
+ }
+
+ public async Task ImportCatalogAsync(SVSimDbContext db, string capturesDir)
+ {
+ var data = LoadCapture(capturesDir, "build_deck-info");
+ if (data is null) return 0;
+
+ int touchedSeries = 0, touchedProducts = 0;
+
+ // Load existing rows for fast lookup
+ var existingSeries = await db.BuildDeckSeries
+ .Include(s => s.SeriesRewards)
+ .ToDictionaryAsync(s => s.Id);
+ var existingProducts = await db.BuildDeckProducts
+ .Include(p => p.Rewards)
+ .ToDictionaryAsync(p => p.Id);
+
+ // The captured data root is an object keyed by order_id string ("15"…"21"); iterate values.
+ foreach (var seriesNode in data.Value.EnumerateObject())
+ {
+ var s = seriesNode.Value;
+ int seriesId = GetInt(s, "series_id");
+ int orderId = GetInt(s, "order_id");
+ bool isNew = GetBool(s, "is_new");
+
+ if (!existingSeries.TryGetValue(seriesId, out var seriesRow))
+ {
+ // Catalog runs before package importer in production, so series rows from the series
+ // CSV should already exist. If not (e.g. the capture has a series the CSV doesn't),
+ // create a bare row so the FK from products holds.
+ seriesRow = new BuildDeckSeriesEntry
+ {
+ Id = seriesId, NameKey = string.Empty, IntroKey = string.Empty,
+ TitlePath = string.Empty, DrumrollPath = string.Empty,
+ };
+ db.BuildDeckSeries.Add(seriesRow);
+ existingSeries[seriesId] = seriesRow;
+ }
+ seriesRow.OrderIndex = orderId;
+ seriesRow.IsNew = isNew;
+ seriesRow.IsEnabled = true;
+
+ // Series rewards: replace wholesale (capture is authoritative for enabled series)
+ seriesRow.SeriesRewards.Clear();
+ if (s.TryGetProperty("series_rewards", out var seriesRewards) &&
+ seriesRewards.ValueKind == JsonValueKind.Object)
+ {
+ foreach (var tier in seriesRewards.EnumerateObject())
+ {
+ if (!int.TryParse(tier.Name, out int tierIndex)) continue;
+ if (!tier.Value.TryGetProperty("reward_list", out var rewardList) ||
+ rewardList.ValueKind != JsonValueKind.Array) continue;
+
+ int itemIndex = 0;
+ foreach (var r in rewardList.EnumerateArray())
+ {
+ seriesRow.SeriesRewards.Add(new BuildDeckSeriesRewardEntry
+ {
+ TierIndex = tierIndex,
+ ItemIndex = itemIndex++,
+ RewardType = GetInt(r, "reward_type"),
+ RewardDetailId = GetLong(r, "reward_detail_id"),
+ RewardNumber = GetInt(r, "reward_number"),
+ MessageId = GetInt(r, "message_id"),
+ });
+ }
+ }
+ }
+ touchedSeries++;
+
+ // Products
+ if (!s.TryGetProperty("products", out var products) || products.ValueKind != JsonValueKind.Array)
+ continue;
+
+ // First pass: parse each captured product, track intro/regular tiers per product.
+ var capturedThisSeries = new List();
+ foreach (var p in products.EnumerateArray())
+ {
+ int productId = GetInt(p, "product_id");
+
+ if (!existingProducts.TryGetValue(productId, out var productRow))
+ {
+ productRow = new BuildDeckProductEntry { Id = productId, SeriesId = seriesId };
+ db.BuildDeckProducts.Add(productRow);
+ existingProducts[productId] = productRow;
+ }
+ productRow.SeriesId = seriesId;
+ productRow.LeaderId = GetInt(p, "leader_id");
+ productRow.DeckCode = GetString(p, "deck_code");
+ productRow.ProductNameKey = GetString(p, "product_name");
+ productRow.FeaturedCardId = GetLong(p, "featured_card_id");
+ productRow.PurchaseNumMax = GetInt(p, "purchase_num_max");
+ productRow.IsEnabled = true;
+
+ bool isFirstPrice = GetBool(p, "is_first_price");
+
+ // Tier-aware price ingestion: each captured row has ONE price tier (intro OR regular).
+ int? priceCrystal = p.TryGetProperty("price_crystal", out var pc) && pc.ValueKind != JsonValueKind.Null
+ ? (int?)GetInt(p, "price_crystal") : null;
+ int? priceRupy = p.TryGetProperty("price_rupy", out var pr) && pr.ValueKind != JsonValueKind.Null
+ ? (int?)GetInt(p, "price_rupy") : null;
+
+ if (priceCrystal is not null)
+ {
+ if (isFirstPrice) productRow.IntroPriceCrystal = priceCrystal;
+ else productRow.RegularPriceCrystal = priceCrystal;
+ }
+ if (priceRupy is not null)
+ {
+ if (isFirstPrice) productRow.IntroPriceRupy = priceRupy;
+ else productRow.RegularPriceRupy = priceRupy;
+ }
+
+ // Product rewards: replace wholesale
+ productRow.Rewards.Clear();
+ if (p.TryGetProperty("rewards", out var rewards) && rewards.ValueKind == JsonValueKind.Object)
+ {
+ foreach (var r in rewards.EnumerateObject())
+ {
+ if (!int.TryParse(r.Name, out int idx)) continue;
+ productRow.Rewards.Add(new BuildDeckProductRewardEntry
+ {
+ RewardIndex = idx,
+ RewardType = GetInt(r.Value, "reward_type"),
+ RewardDetailId = GetLong(r.Value, "reward_detail_id"),
+ RewardNumber = GetInt(r.Value, "reward_number"),
+ MessageId = GetInt(r.Value, "message_id"),
+ });
+ }
+ }
+
+ capturedThisSeries.Add(productRow);
+ touchedProducts++;
+ }
+
+ // Second pass: backfill missing tier per-series when sibling products share a unique value.
+ BackfillSeriesTier(capturedThisSeries);
+ }
+
+ await db.SaveChangesAsync();
+ Console.WriteLine($"[BuildDeckImporter] Catalog: series={touchedSeries}, products={touchedProducts}");
+ return touchedSeries + touchedProducts;
+ }
+
+ private static void BackfillSeriesTier(IReadOnlyList productsInSeries)
+ {
+ // For each (Currency, Tier) pair, if all populated values across siblings are the same,
+ // propagate that value to products that are missing the corresponding tier.
+ BackfillIntroCrystal(productsInSeries);
+ BackfillRegularCrystal(productsInSeries);
+ BackfillIntroRupy(productsInSeries);
+ BackfillRegularRupy(productsInSeries);
+ }
+
+ private static void BackfillIntroCrystal(IReadOnlyList products)
+ {
+ var distinct = products.Where(p => p.IntroPriceCrystal.HasValue).Select(p => p.IntroPriceCrystal!.Value).Distinct().ToList();
+ if (distinct.Count != 1) return;
+ int value = distinct[0];
+ foreach (var p in products)
+ {
+ if (p.IntroPriceCrystal is null) p.IntroPriceCrystal = value;
+ }
+ }
+
+ private static void BackfillRegularCrystal(IReadOnlyList products)
+ {
+ var distinct = products.Where(p => p.RegularPriceCrystal.HasValue).Select(p => p.RegularPriceCrystal!.Value).Distinct().ToList();
+ if (distinct.Count != 1) return;
+ int value = distinct[0];
+ foreach (var p in products)
+ {
+ // For PurchaseNumMax == 1 products, never backfill the Regular tier — they have no second buy.
+ if (p.PurchaseNumMax <= 1) continue;
+ if (p.RegularPriceCrystal is null) p.RegularPriceCrystal = value;
+ }
+ }
+
+ private static void BackfillIntroRupy(IReadOnlyList products)
+ {
+ var distinct = products.Where(p => p.IntroPriceRupy.HasValue).Select(p => p.IntroPriceRupy!.Value).Distinct().ToList();
+ if (distinct.Count != 1) return;
+ int value = distinct[0];
+ foreach (var p in products)
+ {
+ if (p.IntroPriceRupy is null) p.IntroPriceRupy = value;
+ }
+ }
+
+ private static void BackfillRegularRupy(IReadOnlyList products)
+ {
+ var distinct = products.Where(p => p.RegularPriceRupy.HasValue).Select(p => p.RegularPriceRupy!.Value).Distinct().ToList();
+ if (distinct.Count != 1) return;
+ int value = distinct[0];
+ foreach (var p in products)
+ {
+ if (p.PurchaseNumMax <= 1) continue;
+ if (p.RegularPriceRupy is null) p.RegularPriceRupy = value;
+ }
+ }
+
+ ///
+ /// Maps a product_id to its series_id using the numeric pattern derived from the /info capture
+ /// and CSV inspection.
+ /// Sets 1–7: products 1–7, 201–299, 301–399, 401–499, 501–599, 601–699, 701–799 → series 101–107
+ /// Temporary Deck: products 10001–10099 → series 10100
+ /// Trial series: products NNxx where NN in [119,…,132] → series NN00 (divide-by-100 * 100)
+ ///
+ internal static int? InferSeriesId(int productId) => productId switch
+ {
+ >= 1 and <= 7 => 101,
+ >= 201 and <= 299 => 102,
+ >= 301 and <= 399 => 103,
+ >= 401 and <= 499 => 104,
+ >= 501 and <= 599 => 105,
+ >= 601 and <= 699 => 106,
+ >= 701 and <= 799 => 107,
+ >= 10001 and <= 10099 => 10100,
+ >= 11901 and <= 13299 => (productId / 100) * 100,
+ _ => null,
+ };
+
+ private static IEnumerable ReadCsv(string path)
+ {
+ foreach (var raw in File.ReadAllLines(path, System.Text.Encoding.UTF8))
+ {
+ // Strip UTF-8 BOM on the first line if present
+ var line = raw.TrimStart('');
+ if (string.IsNullOrWhiteSpace(line)) continue;
+ yield return line.Split(',');
+ }
+ }
+}
diff --git a/SVSim.Bootstrap/Program.cs b/SVSim.Bootstrap/Program.cs
index c210d83..e6f2487 100644
--- a/SVSim.Bootstrap/Program.cs
+++ b/SVSim.Bootstrap/Program.cs
@@ -76,6 +76,14 @@ public static class Program
if (!opts.SkipGlobals)
{
await new GlobalsImporter().ImportAllAsync(context, opts.CapturesDir);
+
+ // BuildDeck pipeline: series CSV → catalog JSON → package CSV. Catalog must run after
+ // series CSV (FK on products → series) and before package CSV (so the catalog-side
+ // enriched rows take precedence over stub creation).
+ var buildDeck = new BuildDeckImporter();
+ await buildDeck.ImportSeriesAsync(context, opts.ReferenceDataDir);
+ await buildDeck.ImportCatalogAsync(context, opts.CapturesDir);
+ await buildDeck.ImportPackageAsync(context, opts.ReferenceDataDir);
}
else
{
diff --git a/SVSim.Bootstrap/SVSim.Bootstrap.csproj b/SVSim.Bootstrap/SVSim.Bootstrap.csproj
index 5573a3d..dc5bf95 100644
--- a/SVSim.Bootstrap/SVSim.Bootstrap.csproj
+++ b/SVSim.Bootstrap/SVSim.Bootstrap.csproj
@@ -16,6 +16,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/SVSim.Database/Migrations/20260526043148_AddBuildDeck.Designer.cs b/SVSim.Database/Migrations/20260526043148_AddBuildDeck.Designer.cs
new file mode 100644
index 0000000..e6dfa31
--- /dev/null
+++ b/SVSim.Database/Migrations/20260526043148_AddBuildDeck.Designer.cs
@@ -0,0 +1,2834 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using SVSim.Database;
+
+#nullable disable
+
+namespace SVSim.Database.Migrations
+{
+ [DbContext(typeof(SVSimDbContext))]
+ [Migration("20260526043148_AddBuildDeck")]
+ partial class AddBuildDeck
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.8")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.HasSequence("ShortUdidSequence")
+ .StartsAt(400000000L);
+
+ modelBuilder.Entity("DegreeEntryViewer", b =>
+ {
+ b.Property("DegreesId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("DegreesId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("DegreeEntryViewer");
+ });
+
+ modelBuilder.Entity("EmblemEntryViewer", b =>
+ {
+ b.Property("EmblemsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("EmblemsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("EmblemEntryViewer");
+ });
+
+ modelBuilder.Entity("LeaderSkinEntryViewer", b =>
+ {
+ b.Property("LeaderSkinsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("LeaderSkinsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("LeaderSkinEntryViewer");
+ });
+
+ modelBuilder.Entity("MyPageBackgroundEntryViewer", b =>
+ {
+ b.Property("MyPageBackgroundsId")
+ .HasColumnType("integer");
+
+ b.Property("ViewersId")
+ .HasColumnType("bigint");
+
+ b.HasKey("MyPageBackgroundsId", "ViewersId");
+
+ b.HasIndex("ViewersId");
+
+ b.ToTable("MyPageBackgroundEntryViewer");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.SpecialBattleSetting", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("BanishEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ClassDestroyEffectOverride")
+ .HasColumnType("integer");
+
+ b.Property("EnemyAttachSkill")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("EnemyStartLife")
+ .HasColumnType("integer");
+
+ b.Property("EnemyStartPp")
+ .HasColumnType("integer");
+
+ b.Property("IdOverrideInBattleLog")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Note")
+ .HasColumnType("text");
+
+ b.Property("PlayerAttachSkill")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PlayerFirstTurn")
+ .HasColumnType("integer");
+
+ b.Property("PlayerStartLife")
+ .HasColumnType("integer");
+
+ b.Property("PlayerStartPp")
+ .HasColumnType("integer");
+
+ b.Property("ResultSkip")
+ .HasColumnType("integer");
+
+ b.Property("SpecialTokenDrawEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TokenDrawEffectOverride")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("VsEffectOverride")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("SpecialBattleSettings");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StoryChapter", b =>
+ {
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("Battle3dFieldId")
+ .HasColumnType("integer");
+
+ b.Property("BattleExists")
+ .HasColumnType("boolean");
+
+ b.Property("BgFileName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("BgmId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ChapterClearTextId")
+ .HasColumnType("text");
+
+ b.Property("ChapterEffectPath")
+ .HasColumnType("text");
+
+ b.Property("ChapterId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("CharaId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyAiId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyCharaId")
+ .HasColumnType("integer");
+
+ b.Property("EnemyClass")
+ .HasColumnType("integer");
+
+ b.Property("IsCameraMovable")
+ .HasColumnType("integer");
+
+ b.Property("IsMaintenanceChapter")
+ .HasColumnType("boolean");
+
+ b.Property("IsPlayAnotherEndAppearanceAnimation")
+ .HasColumnType("boolean");
+
+ b.Property("IsReleasedAnotherEnd")
+ .HasColumnType("boolean");
+
+ b.Property("IsSkipEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("NextChapterId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ReleasePoint")
+ .HasColumnType("integer");
+
+ b.Property("RequiredChapterId")
+ .HasColumnType("text");
+
+ b.Property("SectionId")
+ .HasColumnType("integer");
+
+ b.Property("SelectionDisplayPosition")
+ .HasColumnType("text");
+
+ b.Property("SelectionTextId")
+ .HasColumnType("text");
+
+ b.Property("ShowCoordinate")
+ .HasColumnType("integer");
+
+ b.Property("ShowSubtitles")
+ .HasColumnType("integer");
+
+ b.Property("SpecialBattleSettingId")
+ .HasColumnType("integer");
+
+ b.Property("UnlockText")
+ .HasColumnType("text");
+
+ b.Property("XCoordinate")
+ .HasColumnType("numeric");
+
+ b.Property("YCoordinate")
+ .HasColumnType("numeric");
+
+ b.HasKey("StoryId");
+
+ b.HasIndex("NextChapterId");
+
+ b.HasIndex("SpecialBattleSettingId");
+
+ b.HasIndex("SectionId", "CharaId", "ChapterId");
+
+ b.ToTable("StoryChapters");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StorySection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("AllStoryOrderId")
+ .HasColumnType("integer");
+
+ b.Property("BackGroundId")
+ .HasColumnType("integer");
+
+ b.Property("ChapterSelectType")
+ .HasColumnType("integer");
+
+ b.Property("ImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsLeaderSelect")
+ .HasColumnType("boolean");
+
+ b.Property("IsPlayAnotherEndAppearanceAnimation")
+ .HasColumnType("boolean");
+
+ b.Property("IsSpoiler")
+ .HasColumnType("integer");
+
+ b.Property("IsUnderMaintenance")
+ .HasColumnType("boolean");
+
+ b.Property("NameTextKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderId")
+ .HasColumnType("integer");
+
+ b.Property("SpoilerMessage")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("StoryApiType")
+ .HasColumnType("integer");
+
+ b.Property("StoryTypeOverwrite")
+ .HasColumnType("integer");
+
+ b.Property("WorldId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("WorldId");
+
+ b.ToTable("StorySections");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.StoryWorld", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("PanelImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("RibbonText")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("TitleTextKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("StoryWorlds");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.ViewerStoryBranchUnlock", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("UnlockedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ViewerId", "StoryId");
+
+ b.ToTable("ViewerStoryBranchUnlocks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Entities.Story.ViewerStoryProgress", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("StoryId")
+ .HasColumnType("integer");
+
+ b.Property("FinishedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsFinish")
+ .HasColumnType("boolean");
+
+ b.Property("IsSkipped")
+ .HasColumnType("boolean");
+
+ b.Property("SkippedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ViewerId", "StoryId");
+
+ b.ToTable("ViewerStoryProgress");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ArenaSeasonConfig", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Cost")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Enable")
+ .HasColumnType("integer");
+
+ b.Property("FormatInfo")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("IsJoin")
+ .HasColumnType("boolean");
+
+ b.Property("Mode")
+ .HasColumnType("integer");
+
+ b.Property("RupyCost")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("TicketCost")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("ArenaSeasons");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.AvatarAbilityEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Ability")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("AbilityCost")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("AbilityDesc")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("BattleStartFirstPlayerTurnBp")
+ .HasColumnType("integer");
+
+ b.Property("BattleStartMaxLife")
+ .HasColumnType("integer");
+
+ b.Property("BattleStartSecondPlayerTurnBp")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("integer");
+
+ b.Property("PassiveAbility")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PassiveAbilityDesc")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("AvatarAbilities");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BannerEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("ChangeTime")
+ .HasColumnType("integer");
+
+ b.Property("Click")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ImageName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ImagePaths")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("RemainingTime")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Banners");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlePassLevelEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Level")
+ .HasColumnType("integer");
+
+ b.Property("RewardData")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.HasKey("Id");
+
+ b.ToTable("BattlePassLevels");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BattlefieldEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsOpen")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Battlefields");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BuildDeckProductEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DeckCode")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("FeaturedCardId")
+ .HasColumnType("bigint");
+
+ b.Property("IntroPriceCrystal")
+ .HasColumnType("integer");
+
+ b.Property("IntroPriceRupy")
+ .HasColumnType("integer");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("LeaderId")
+ .HasColumnType("integer");
+
+ b.Property("ProductNameKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("PurchaseNumMax")
+ .HasColumnType("integer");
+
+ b.Property("RegularPriceCrystal")
+ .HasColumnType("integer");
+
+ b.Property("RegularPriceRupy")
+ .HasColumnType("integer");
+
+ b.Property("SeriesId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SeriesId");
+
+ b.ToTable("BuildDeckProducts");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.BuildDeckSeriesEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DrumrollPath")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IntroKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsEnabled")
+ .HasColumnType("boolean");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean");
+
+ b.Property("NameKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("OrderIndex")
+ .HasColumnType("integer");
+
+ b.Property("TitlePath")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("BuildDeckSeries");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.CardCosmeticReward", b =>
+ {
+ b.Property("CardId")
+ .HasColumnType("bigint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.Property("CosmeticId")
+ .HasColumnType("bigint");
+
+ b.Property("Quantity")
+ .HasColumnType("integer");
+
+ b.HasKey("CardId", "Type", "CosmeticId");
+
+ b.HasIndex("CardId");
+
+ b.ToTable("CardCosmeticRewards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ClassEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Classes");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ClassExpEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("NecessaryExp")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("ClassExpCurve");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ColosseumConfig", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("CardPoolName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ColosseumId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ColosseumName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DeckFormat")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("EndTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsAllCardEnabled")
+ .HasColumnType("integer");
+
+ b.Property("IsColosseumPeriod")
+ .HasColumnType("boolean");
+
+ b.Property("IsDisplayTips")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsNormalTwoPick")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsRoundPeriod")
+ .HasColumnType("boolean");
+
+ b.Property("IsSpecialMode")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("NowRound")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("SalesPeriodInfo")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("StartTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("TipsId")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Colosseums");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.DailyLoginBonusEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("BonusData")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("BonusId")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("DailyLoginBonuses");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.DefaultDeckEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("CardIdArray")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DeckName")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DeckNo")
+ .HasColumnType("integer");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("integer");
+
+ b.Property("SleeveId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.ToTable("DefaultDecks");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.DefaultLeaderSkinSettingEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsRandomLeaderSkin")
+ .HasColumnType("integer");
+
+ b.Property("LeaderSkinId")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("DefaultLeaderSkinSettings");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.DegreeEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("Degrees");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.EmblemEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("Emblems");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.FeatureMaintenanceEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("FeatureKey")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("FeatureMaintenances");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.GameConfigSection", b =>
+ {
+ b.Property("SectionName")
+ .HasColumnType("text");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ValueJson")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.HasKey("SectionName");
+
+ b.ToTable("GameConfigs");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.ItemEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("Items");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.LeaderSkinEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("ClassId")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EmoteId")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClassId");
+
+ b.ToTable("LeaderSkins");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.LoadingExclusionCardEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("CardId")
+ .HasColumnType("bigint");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("LoadingExclusionCards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.MaintenanceCardEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("bigint");
+
+ b.Property("CardId")
+ .HasColumnType("bigint");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("MaintenanceCards");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.MasterPointRankingPeriodEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("BeginTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EndTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("NecessaryScore")
+ .HasColumnType("bigint");
+
+ b.Property("PeriodNum")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("MasterPointRankingPeriods");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.MyPageBackgroundEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DateUpdated")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("MyPageBackgrounds");
+ });
+
+ modelBuilder.Entity("SVSim.Database.Models.MyRotationAbilityEntry", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("AbilityId")
+ .HasColumnType("integer");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("jsonb");
+
+ b.Property("DateCreated")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property