diff --git a/test/artifact.json b/test/artifact.json
new file mode 100644
index 0000000..eb814ac
--- /dev/null
+++ b/test/artifact.json
@@ -0,0 +1 @@
+{"id":"noblesse_oblige","name":"Noblesse Oblige","setPiece":[2,4],"sets":{"goblet":"Royal Silver Urn","plume":"Royal Plume","circlet":"Royal Masque","flower":"Royal Flora","sands":"Royal Pocket Watch"},"bonuses":["Elemental Burst DMG +20%","Using an Elemental Burst increases all party members' ATK by 20% for 12s. This effect cannot stack."],"rarity":[4,5],"domain":"clear_pool_and_mountain_cavern"}
\ No newline at end of file
diff --git a/test/build.json b/test/build.json
new file mode 100644
index 0000000..fd35962
--- /dev/null
+++ b/test/build.json
@@ -0,0 +1 @@
+{"roles":[{"recommended":true,"weapons":[{"id":"amos_bow"},{"id":"aqua_simulacra"},{"id":"polar_star"},{"id":"skyward_harp"},{"id":"thundering_pulse"},{"id":"hamayumi"},{"id":"prototype_crescent"},{"id":"blackcliff_warbow"}],"artifacts":[["shimenawas_reminiscence"],["wanderers_troupe"],["blizzard_strayer","+18%_atk_set","wanderers_troupe"]],"mainStats":{"sands":["EM","ATK%"],"goblet":["Cryo DMG"],"circlet":["Crit Rate","DMG"]},"subStats":["Crit Rate / DMG","Elemental Mastery","ATK%","Flat ATK"],"talent":["Normal Attack","Skill","Burst"],"tip":"In some teams and situations, using Ganyu's Elemental Burst can be detrimental to overall damage due to stealing Pyro aura, thus reducing the amount of CAs melting.","note":"Ganyu's Level 2 Charged Shot applies two instances Cryo as they do not share the same ICD, which allows you to trigger Melt reaction twice for both damage instances. Charged Attack will be the majority of her damage output while neglecting her Skill/Burst damage contribution for most scenarios.\n\nRegarding Weapon Choices:\nAmos' Bow: Amos is an excellent weapon for Ganyu since her Level 2 Charge Shot Bloom extends arrow flight duration and you can get 3 stacks of Amos' passive even on point blank range.\nHamayumi: This weapon doesn't synergize well with Shimenawa's Reminiscence (4) due to its passive.\nPrototype Crescent: At higher refinement levels with good uptime on its passive, it can potentially be on par with Skyward Harp. However, do bear in mind that not all enemies have weak spots that you can headshot, which does affect its performance significantly. \n\nRegarding Talent Priority:\nGanyu's Elemental Burst is low priority on a Melt Build since most of the times, you don't cast her burst at all so that it doesn't steal your Melt reaction.\n\n","name":"MELT DPS"},{"recommended":true,"weapons":[{"id":"polar_star"},{"id":"aqua_simulacra"},{"id":"thundering_pulse"},{"id":"skyward_harp"},{"id":"amos_bow"},{"id":"prototype_crescent"},{"id":"blackcliff_warbow"},{"id":"hamayumi"}],"artifacts":[["blizzard_strayer"],["blizzard_strayer","+18%_atk_set"]],"mainStats":{"sands":["ATK%"],"goblet":["Cryo DMG"],"circlet":["Crit DMG"]},"subStats":["Crit Rate / DMG","ATK%","Energy Recharge","Flat ATK"],"talent":["Burst","Normal Attack","Skill"],"tip":"Try to not overcap on Crit Rate (within the range of 25%-45% Crit Rate) since Ganyu's A1 passive only affects her Charged Shot and subsequent Blooms.","note":"Freeze Ganyu gives a lot of i-frames since you would be spamming Elemental Burst from all of your party members off cooldown. Ganyu's Elemental Burst can deal a ton of damage based on how grouped the enemies are, due to the quadratic scaling on her Elemental Burst.\n\nRegarding Weapon Choices: \nPolar Star: This weapon is much harder to optimize with, due to having a very high Crit Rate stat resulting in your Crit Rate going well above 100%. However, if optimised properly (i.e. very little Crit Rate substats), it pulls quite far ahead of all the other options.\nAqua Simulacra: Due to the sheer amount of Crit stats you can get from Blizzard Strayer (4), Ganyu's ascension passive and this weapon itself, you can consider running an ATK% circlet, especially if it has better substats than your Crit DMG one.\nAmos' Bow: In quickswap heavy rotations (Ganyu Mona Venti Diona) where you usually don't do a lot of Charged Shots, this weapon performs worse than the other 5 star options listed.\nPrototype Crescent: Similar to the Melt Build, this weapon at higher refinement levels and good passive uptime can pull ahead of some of the 5 star options such as Thundering Pulse and Skyward Harp. However, do bear in mind that not all enemies have weak spots that you can headshot, which does affect its performance significantly. \n\nRegarding Artifact Sets:\nBlizzard Strayer (4): This set is the go to set for a Frozen team comp due to the huge stats it provides.\n","name":"FREEZE DPS"},{"recommended":false,"weapons":[{"id":"thundering_pulse"},{"id":"skyward_harp"},{"id":"polar_star"},{"id":"amos_bow"},{"id":"alley_hunter"},{"id":"the_stringless"},{"id":"prototype_crescent"},{"id":"blackcliff_warbow"},{"id":"the_viridescent_hunt"},{"id":"elegy_for_the_end"}],"artifacts":[["blizzard_strayer"],["noblesse_oblige","blizzard_strayer"],["emblem_of_severed_fate"],["noblesse_oblige","blizzard_strayer","+18%_atk_set","emblem_of_severed_fate"],["noblesse_oblige"]],"mainStats":{"sands":["ATK%","Energy Recharge"],"goblet":["Cryo DMG"],"circlet":["Crit Rate","DMG"]},"subStats":["Energy Recharge (until needed)","Crit Rate / DMG","ATK%","Elemental Mastery (on a non Freeze comp)","Flat ATK"],"talent":["Burst","Skill","Normal Attack"],"tip":"When using her Elemental Burst, place her Elemental Skill in the AoE to taunt and keep enemies inside the zone for constant damage.\n\nMake sure to hit enemies with her skill's initial damage and her explosion damage as they both regen energy for her ult.","note":"An Off-field DPS Ganyu shines brightly on a Freeze comp as she has 100% Elemental Burst uptime and her Elemental Burst buffs party members' Cryo Damage. \n\nRegarding Weapon Choices:\nPrototype Crescent: This weapon might pull ahead of some of the other options if you activate the buff before casting Elemental Burst.\nElegy for the End: Offers party-wide Elemental Mastery and ATK buff which is quite nice on reaction heavy team comps.\n\nRegarding Artifact Sets:\nBlizzard Strayer (4): This set offers a huge amount of stats, use this set only if your Ganyu is used on a Freeze team.\nNoblesse Oblige (4): This set provides Ganyu with more utility so that she can buff your whole party's ATK by 20%.","name":"OFF-FIELD DPS"}]}
\ No newline at end of file
diff --git a/test/character.json b/test/character.json
new file mode 100644
index 0000000..8f48dab
--- /dev/null
+++ b/test/character.json
@@ -0,0 +1 @@
+{"id":"albedo","name":"Albedo","rarity":5,"weapon":{"id":"sword","name":"Sword"},"stats":{"hp":13226,"atk":251,"def":876},"ascension":[{"items":[{"item":{"id":"prithiva_topaz_sliver","name":"Prithiva Topaz Sliver","rarity":1},"amount":1},{"item":{"id":"cecilia","name":"Cecilia"},"amount":3},{"item":{"id":"divining_scroll","name":"Divining Scroll"},"amount":3}],"mora":20000},{"items":[{"item":{"id":"prithiva_topaz_fragment","name":"Prithiva Topaz Fragment","rarity":2,"parent":"prithiva_topaz_sliver"},"amount":3},{"item":{"id":"basalt_pillar","name":"Basalt Pillar","rarity":5,"parent":"prithiva_topaz_sliver"},"amount":2},{"item":{"id":"cecilia","name":"Cecilia"},"amount":10},{"item":{"id":"divining_scroll","name":"Divining Scroll"},"amount":15}],"mora":40000},{"items":[{"item":{"id":"prithiva_topaz_fragment","name":"Prithiva Topaz Fragment","rarity":2,"parent":"prithiva_topaz_sliver"},"amount":6},{"item":{"id":"basalt_pillar","name":"Basalt Pillar","rarity":5,"parent":"prithiva_topaz_sliver"},"amount":4},{"item":{"id":"cecilia","name":"Cecilia"},"amount":20},{"item":{"id":"sealed_scroll","name":"Sealed Scroll"},"amount":12}],"mora":60000},{"items":[{"item":{"id":"prithiva_topaz_chunk","name":"Prithiva Topaz Chunk","rarity":3,"parent":"prithiva_topaz_sliver"},"amount":3},{"item":{"id":"basalt_pillar","name":"Basalt Pillar","rarity":5,"parent":"prithiva_topaz_sliver"},"amount":8},{"item":{"id":"cecilia","name":"Cecilia"},"amount":30},{"item":{"id":"sealed_scroll","name":"Sealed Scroll"},"amount":18}],"mora":80000},{"items":[{"item":{"id":"prithiva_topaz_chunk","name":"Prithiva Topaz Chunk","rarity":3,"parent":"prithiva_topaz_sliver"},"amount":6},{"item":{"id":"basalt_pillar","name":"Basalt Pillar","rarity":5,"parent":"prithiva_topaz_sliver"},"amount":12},{"item":{"id":"cecilia","name":"Cecilia"},"amount":45},{"item":{"id":"forbidden_curse_scroll","name":"Forbidden Curse Scroll"},"amount":12}],"mora":100000},{"items":[{"item":{"id":"prithiva_topaz_gemstone","name":"Prithiva Topaz Gemstone","rarity":4,"parent":"prithiva_topaz_sliver"},"amount":6},{"item":{"id":"basalt_pillar","name":"Basalt Pillar","rarity":5,"parent":"prithiva_topaz_sliver"},"amount":20},{"item":{"id":"cecilia","name":"Cecilia"},"amount":60},{"item":{"id":"forbidden_curse_scroll","name":"Forbidden Curse Scroll"},"amount":24}],"mora":120000}],"material":{"material":[{"id":"divining_scroll","name":"Divining Scroll"},{"id":"sealed_scroll","name":"Sealed Scroll"},{"id":"forbidden_curse_scroll","name":"Forbidden Curse Scroll"}],"book":[{"id":"teachings_of_ballad","name":"Teachings of Ballad","day":["wednesday","saturday"],"rarity":2},{"id":"guide_to_ballad","name":"Guide to Ballad","day":["wednesday","saturday"],"rarity":3,"parent":"teachings_of_ballad"},{"id":"philosophies_of_ballad","name":"Philosophies of Ballad","day":["wednesday","saturday"],"rarity":4,"parent":"teachings_of_ballad"}],"boss":{"id":"tusk_of_monoceros_caeli","name":"Tusk of Monoceros Caeli"}},"element":{"id":"geo","name":"Geo","simpleName":"Stone","color":16760576},"builds":[{"recommended":true,"weapons":[{"id":"cinnabar_spindle","refine":[5]},{"id":"harbinger_of_dawn"},{"id":"primordial_jade_cutter"},{"id":"mistsplitter_reforged"},{"id":"freedom-sworn"}],"artifacts":[["husk_of_opulent_dreams"],["husk_of_opulent_dreams","archaic_petra"],["noblesse_oblige","archaic_petra"],["tenacity_of_the_millelith"],["noblesse_oblige"]],"mainStats":{"sands":["DEF%"],"goblet":["Geo DMG"],"circlet":["Crit Rate","DMG","DEF%"]},"subStats":["Crit Rate / DMG","DEF%","ATK%","Energy Recharge","Flat DEF","Flat ATK"],"talent":["Skill","Burst"],"tip":"Albedo's Elemental Skill particle generation is completely RNG like Zhongli, but with better odds.","note":"Albedo is a character that can summon a Geo Construct from his Elemental Skill which deals damage on a 2 second interval whenever enemies in the field are damaged. His Elemental Burst provides 125 EM to the party, which is good on teams that rely on amplification reactions, such as Vaporize. It is worth noting that since his stat priority is focused on DEF (Elemental Skill scaling), you might want to skip casting Elemental Burst if your team doesn't benefit from the 125 EM buff. Another option is to build him with ATK-DEF Hybrid, which ends up with lower Skill damage but higher Burst damage.\n\nRegarding Weapon Choices:\nHarbinger of Dawn: Albedo's Elemental Skill scales with Defense, which is why the Base ATK from the weapon doesn't matter that much. Harbinger of Dawn offers a lot of Crit stats which is why it is one of the strongest weapons for him despite being a 3 star weapon. The downside of this weapon is that you'd need to keep Albedo's HP at 90% or higher to benefit from the passive, so it might be annoying to use against certain enemies which has a HP lowering debuff, even when off-field, such as Corrosion.\nMistsplitter Reforged: Realistically you are only able to get 2 stacks of this weapon's passive and this requires setup. Generally just use Harbinger of Dawn instead and give your Mistsplitter Reforged to another sword DPS character.\nFreedom-Sworn: Equipping this weapon will decrease Albedo's own damage significantly but he is one of the better Freedom-Sworn holders since he can trigger the passive quite easily to buff your other party members.\n\nRegarding Artifact Sets:\nHusk of Opulent Dreams (4): Due to Albedo's skill snapshotting upon cast, you need to either wait ~12 seconds before starting a domain/fight to reach max stacks or recast his skill to benefit from the DEF and Geo DMG bonus provided by the 4 piece set effect.\nTenacity of the Milelith (4): This set is used for the 4 piece set effect which has good uptime on Albedo. Worth noting that this set decreases your Elemental Skill damage by a lot if compared to the other offensive sets.\nNoblesse Oblige (4): If you don't have another character in your party that has this set, you can use this set on Albedo. You might want to get some Energy Recharge substats to maintain your Elemental Burst uptime for this. It is also worth noting that this set decreases your Elemental Skill damage by a lot if compared to the other offensive sets.\n\nRegarding Artifact Substats Priority:\nATK and Energy Recharge substats are only valuable on a Hybrid Albedo that casts his Elemental Burst.","name":"OFF-FIELD DPS"}]}
\ No newline at end of file
diff --git a/test/domain.json b/test/domain.json
new file mode 100644
index 0000000..3bfef38
--- /dev/null
+++ b/test/domain.json
@@ -0,0 +1 @@
+{"name":"Domain of Guyun","domains":[{"s":5100,"id":"domain_of_blessing_spring_i","name":"Domain of Blessing: Spring I","ar":1,"level":34,"reward":{"adventureExp":"100","mora":"1525","friendshipExp":"15"},"monsters":[{"id":"hydro_slime","name":"Hydro Slime","count":21},{"id":"large_hydro_slime","name":"Large Hydro Slime","count":6},{"id":"hydro_abyss_mage","name":"Hydro Abyss Mage","count":1}],"disorder":[""]},{"s":5101,"id":"domain_of_blessing_spring_ii","name":"Domain of Blessing: Spring II","ar":25,"level":47,"reward":{"adventureExp":"100","mora":"1700","friendshipExp":"15"},"monsters":[{"id":"pyro_slime","name":"Pyro Slime","count":16},{"id":"large_pyro_slime","name":"Large Pyro Slime","count":5},{"id":"pyro_abyss_mage","name":"Pyro Abyss Mage","count":1}],"disorder":[""]},{"s":5102,"id":"domain_of_blessing_spring_iii","name":"Domain of Blessing: Spring III","ar":30,"level":59,"reward":{"adventureExp":"100","mora":"1850","friendshipExp":"15"},"monsters":[{"id":"cryo_slime","name":"Cryo Slime","count":15},{"id":"large_cryo_slime","name":"Large Cryo Slime","count":4},{"id":"cryo_abyss_mage","name":"Cryo Abyss Mage","count":1}],"disorder":[""]},{"s":5103,"id":"domain_of_blessing_spring_iv","name":"Domain of Blessing: Spring IV","ar":35,"level":69,"reward":{"adventureExp":"100","mora":"2025","friendshipExp":"20"},"monsters":[{"id":"hydro_slime","name":"Hydro Slime","count":5},{"id":"large_hydro_slime","name":"Large Hydro Slime","count":6},{"id":"hilichurl","name":"Hilichurl","count":6},{"id":"hydro_samachurl","name":"Hydro Samachurl","count":2},{"id":"hydro_abyss_mage","name":"Hydro Abyss Mage","count":1}],"disorder":[""]},{"s":5104,"id":"domain_of_blessing_spring_v","name":"Domain of Blessing: Spring V","ar":40,"level":80,"reward":{"adventureExp":"100","mora":"2200","friendshipExp":"20"},"monsters":[{"id":"pyro_abyss_mage","name":"Pyro Abyss Mage","count":1},{"id":"ruin_guard","name":"Ruin Guard","count":2}],"disorder":["","",""]},{"s":5105,"id":"domain_of_blessing_spring_vi","name":"Domain of Blessing: Spring VI","ar":45,"level":90,"reward":{"adventureExp":"100","mora":"2525","friendshipExp":"20"},"monsters":[{"id":"ruin_hunter","name":"Ruin Hunter","count":1},{"id":"hilichurl","name":"Hilichurl","count":2},{"id":"cryo_abyss_mage","name":"Cryo Abyss Mage","count":2}],"disorder":["","",""]}],"artifacts":["lucky_dog","brave_heart","archaic_petra","retracing_bolide"]}
\ No newline at end of file
diff --git a/test/element.json b/test/element.json
new file mode 100644
index 0000000..9d81246
--- /dev/null
+++ b/test/element.json
@@ -0,0 +1 @@
+{"id":"cryo","name":"Cryo","simpleName":"Ice","color":14090234}
\ No newline at end of file
diff --git a/test/events.json b/test/events.json
new file mode 100644
index 0000000..cfb697b
--- /dev/null
+++ b/test/events.json
@@ -0,0 +1 @@
+[{"name":"A Muddy Bizzare Adventure","pos":"0% 50%","image":"a_muddy_bizzare_adventure.jpg","start":"2022-06-22 10:00:00","end":"2022-07-04 03:59:59","color":"#8882e2","zoom":"220%","url":"https://www.hoyolab.com/article/5513175","showOnHome":true},{"name":"Ley Line Overflow","pos":"0% 20%","image":"leyline_overflow.jpg","start":"2022-07-04 04:00:00","end":"2022-07-11 03:59:59","color":"#5baced","zoom":"200%","url":"https://www.hoyolab.com/article/5444663","showOnHome":true},{"name":"Mesmerizing Dream at Sea","pos":"20% 23%","image":"mesmerizing_dream_at_sea.jpg","start":"2022-07-22 10:00:00","end":"2022-07-31 23:59:59","color":"#8cd8f1","zoom":"300%","url":"https://www.hoyolab.com/article/6129641","showOnHome":true},{"name":"Reminiscent Regimen","pos":"0% 30%","image":"reminiscent_regimen.jpg","start":"2022-08-04 10:00:00","end":"2022-08-15 03:59:59","color":"#82cff9","zoom":"100%","url":"https://www.hoyolab.com/article/6197391","showOnHome":true},{"name":"Spices From the West","pos":"0% 40%","zoom":"200%","image":"spices_from_the_west.jpg","start":"2022-05-14 10:00:00","end":"2022-06-07 03:59:59","color":"#83bfb4","url":"https://www.hoyolab.com/article/4592260","showOnHome":true},{"name":"The Almighty Arataki Great and Glorious Drumalong Festival","pos":"0% 50%","image":"drumalong_festival.jpg","start":"2022-06-13 10:00:00","end":"2022-07-04 03:59:59","color":"#ffca92","zoom":"250%","url":"https://www.hoyolab.com/article/5350611","showOnHome":true},{"name":"Hidden Strife","pos":"0% 30%","image":"hidden_strife.jpg","start":"2022-07-27 10:00:00","end":"2022-08-15 03:59:59","color":"#ff7c84","zoom":"220%","url":"https://www.hoyolab.com/article/6171423","showOnHome":true},{"name":"Perilous Trail","pos":"0% 20%","zoom":"150%","image":"perilous_trail.jpg","start":"2022-05-31 06:00:00","end":"2022-06-20 03:59:59","color":"#c9bcff","url":"https://www.hoyolab.com/article/4998961","showOnHome":true,"timezoneDependent":true},{"name":"Core of the Apparatus","pos":"50% 50%","zoom":"150%","image":"core_of_the_apparatus.jpg","start":"2022-06-29 10:00:00","end":"2022-07-11 03:59:59","color":"#fdf9f4","url":"https://www.hoyolab.com/article/5444663","showOnHome":true},{"name":"Summertime Odyssey","pos":"40% 20%","zoom":"200%","image":"summertime_odyssey.jpg","start":"2022-07-15 10:00:00","end":"2022-08-24 06:00:00","color":"#7eebff","url":"https://www.hoyolab.com/article/5958494","showOnHome":true},{"name":"Discerner of Enigmas - Yelan Banner","pos":"20% 15%","zoom":"200%","image":"discerner_of_enigmas.jpg","start":"2022-05-31 06:00:00","end":"2022-06-21 17:59:59","color":"#7de6fd","url":"https://www.hoyolab.com/article/4998733","showOnHome":true,"timezoneDependent":true},{"name":"Leaves in the Wind - Kazuha Banner","pos":"30% 15%","zoom":"200%","image":"leaves_in_the_wind_2.jpg","start":"2022-07-13 06:00:00","end":"2022-08-02 17:59:59","color":"#7edec3","url":"https://www.hoyolab.com/article/5915985","showOnHome":true,"timezoneDependent":true},{"name":"Evermotion Mechanical Painting","pos":"0% 30%","image":"evermotion_mechanical_painting.jpg","start":"2022-08-12 10:00:00","end":"2022-08-22 03:59:59","color":"#ffc284","zoom":"100%","url":"https://www.ho9yolab.com/article/617391","showOnHome":true},{"name":"Invitation to Mundane Life - Xiao Banner","pos":"20% 15%","zoom":"200%","image":"invitation_to_mundane_life_3.jpg","start":"2022-05-31 06:00:00","end":"2022-06-21 17:59:59","color":"#25d7b8","url":"https://www.hoyolab.com/article/4998734","showOnHome":true,"timezoneDependent":true},{"name":"Oni's Royale - Itto Banner","pos":"20% 15%","zoom":"200%","image":"onis_royale_2.jpg","start":"2022-06-21 18:00:00","end":"2022-07-12 14:59:59","color":"#FFB455","url":"https://www.hoyolab.com/article/5444430","showOnHome":true},{"name":"Sparkling Steps - Klee Banner","pos":"35% 25%","zoom":"200%","image":"sparkling_steps_3.jpg","start":"2022-07-13 06:00:00","end":"2022-08-02 17:59:59","color":"#ff7763","url":"https://www.hoyolab.com/article/5915988","showOnHome":true,"timezoneDependent":true},{"name":"Tapestry of Golden Flames - Yoimiya Banner","pos":"30% 25%","zoom":"200%","image":"tapestry_of_golden_flames_2.jpg","start":"2022-08-02 18:00:00","end":"2022-08-23 14:59:59","color":"#fc8976","url":"https://www.hoyolab.com/article/6197311","showOnHome":true},{"name":"Epitome Invocation - Weapon Banner","pos":"30% 30%","zoom":"150%","image":"epitome_invocation_29.jpg","start":"2022-05-31 06:00:00","end":"2022-06-21 17:59:59","color":"#FFAA4B","url":"https://www.hoyolab.com/article/4998735","showOnHome":true,"timezoneDependent":true},{"name":"Epitome Invocation - Weapon Banner","pos":"30% 30%","zoom":"150%","image":"epitome_invocation_30.jpg","start":"2022-06-21 18:00:00","end":"2022-07-12 14:59:59","color":"#FFAA4B","url":"https://www.hoyolab.com/article/5444431","showOnHome":true},{"name":"Epitome Invocation - Weapon Banner","pos":"30% 30%","zoom":"150%","image":"epitome_invocation_31.jpg","start":"2022-07-13 06:00:00","end":"2022-08-02 17:59:59","color":"#FFAA4B","url":"https://www.hoyolab.com/article/5915986","showOnHome":true,"timezoneDependent":true},{"name":"Epitome Invocation - Weapon Banner","pos":"30% 30%","zoom":"150%","image":"epitome_invocation_32.jpg","start":"2022-08-02 18:00:00","end":"2022-08-23 14:59:59","color":"#FFAA4B","url":"https://www.hoyolab.com/article/6197314","showOnHome":true},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-05-16 04:00:00","end":"2022-06-01 04:00:00","color":"#4299E1","description":"After a character's Normal Attack hits an opponent, this opponent will be afflicted with a Mark of Ending. After 10s, this Mark of Ending will be removed, dealing True DMG to this opponent. When a character's Normal Attack hits an opponent with a Mark of Ending, the DMG dealt by the Mark of Ending's removal will be increased. This DMG can be increased 9 times."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-06-01 04:00:00","end":"2022-06-16 04:00:00","color":"#4299E1","description":"After the active character uses an Elemental Skill, >Normal Attack DMG is increased by 16% for 8s. Max 3 stacks. Stacks are counted independently."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-06-16 04:00:00","end":"2022-07-01 04:00:00","color":"#4299E1","description":"After a character's Elemental Skill hits an opponent, that opponent's Physical and All Elemental RES will be decreased by 12% for 8s. Max 3 stacks. Stacks are counted independently."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-07-01 04:00:00","end":"2022-07-16 04:00:00","color":"#4299E1","description":"After the active character uses an Elemental Skill, that character's next Normal Attack that hits an opponent will unleash a shockwave at that opponent's position, dealing DMG. This effect can occur once every 1.2s."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-07-16 04:00:00","end":"2022-08-01 04:00:00","color":"#4299E1","description":"When a character takes the field, they will gain 1 Fortitude stack every 2s. This will increase their ATK by 20%. Max 3 stacks. When characters with 3 Fortitude stacks hit opponents with Charged Attacks, a shockwave will be unleashed at the opponents' position, dealing True DMG. A shockwave can be unleashed in this manner once every 2s. When the character leaves the field, all their Fortitude stacks will be cleared."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-08-01 04:00:00","end":"2022-08-16 04:00:00","color":"#4299E1","description":"When a character triggers Swirl on an opponent, that opponent's DEF is decreased by 12% for 10s. Max 3 stacks. Each stack's duration is counted independently."},{"name":"Spiral Abyss","image":"spiral_abyss.jpg","pos":"50% 20%","start":"2022-08-16 04:00:00","end":"2022-09-01 04:00:00","color":"#4299E1","description":"After the active character's Normal, Charged, or Plunging Attacks hit opponents, that character's Normal, Charged, and Plunging Attack DMG is increased by 12% for 8s. This effect can be triggered once every 0.1s. Max 4 stacks. Each stack's duration is counted independently. This effect will be cleared if the character leaves the field."},{"name":"Paimon's Bargain - Barbara, Kaeya, and Royal","pos":"0% 50%","zoom":"150%","start":"2022-06-01 04:00:00","end":"2022-07-01 04:00:00","color":"#B6A1EA","image":"paimon_bargain.png","description":"Now selling: Barbara, Kaeya, and Royal Weapons."},{"name":"Paimon's Bargain - Fischl, Xiangling, and Blackcliff","pos":"0% 50%","zoom":"150%","start":"2022-07-01 04:00:00","end":"2022-08-01 04:00:00","color":"#B6A1EA","image":"paimon_bargain.png","description":"Now selling: Fischl, Xiangling, and Blackcliff Weapons."},{"name":"Paimon's Bargain - Beidou, Noelle, and Royal","pos":"0% 50%","zoom":"150%","start":"2022-08-01 04:00:00","end":"2022-09-01 04:00:00","color":"#B6A1EA","image":"paimon_bargain.png","description":"Now selling: Beidou, Noelle, and Royal Weapons."},{"name":"Battle Pass - Gorge Sunset","pos":"0% 12%","image":"gorge_sunset.jpg","start":"2022-05-31 06:00:00","end":"2022-07-11 03:59:59","color":"#8fc2ea","url":"https://www.hoyolab.com/article/4998961","timezoneDependent":true},{"name":"Battle Pass - Azure Main","pos":"0% 12%","image":"azure_main.jpg","start":"2022-07-13 06:00:00","end":"2022-08-22 03:59:59","color":"#8fc2ea","url":"https://www.hoyolab.com/article/5916190","timezoneDependent":true}]
\ No newline at end of file
diff --git a/test/item.json b/test/item.json
new file mode 100644
index 0000000..5614234
--- /dev/null
+++ b/test/item.json
@@ -0,0 +1 @@
+{"id":"jade_branch_of_a_distant_sea","name":"Jade Branch of a Distant Sea","day":["monday","thursday"],"rarity":3,"parent":"coral_branch_of_a_distant_sea"}
\ No newline at end of file
diff --git a/test/weapon.json b/test/weapon.json
new file mode 100644
index 0000000..bf6f5b9
--- /dev/null
+++ b/test/weapon.json
@@ -0,0 +1 @@
+{"name":"Lion's Roar","id":"lions_roar","rarity":4,"atk":42,"secondary":"ATK","type":{"id":"sword","name":"Sword"},"source":"wish","ascension":[{"items":[{"item":{"id":"luminous_sands_from_guyun","name":"Luminous Sands from Guyun","day":["monday","thursday"],"rarity":1},"amount":3},{"item":{"id":"hunters_sacrificial_knife","name":"Hunter's Sacrificial Knife"},"amount":3},{"item":{"id":"treasure_hoarder_insignia","name":"Treasure Hoarder Insignia"},"amount":2}],"mora":5000},{"items":[{"item":{"id":"lustrous_stone_from_guyun","name":"Lustrous Stone from Guyun","day":["monday","thursday"],"rarity":2,"parent":"luminous_sands_from_guyun"},"amount":3},{"item":{"id":"hunters_sacrificial_knife","name":"Hunter's Sacrificial Knife"},"amount":12},{"item":{"id":"treasure_hoarder_insignia","name":"Treasure Hoarder Insignia"},"amount":8}],"mora":15000},{"items":[{"item":{"id":"lustrous_stone_from_guyun","name":"Lustrous Stone from Guyun","day":["monday","thursday"],"rarity":2,"parent":"luminous_sands_from_guyun"},"amount":6},{"item":{"id":"agents_sacrificial_knife","name":"Agent's Sacrificial Knife"},"amount":6},{"item":{"id":"silver_raven_insignia","name":"Silver Raven Insignia"},"amount":6}],"mora":20000},{"items":[{"item":{"id":"relic_from_guyun","name":"Relic from Guyun","day":["monday","thursday"],"rarity":3,"parent":"luminous_sands_from_guyun"},"amount":3},{"item":{"id":"agents_sacrificial_knife","name":"Agent's Sacrificial Knife"},"amount":12},{"item":{"id":"silver_raven_insignia","name":"Silver Raven Insignia"},"amount":9}],"mora":30000},{"items":[{"item":{"id":"relic_from_guyun","name":"Relic from Guyun","day":["monday","thursday"],"rarity":3,"parent":"luminous_sands_from_guyun"},"amount":6},{"item":{"id":"inspectors_sacrificial_knife","name":"Inspector's Sacrificial Knife"},"amount":9},{"item":{"id":"golden_raven_insignia","name":"Golden Raven Insignia"},"amount":6}],"mora":35000},{"items":[{"item":{"id":"divine_body_from_guyun","name":"Divine Body from Guyun","day":["monday","thursday"],"rarity":4,"parent":"luminous_sands_from_guyun"},"amount":4},{"item":{"id":"inspectors_sacrificial_knife","name":"Inspector's Sacrificial Knife"},"amount":18},{"item":{"id":"golden_raven_insignia","name":"Golden Raven Insignia"},"amount":12}],"mora":45000}],"extras":{"id":"lions_roar","name":"Lion's Roar","type":"sword","rarity":4,"description":"A sharp blade with extravagant carvings that somehow does not compromise on durability and sharpness. It roars like a lion as it cuts through the air.","skill":{"name":"Bane of Fire and Thunder","description":"Increases DMG against opponents affected by Pyro or Electro by 20%/24%/28%/32%/36%."},"secondary":{"name":"atkPercent","stats":[null,0.09000000357627869,0.09000000357627869,0.09000000357627869,0.09000000357627869,0.10457999883413294,0.10457999883413294,0.10457999883413294,0.10457999883413294,0.10457999883413294,0.12267000805020345,0.12267000805020345,0.12267000805020345,0.12267000805020345,0.12267000805020345,0.14085001074671766,0.14085001074671766,0.14085001074671766,0.14085001074671766,0.14085001074671766,0.15903000271439538,0.15903000271439538,0.15903000271439538,0.15903000271439538,0.15903000271439538,0.15903000271439538,0.1772100054109096,0.1772100054109096,0.1772100054109096,0.1772100054109096,0.1772100054109096,0.1953900081074238,0.1953900081074238,0.1953900081074238,0.1953900081074238,0.1953900081074238,0.21357000007510152,0.21357000007510152,0.21357000007510152,0.21357000007510152,0.21357000007510152,0.2317500135004522,0.2317500135004522,0.2317500135004522,0.2317500135004522,0.2317500135004522,0.2317500135004522,0.24993000546812993,0.24993000546812993,0.24993000546812993,0.24993000546812993,0.24993000546812993,0.26811001889348063,0.26811001889348063,0.26811001889348063,0.26811001889348063,0.26811001889348063,0.26811001889348063,0.28629001086115835,0.28629001086115835,0.28629001086115835,0.28629001086115835,0.28629001086115835,0.3044700028288361,0.3044700028288361,0.3044700028288361,0.3044700028288361,0.3044700028288361,0.3044700028288361,0.32265001625418677,0.32265001625418677,0.32265001625418677,0.32265001625418677,0.32265001625418677,0.3407400147414208,0.3407400147414208,0.3407400147414208,0.3407400147414208,0.3407400147414208,0.3407400147414208,0.3589200067090985,0.3589200067090985,0.3589200067090985,0.3589200067090985,0.3589200067090985,0.3771000201344492,0.3771000201344492,0.3771000201344492,0.3771000201344492,0.3771000201344492,0.3771000201344492,0.3952800335597999,0.3952800335597999,0.3952800335597999,0.3952800335597999,0.3952800335597999,0.41346000406980465]},"atk":[null,42.4010009765625,45.92028171228594,49.39716452022549,52.91645031054213,56.39333311848168,59.91261385420512,63.389496662144666,66.9087773978681,70.42806318818475,73.9049459961243,77.42422673184774,80.90110953978729,84.42039533010393,87.89727308345027,91.41655381917371,94.93584466408356,98.41272747202311,101.93200820774655,105.4088910156861,108.92817175140954,134.8281713699398,138.30505417787936,141.8243349136028,145.34361564932624,148.82049845726578,152.33978930217563,155.81666200092877,159.33595284583862,162.81283565377817,166.3321163895016,169.80899919744115,173.3282799331646,176.84756066888804,180.32444347682758,183.84372421255102,187.32060702049057,190.83989786540042,194.31677056415356,197.836051299877,201.35534214478685,204.83221484354,230.83221675088862,234.35150759579847,237.82840051292442,241.34767113946145,244.8245640565874,248.34383468312444,251.8631255280343,255.33999822678743,258.8592890716973,262.3361617704504,265.85545261536026,291.75545414123917,295.2323268399923,298.75161768490216,302.270908529812,305.74778122856515,309.267072073475,312.74394477222813,316.263235617138,319.7401083158911,323.25939916080097,326.7786900057108,352.6786839021952,356.15555660094833,359.6748474458582,363.1517201446113,366.67101098952116,370.1478836882743,373.66717453318415,377.1864451597212,380.66333807684714,384.1826087033842,387.6595016205101,413.6595016205101,417.17879246542,420.6556651641731,424.17495600908296,427.69422663562,431.17111955274595,434.690390179283,438.16728309640894,441.686553722946,445.1634466400719,448.68271726660896,474.5827264218824,478.10201726679225,481.5789101839182,485.09818081045523,488.5750737275812,492.0943443541182,495.57121705287136,499.0905078977812,502.56738059653435,506.0866714414442,509.60596228635404]}}
\ No newline at end of file