{"action":"created","comment":{"url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/comments/240459925","pull_request_review_id":183494868,"id":240459925,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDI0MDQ1OTkyNQ==","diff_hunk":"@@ -0,0 +1,532 @@\n+import * as Firestore from '@google-cloud/firestore';\n+import * as express from 'express';\n+import * as functions from 'firebase-functions';\n+const uuidv4 = require('uuid/v4');\n+import * as createError from 'http-errors';\n+\n+// Firestore client - as a Cloud Function, this is\n+// all the setup we need\n+const firestore = new Firestore.Firestore({\n+    projectId: process.env.GCP_PROJECT,\n+    timestampsInSnapshots: true\n+  });\n+\n+// TODO: wrap await's in try/catch\n+\n+// TODO Remove this business\n+const aurelia = {\"name\":\"[CommanderReplay] Aurelia - RW Angel Reanimator (EDH / Commander)\",\"cards\":{\"Solemn Simulacrum\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Solemn Simulacrum\"},\"Ancient Tomb\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ancient Tomb\"},\"Magus of the Wheel\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Magus of the Wheel\"},\"Emeria Shepherd\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Emeria Shepherd\"},\"Iona, Shield of Emeria\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Iona, Shield of Emeria\"},\"Aurelia, the Warleader\":{\"quantity\":1,\"board\":\"command\",\"set\":null,\"scryfall_id\":\"Aurelia, the Warleader\"},\"Strip Mine\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Strip Mine\"},\"Teferi's Protection\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Teferi's Protection\"},\"Gisela, Blade of Goldnight\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gisela, Blade of Goldnight\"},\"Archangel of Thune\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Archangel of Thune\"},\"Angel of Serenity\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Angel of Serenity\"},\"Swords to Plowshares\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Swords to Plowshares\"},\"Ugin, the Spirit Dragon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ugin, the Spirit Dragon\"},\"Baneslayer Angel\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Baneslayer Angel\"},\"Windswept Heath\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Windswept Heath\"},\"Homeward Path\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Homeward Path\"},\"Return to Dust\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Return to Dust\"},\"Mistveil Plains\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mistveil Plains\"},\"Plains\":{\"quantity\":9,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Plains\"},\"Sword of the Animist\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sword of the Animist\"},\"Urza's Incubator\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Urza's Incubator\"},\"Land Tax\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Land Tax\"},\"Karmic Guide\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Karmic Guide\"},\"Command Tower\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Command Tower\"},\"Enlightened Tutor\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Enlightened Tutor\"},\"Sacred Foundry\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sacred Foundry\"},\"Boros Locket\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Boros Locket\"},\"Akroma, Angel of Fury\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Akroma, Angel of Fury\"},\"Bruna, the Fading Light\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Bruna, the Fading Light\"},\"Emeria, the Sky Ruin\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Emeria, the Sky Ruin\"},\"Mask of Memory\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mask of Memory\"},\"Gift of Estates\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gift of Estates\"},\"Nahiri, the Harbinger\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Nahiri, the Harbinger\"},\"Thran Dynamo\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Thran Dynamo\"},\"Chaos Warp\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Chaos Warp\"},\"Geier Reach Sanitarium\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Geier Reach Sanitarium\"},\"Worn Powerstone\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Worn Powerstone\"},\"Marsh Flats\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Marsh Flats\"},\"Myriad Landscape\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Myriad Landscape\"},\"Boros Garrison\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Boros Garrison\"},\"Reya Dawnbringer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Reya Dawnbringer\"},\"Gilded Lotus\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gilded Lotus\"},\"Path to Exile\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Path to Exile\"},\"Burnished Hart\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Burnished Hart\"},\"Altar of Dementia\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Altar of Dementia\"},\"Wheel of Fortune\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Wheel of Fortune\"},\"Devout Witness\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Devout Witness\"},\"Day of Judgment\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Day of Judgment\"},\"Mountain\":{\"quantity\":6,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mountain\"},\"Herald of War\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Herald of War\"},\"Path of Ancestry\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Path of Ancestry\"},\"Steelshaper's Gift\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Steelshaper's Gift\"},\"High Market\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"High Market\"},\"Expedition Map\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Expedition Map\"},\"Hedron Archive\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hedron Archive\"},\"Miraculous Recovery\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Miraculous Recovery\"},\"Arid Mesa\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Arid Mesa\"},\"Blasphemous Act\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Blasphemous Act\"},\"Hanweir Battlements\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hanweir Battlements\"},\"Boros Signet\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Boros Signet\"},\"Wrath of God\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Wrath of God\"},\"Temple of Triumph\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Temple of Triumph\"},\"Plateau\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Plateau\"},\"Planar Bridge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Planar Bridge\"},\"Adarkar Valkyrie\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Adarkar Valkyrie\"},\"Marshal's Anthem\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Marshal's Anthem\"},\"Temple of the False God\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Temple of the False God\"},\"Lightning Greaves\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Lightning Greaves\"},\"Battlefield Forge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Battlefield Forge\"},\"Vandalblast\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Vandalblast\"},\"Cavern of Souls\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Cavern of Souls\"},\"Flooded Strand\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Flooded Strand\"},\"Hour of Revelation\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hour of Revelation\"},\"Platinum Angel\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Platinum Angel\"},\"Tithe\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tithe\"},\"Angelic Skirmisher\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Angelic Skirmisher\"},\"Austere Command\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Austere Command\"},\"Mesmeric Orb\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mesmeric Orb\"},\"Aura of Silence\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Aura of Silence\"},\"Boros Charm\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Boros Charm\"},\"Dawnbreak Reclaimer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Dawnbreak Reclaimer\"},\"Sunhome, Fortress of the Legion\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sunhome, Fortress of the Legion\"},\"Avacyn, Angel of Hope\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Avacyn, Angel of Hope\"},\"Memory Jar\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Memory Jar\"},\"Stoneforge Mystic\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Stoneforge Mystic\"},\"Akroma, Angel of Wrath\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Akroma, Angel of Wrath\"},\"Angelic Arbiter\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Angelic Arbiter\"}}};\n+const xenagos = {\"name\":\"Budget Commander: Xenagos, God of Revels\",\"cards\":{\"Elemental Bond\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elemental Bond\"},\"Strionic Resonator\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Strionic Resonator\"},\"Llanowar Elves\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Llanowar Elves\"},\"Rapacious One\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rapacious One\"},\"Reclamation Sage\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Reclamation Sage\"},\"Nature's Lore\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Nature's Lore\"},\"Farseek\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Farseek\"},\"Giant Adephage\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Giant Adephage\"},\"Tyrant's Familiar\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tyrant's Familiar\"},\"Thunderfoot Baloth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Thunderfoot Baloth\"},\"Bane of Bala Ged\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Bane of Bala Ged\"},\"Sage of Ancient Lore\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sage of Ancient Lore\"},\"Phyrexian Hydra\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Phyrexian Hydra\"},\"Deus of Calamity\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Deus of Calamity\"},\"Moldgraf Monstrosity\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Moldgraf Monstrosity\"},\"Hydra Omnivore\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hydra Omnivore\"},\"Wood Elves\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Wood Elves\"},\"Elvish Mystic\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elvish Mystic\"},\"Silklash Spider\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Silklash Spider\"},\"Spellbreaker Behemoth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Spellbreaker Behemoth\"},\"Hunter's Prowess\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hunter's Prowess\"},\"Temple of Abandon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Temple of Abandon\"},\"Gruul Ragebeast\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gruul Ragebeast\"},\"Spearbreaker Behemoth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Spearbreaker Behemoth\"},\"Bane of Progress\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Bane of Progress\"},\"Gruul Guildgate\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gruul Guildgate\"},\"Feldon of the Third Path\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Feldon of the Third Path\"},\"Savage Ventmaw\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Savage Ventmaw\"},\"Terastodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Terastodon\"},\"Arbor Elf\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Arbor Elf\"},\"Fierce Empath\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Fierce Empath\"},\"Inferno Titan\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Inferno Titan\"},\"Gruul Signet\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gruul Signet\"},\"See the Unwritten\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"See the Unwritten\"},\"Fyndhorn Elves\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Fyndhorn Elves\"},\"Gruul Turf\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gruul Turf\"},\"Nature's Claim\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Nature's Claim\"},\"Kazandu Refuge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Kazandu Refuge\"},\"Rugged Highlands\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rugged Highlands\"},\"Malignus\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Malignus\"},\"Spinerock Knoll\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Spinerock Knoll\"},\"Warstorm Surge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Warstorm Surge\"},\"Ulvenwald Tracker\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ulvenwald Tracker\"},\"Molten Primordial\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Molten Primordial\"},\"Mountain\":{\"quantity\":12,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mountain\"},\"Rampaging Baloths\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rampaging Baloths\"},\"Acidic Slime\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Acidic Slime\"},\"Gruul Charm\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Gruul Charm\"},\"Mosswort Bridge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mosswort Bridge\"},\"Timber Gorge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Timber Gorge\"},\"Harmonize\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Harmonize\"},\"Life's Legacy\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Life's Legacy\"},\"Atarka, World Render\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Atarka, World Render\"},\"Vandalblast\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Vandalblast\"},\"Yavimaya Elder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Yavimaya Elder\"},\"Farhaven Elf\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Farhaven Elf\"},\"Ruric Thar, the Unbowed\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ruric Thar, the Unbowed\"},\"Sakura-Tribe Elder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sakura-Tribe Elder\"},\"Guild Feud\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Guild Feud\"},\"Skarrg, the Rage Pits\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Skarrg, the Rage Pits\"},\"Soul of the Harvest\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Soul of the Harvest\"},\"Blood Mist\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Blood Mist\"},\"Somberwald Sage\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Somberwald Sage\"},\"Xenagos, God of Revels\":{\"quantity\":1,\"board\":\"command\",\"set\":null,\"scryfall_id\":\"Xenagos, God of Revels\"},\"Chandra's Ignition\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Chandra's Ignition\"},\"Temur Battle Rage\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Temur Battle Rage\"},\"Hunter's Insight\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hunter's Insight\"},\"Skullwinder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Skullwinder\"},\"Forest\":{\"quantity\":17,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Forest\"},\"Evolutionary Leap\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Evolutionary Leap\"},\"Skullclamp\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Skullclamp\"},\"Artisan of Kozilek\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Artisan of Kozilek\"},\"Rampant Growth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rampant Growth\"}}}\n+const nin = {\"name\":\"Budget Coin Flips\",\"cards\":{\"Fabricate\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Fabricate\"},\"Darksteel Ingot\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Darksteel Ingot\"},\"Intellectual Offering\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Intellectual Offering\"},\"Karplusan Minotaur\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Karplusan Minotaur\"},\"Young Pyromancer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Young Pyromancer\"},\"Sol Ring\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sol Ring\"},\"Mana Geyser\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mana Geyser\"},\"Mogg Assassin\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mogg Assassin\"},\"Nin, the Pain Artist\":{\"quantity\":1,\"board\":\"command\",\"set\":null,\"scryfall_id\":\"Nin, the Pain Artist\"},\"Tide of War\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tide of War\"},\"Hammer of Purphoros\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Hammer of Purphoros\"},\"Stitch in Time\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Stitch in Time\"},\"Commander's Sphere\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Commander's Sphere\"},\"Swiftfoot Boots\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Swiftfoot Boots\"},\"Goblin Bangchuckers\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Bangchuckers\"},\"Treasure Cruise\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Treasure Cruise\"},\"Relic of Progenitus\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Relic of Progenitus\"},\"Everflowing Chalice\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Everflowing Chalice\"},\"Willbreaker\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Willbreaker\"},\"Muddle the Mixture\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Muddle the Mixture\"},\"Desperate Gambit\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Desperate Gambit\"},\"Izzet Boilerworks\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Izzet Boilerworks\"},\"Mind Stone\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mind Stone\"},\"Island\":{\"quantity\":15,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Island\"},\"Volatile Rig\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Volatile Rig\"},\"Creepy Doll\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Creepy Doll\"},\"Krark's Thumb\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Krark's Thumb\"},\"Puppet's Verdict\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Puppet's Verdict\"},\"Reshape\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Reshape\"},\"Izzet Charm\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Izzet Charm\"},\"Talrand, Sky Summoner\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Talrand, Sky Summoner\"},\"Brainstorm\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Brainstorm\"},\"Izzet Signet\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Izzet Signet\"},\"Squee's Revenge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Squee's Revenge\"},\"Tezzeret the Seeker\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tezzeret the Seeker\"},\"Risky Move\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Risky Move\"},\"Fervor\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Fervor\"},\"Worn Powerstone\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Worn Powerstone\"},\"Buried Ruin\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Buried Ruin\"},\"Goblin Assassin\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Assassin\"},\"Counterspell\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Counterspell\"},\"Goblin Archaeologist\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Archaeologist\"},\"Crooked Scales\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Crooked Scales\"},\"Burnished Hart\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Burnished Hart\"},\"Chance Encounter\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Chance Encounter\"},\"Game of Chaos\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Game of Chaos\"},\"Evolving Wilds\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Evolving Wilds\"},\"Ponder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ponder\"},\"Mountain\":{\"quantity\":16,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mountain\"},\"Preordain\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Preordain\"},\"Dig Through Time\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Dig Through Time\"},\"Impulse\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Impulse\"},\"Mystic Remora\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mystic Remora\"},\"Izzet Guildgate\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Izzet Guildgate\"},\"Thought Vessel\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Thought Vessel\"},\"Volcanic Offering\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Volcanic Offering\"},\"Goblin Festival\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Festival\"},\"Terramorphic Expanse\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Terramorphic Expanse\"},\"Myr Retriever\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Myr Retriever\"},\"Fiery Gambit\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Fiery Gambit\"},\"Goblin Welder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Welder\"},\"Swiftwater Cliffs\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Swiftwater Cliffs\"},\"Daretti, Scrap Savant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Daretti, Scrap Savant\"},\"Frenetic Efreet\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Frenetic Efreet\"},\"Goblin Kaboomist\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Goblin Kaboomist\"},\"Wayfarer's Bauble\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Wayfarer's Bauble\"},\"Swan Song\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Swan Song\"},\"Planar Chaos\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Planar Chaos\"},\"Highland Lake\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Highland Lake\"},\"Molten Birth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Molten Birth\"},\"Impulsive Maneuvers\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Impulsive Maneuvers\"}}};\n+const selvala = {\"name\":\"Trunkload of Elephants ($81)\",\"cards\":{\"Selvala, Explorer Returned\":{\"quantity\":1,\"board\":\"command\",\"set\":null,\"scryfall_id\":\"Selvala, Explorer Returned\"},\"Rabid Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rabid Elephant\"},\"Trained Armodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Trained Armodon\"},\"Wild Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Wild Elephant\"},\"Loxodon Hierarch\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Hierarch\"},\"Tranquil Expanse\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tranquil Expanse\"},\"Crazed Armodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Crazed Armodon\"},\"Cultivate\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Cultivate\"},\"Woolly Loxodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Woolly Loxodon\"},\"Coat of Arms\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Coat of Arms\"},\"Elfhame Palace\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elfhame Palace\"},\"Loxodon Partisan\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Partisan\"},\"Belbe's Portal\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Belbe's Portal\"},\"Kazandu Tuskcaller\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Kazandu Tuskcaller\"},\"Loxodon Warhammer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Warhammer\"},\"Loxodon Anchorite\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Anchorite\"},\"Loxodon Gatekeeper\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Gatekeeper\"},\"Tempting Licid\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Tempting Licid\"},\"Elephant Grass\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elephant Grass\"},\"Ghalma's Warden\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Ghalma's Warden\"},\"Kodama's Reach\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Kodama's Reach\"},\"Krosan Verge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Krosan Verge\"},\"Loxodon Smiter\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Smiter\"},\"Trumpeting Armodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Trumpeting Armodon\"},\"Elephant Ambush\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elephant Ambush\"},\"Plains\":{\"quantity\":11,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Plains\"},\"Urza's Incubator\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Urza's Incubator\"},\"Iron Tusk Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Iron Tusk Elephant\"},\"Sandsteppe Mastodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sandsteppe Mastodon\"},\"Mask of Memory\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mask of Memory\"},\"Terastodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Terastodon\"},\"Graypelt Refuge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Graypelt Refuge\"},\"Door of Destinies\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Door of Destinies\"},\"Behemoth Sledge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Behemoth Sledge\"},\"Call of the Herd\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Call of the Herd\"},\"Nemesis Mask\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Nemesis Mask\"},\"Frontier Mastodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Frontier Mastodon\"},\"Loxodon Wayfarer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Wayfarer\"},\"War Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"War Elephant\"},\"Cryptic Gateway\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Cryptic Gateway\"},\"Infiltration Lens\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Infiltration Lens\"},\"Nightshade Peddler\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Nightshade Peddler\"},\"Bow of Nylea\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Bow of Nylea\"},\"Loxodon Punisher\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Punisher\"},\"Blossoming Sands\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Blossoming Sands\"},\"War Mammoth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"War Mammoth\"},\"Acidic Slime\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Acidic Slime\"},\"Metamorphic Wurm\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Metamorphic Wurm\"},\"Noble Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Noble Elephant\"},\"Southern Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Southern Elephant\"},\"Mammoth Umbra\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mammoth Umbra\"},\"Brawn\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Brawn\"},\"Vintara Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Vintara Elephant\"},\"Loxodon Mystic\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Mystic\"},\"Prized Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Prized Elephant\"},\"Harmonize\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Harmonize\"},\"Selvala's Charge\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Selvala's Charge\"},\"Spelltithe Enforcer\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Spelltithe Enforcer\"},\"Elephant Guide\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elephant Guide\"},\"Loxodon Stalwart\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Loxodon Stalwart\"},\"Sakura-Tribe Elder\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Sakura-Tribe Elder\"},\"Selesnya Sanctuary\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Selesnya Sanctuary\"},\"Shinen of Life's Roar\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Shinen of Life's Roar\"},\"Siege Mastodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Siege Mastodon\"},\"Rampant Elephant\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rampant Elephant\"},\"Selesnya Sentry\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Selesnya Sentry\"},\"Forest\":{\"quantity\":19,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Forest\"},\"Selesnya Guildgate\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Selesnya Guildgate\"},\"Elephant Graveyard\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Elephant Graveyard\"},\"Rampant Growth\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Rampant Growth\"},\"Revenge of the Hunted\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Revenge of the Hunted\"},\"Mosstodon\":{\"quantity\":1,\"board\":\"main\",\"set\":null,\"scryfall_id\":\"Mosstodon\"}}};\n+\n+const deckList = {\n+    aurelia: aurelia,\n+    xenagos: xenagos,\n+    nin: nin,\n+    selvala: selvala\n+}\n+\n+const errorResponseMapper = function(error: createError.HttpError, response: express.Response): void {\n+    response.status(error.status)\n+        .header(error.headers)\n+        .send(error.message);\n+}\n+\n+\n+// Import one of the pre-defined decks for a player.\n+//\n+// Request body format:\n+// - player: string - the username of the player\n+// - deck: string - the short name of the predefined deck\n+export const importDeckForPlayer = functions.https.onRequest((request, response) => {\n+    if (request.method !== 'POST') {\n+        response.status(405)\n+            .header('Allow', 'POST')\n+            .send('Method Not Allowed');\n+    }\n+    \n+    const player = request.body.player;\n+    const deck = deckList[request.body.deck]\n+\n+    if (deck === undefined) {\n+        response.send('There is no deck identified by ' + request.body.deck);\n+    }\n+\n+    // This function will be removed in the future, so ignore this peek\n+    // into callback hell\n+    firestore.collection('Users').where('username', '==', player).limit(1).get()\n+        .then((querySnapshot) => {\n+            if (querySnapshot.docs.length === 0) {\n+                response\n+                    .status(400)\n+                    .send('There is no user with the username: ' + player);\n+            }\n+            querySnapshot.docs[0].ref.collection('Decks').add(deck)\n+                .then((addedDoc) => {\n+                    response\n+                        .status(201)\n+                        .header('X-DeckID', addedDoc.id)\n+                        .send('Deck imported at ' + addedDoc.path);\n+                 }).catch((reason) => {\n+                    response\n+                        .status(500)\n+                        .send('Failed to import deck: ' + reason);\n+                 });\n+        }).catch((reason) => {\n+            if (reason instanceof createError.HttpError) {\n+                errorResponseMapper(reason, response);\n+            } else {\n+                console.error('Caught unexpected error: ', reason);\n+                response.sendStatus(500);\n+            }\n+        });\n+});\n+\n+const createBaseGameDocument = function(params) {\n+    return {\n+        turn_order: {\n+            1: params.username\n+        }\n+    };\n+};\n+\n+enum PlayState {\n+    Playing = 'playing',\n+    Draw = 'draw',\n+    Lost = 'lost',\n+    Won = 'won'\n+};\n+\n+enum Board {\n+    Main = 'main',\n+    Command = 'command',\n+    Side = 'side',\n+    Maybe = 'maybe'\n+};\n+\n+enum Zone {\n+    Library = 'Library',\n+    Hand = 'Hand',\n+    Battlefield = 'Battlefield',\n+    Graveyard = 'Graveyard',\n+    Stack = 'Stack',\n+    Exile = 'Exile',\n+    Command = 'Command'\n+    // Reveal zone maybe?\n+};\n+\n+const createBasePlayerDocument = function(params) {\n+    return {\n+        life : 40,\n+        username : params.username,\n+        counters: {\n+            energy: 0,\n+            experience: 0,\n+            poison: 0\n+        },\n+        play_state: PlayState.Playing\n+    };\n+};\n+\n+const createEmptyZone = function() {\n+    return {\n+        cards: {}\n+    };\n+};\n+\n+const createLibraryZone = function(params) {\n+    const player = params.player;\n+    const deck = params.deck;\n+    const zone = createEmptyZone();\n+\n+    // Expand the deck so a card with quantity > 1 becomes\n+    // that number of distinct objects\n+    const library = [];\n+    Object.keys(deck.cards).forEach(key => {\n+        const card = deck.cards[key];\n+        for (let i = 0; i < card.quantity; i++) {\n+            library.push(card);\n+        }\n+    });\n+    // Now shuffle it\n+    library.sort(() => uuidv4());\n+\n+    // Now we can iterate over the library to create the zone\n+    let position = 0;\n+    library.forEach(card => {\n+        if (card.board === Board.Main) {\n+            const id = uuidv4();\n+            // We do not fully populate this since it is unnecessary,\n+            // and this reduces bandwidth usage (recall that we pay for \n+            // bandwith and since Firestore is schemaless, the field name \n+            // has to be sent as well)\n+            // TODO: this creates an invalid object... probably because the properties\n+            // aren't properly defined\n+            Object.defineProperty(zone.cards, id, {\n+                value: {\n+                    id: id,\n+                    scryfall_id: card.scryfall_id,\n+                    state: {\n+                        owner: player,\n+                        controller: player,\n+                        zone: Zone.Library,\n+                        position: position,\n+                        tapped: false,\n+                        face_up: false,\n+                        clone_of: null,\n+                        is_morph: false,\n+                        is_token: false,\n+                        power: null,\n+                        toughness: null,\n+                        attachments: {\n+                            counters: {\n+\n+                            },\n+                            permanents: {\n+\n+                            }\n+                        }\n+                    }\n+                },\n+                enumerable: true\n+            });\n+            position++;\n+        }\n+    });\n+    \n+    return zone;\n+};\n+\n+const createCommandZone = function(params) {\n+    const player = params.player;\n+    const deck = params.deck;","path":"firebase/functions/src/index.ts","position":202,"original_position":202,"commit_id":"b76c6a85858c5e9d733f8cc2252041a3feaa7662","original_commit_id":"b76c6a85858c5e9d733f8cc2252041a3feaa7662","user":{"login":"eeeeeric","id":3723705,"node_id":"MDQ6VXNlcjM3MjM3MDU=","avatar_url":"https://avatars0.githubusercontent.com/u/3723705?v=4","gravatar_id":"","url":"https://api.github.com/users/eeeeeric","html_url":"https://github.com/eeeeeric","followers_url":"https://api.github.com/users/eeeeeric/followers","following_url":"https://api.github.com/users/eeeeeric/following{/other_user}","gists_url":"https://api.github.com/users/eeeeeric/gists{/gist_id}","starred_url":"https://api.github.com/users/eeeeeric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eeeeeric/subscriptions","organizations_url":"https://api.github.com/users/eeeeeric/orgs","repos_url":"https://api.github.com/users/eeeeeric/repos","events_url":"https://api.github.com/users/eeeeeric/events{/privacy}","received_events_url":"https://api.github.com/users/eeeeeric/received_events","type":"User","site_admin":false},"body":"Also refactored this to individual parameters instead (I was actually forgetting to provide one of the parameters, which caused a silent failure - the field in the Zone object that depended on the undefined value was itself undefined).","created_at":"2018-12-11T03:08:25Z","updated_at":"2018-12-11T03:08:25Z","html_url":"https://github.com/acmorales/mystic-get-together/pull/3#discussion_r240459925","pull_request_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3","author_association":"COLLABORATOR","_links":{"self":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/comments/240459925"},"html":{"href":"https://github.com/acmorales/mystic-get-together/pull/3#discussion_r240459925"},"pull_request":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3"}},"in_reply_to_id":239327540},"pull_request":{"url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3","id":236390864,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM2MzkwODY0","html_url":"https://github.com/acmorales/mystic-get-together/pull/3","diff_url":"https://github.com/acmorales/mystic-get-together/pull/3.diff","patch_url":"https://github.com/acmorales/mystic-get-together/pull/3.patch","issue_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/3","number":3,"state":"open","locked":false,"title":"Initial commit of Firebase features.","user":{"login":"eeeeeric","id":3723705,"node_id":"MDQ6VXNlcjM3MjM3MDU=","avatar_url":"https://avatars0.githubusercontent.com/u/3723705?v=4","gravatar_id":"","url":"https://api.github.com/users/eeeeeric","html_url":"https://github.com/eeeeeric","followers_url":"https://api.github.com/users/eeeeeric/followers","following_url":"https://api.github.com/users/eeeeeric/following{/other_user}","gists_url":"https://api.github.com/users/eeeeeric/gists{/gist_id}","starred_url":"https://api.github.com/users/eeeeeric/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/eeeeeric/subscriptions","organizations_url":"https://api.github.com/users/eeeeeric/orgs","repos_url":"https://api.github.com/users/eeeeeric/repos","events_url":"https://api.github.com/users/eeeeeric/events{/privacy}","received_events_url":"https://api.github.com/users/eeeeeric/received_events","type":"User","site_admin":false},"body":"This commit includes the default files for many features such as Firestore (access rules and indexes), Functions, Hosting, and Storage (access rules).\r\n\r\nOnly Functions are of interest here - all other files are the default created by the firebase CLI.\r\n\r\nFunctions currently provide a way to\r\n- import a hardcoded deck (to be removed and replaced with a more robust solution soon)\r\n- create a new game given a player (username) and deckId (which must belong to player)\r\n- join an existing game given the gameId, player, and deckId\r\n- determine the turn order for a game, which is akin to rolling a dice for all active players","created_at":"2018-12-06T02:48:34Z","updated_at":"2018-12-11T03:08:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":"576e12c57e5b5c3e2fd94d21eacbf167f89b6659","assignee":{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false},"assignees":[{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1110838530,"node_id":"MDU6TGFiZWwxMTEwODM4NTMw","url":"https://api.github.com/repos/acmorales/mystic-get-together/labels/enhancement","name":"enhancement","color":"a2eeef","default":true}],"milestone":null,"commits_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3/commits","review_comments_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3/comments","review_comment_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/comments{/number}","comments_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/3/comments","statuses_url":"https://api.github.com/repos/acmorales/mystic-get-together/statuses/b76c6a85858c5e9d733f8cc2252041a3feaa7662","head":{"label":"acmorales:cloud-functions","ref":"cloud-functions","sha":"b76c6a85858c5e9d733f8cc2252041a3feaa7662","user":{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false},"repo":{"id":155491926,"node_id":"MDEwOlJlcG9zaXRvcnkxNTU0OTE5MjY=","name":"mystic-get-together","full_name":"acmorales/mystic-get-together","private":false,"owner":{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false},"html_url":"https://github.com/acmorales/mystic-get-together","description":"Mystic the Get-Together","fork":false,"url":"https://api.github.com/repos/acmorales/mystic-get-together","forks_url":"https://api.github.com/repos/acmorales/mystic-get-together/forks","keys_url":"https://api.github.com/repos/acmorales/mystic-get-together/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acmorales/mystic-get-together/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acmorales/mystic-get-together/teams","hooks_url":"https://api.github.com/repos/acmorales/mystic-get-together/hooks","issue_events_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/events{/number}","events_url":"https://api.github.com/repos/acmorales/mystic-get-together/events","assignees_url":"https://api.github.com/repos/acmorales/mystic-get-together/assignees{/user}","branches_url":"https://api.github.com/repos/acmorales/mystic-get-together/branches{/branch}","tags_url":"https://api.github.com/repos/acmorales/mystic-get-together/tags","blobs_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/refs{/sha}","trees_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acmorales/mystic-get-together/statuses/{sha}","languages_url":"https://api.github.com/repos/acmorales/mystic-get-together/languages","stargazers_url":"https://api.github.com/repos/acmorales/mystic-get-together/stargazers","contributors_url":"https://api.github.com/repos/acmorales/mystic-get-together/contributors","subscribers_url":"https://api.github.com/repos/acmorales/mystic-get-together/subscribers","subscription_url":"https://api.github.com/repos/acmorales/mystic-get-together/subscription","commits_url":"https://api.github.com/repos/acmorales/mystic-get-together/commits{/sha}","git_commits_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/commits{/sha}","comments_url":"https://api.github.com/repos/acmorales/mystic-get-together/comments{/number}","issue_comment_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/comments{/number}","contents_url":"https://api.github.com/repos/acmorales/mystic-get-together/contents/{+path}","compare_url":"https://api.github.com/repos/acmorales/mystic-get-together/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acmorales/mystic-get-together/merges","archive_url":"https://api.github.com/repos/acmorales/mystic-get-together/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acmorales/mystic-get-together/downloads","issues_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues{/number}","pulls_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls{/number}","milestones_url":"https://api.github.com/repos/acmorales/mystic-get-together/milestones{/number}","notifications_url":"https://api.github.com/repos/acmorales/mystic-get-together/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acmorales/mystic-get-together/labels{/name}","releases_url":"https://api.github.com/repos/acmorales/mystic-get-together/releases{/id}","deployments_url":"https://api.github.com/repos/acmorales/mystic-get-together/deployments","created_at":"2018-10-31T03:18:01Z","updated_at":"2018-12-06T04:07:52Z","pushed_at":"2018-12-10T04:05:02Z","git_url":"git://github.com/acmorales/mystic-get-together.git","ssh_url":"git@github.com:acmorales/mystic-get-together.git","clone_url":"https://github.com/acmorales/mystic-get-together.git","svn_url":"https://github.com/acmorales/mystic-get-together","homepage":"","size":800,"stargazers_count":3,"watchers_count":3,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":3,"license":null,"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"base":{"label":"acmorales:master","ref":"master","sha":"2dc19063e2bffaff215dcb1fac0d6a85fbc14b37","user":{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false},"repo":{"id":155491926,"node_id":"MDEwOlJlcG9zaXRvcnkxNTU0OTE5MjY=","name":"mystic-get-together","full_name":"acmorales/mystic-get-together","private":false,"owner":{"login":"acmorales","id":8978958,"node_id":"MDQ6VXNlcjg5Nzg5NTg=","avatar_url":"https://avatars1.githubusercontent.com/u/8978958?v=4","gravatar_id":"","url":"https://api.github.com/users/acmorales","html_url":"https://github.com/acmorales","followers_url":"https://api.github.com/users/acmorales/followers","following_url":"https://api.github.com/users/acmorales/following{/other_user}","gists_url":"https://api.github.com/users/acmorales/gists{/gist_id}","starred_url":"https://api.github.com/users/acmorales/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/acmorales/subscriptions","organizations_url":"https://api.github.com/users/acmorales/orgs","repos_url":"https://api.github.com/users/acmorales/repos","events_url":"https://api.github.com/users/acmorales/events{/privacy}","received_events_url":"https://api.github.com/users/acmorales/received_events","type":"User","site_admin":false},"html_url":"https://github.com/acmorales/mystic-get-together","description":"Mystic the Get-Together","fork":false,"url":"https://api.github.com/repos/acmorales/mystic-get-together","forks_url":"https://api.github.com/repos/acmorales/mystic-get-together/forks","keys_url":"https://api.github.com/repos/acmorales/mystic-get-together/keys{/key_id}","collaborators_url":"https://api.github.com/repos/acmorales/mystic-get-together/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/acmorales/mystic-get-together/teams","hooks_url":"https://api.github.com/repos/acmorales/mystic-get-together/hooks","issue_events_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/events{/number}","events_url":"https://api.github.com/repos/acmorales/mystic-get-together/events","assignees_url":"https://api.github.com/repos/acmorales/mystic-get-together/assignees{/user}","branches_url":"https://api.github.com/repos/acmorales/mystic-get-together/branches{/branch}","tags_url":"https://api.github.com/repos/acmorales/mystic-get-together/tags","blobs_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/refs{/sha}","trees_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/trees{/sha}","statuses_url":"https://api.github.com/repos/acmorales/mystic-get-together/statuses/{sha}","languages_url":"https://api.github.com/repos/acmorales/mystic-get-together/languages","stargazers_url":"https://api.github.com/repos/acmorales/mystic-get-together/stargazers","contributors_url":"https://api.github.com/repos/acmorales/mystic-get-together/contributors","subscribers_url":"https://api.github.com/repos/acmorales/mystic-get-together/subscribers","subscription_url":"https://api.github.com/repos/acmorales/mystic-get-together/subscription","commits_url":"https://api.github.com/repos/acmorales/mystic-get-together/commits{/sha}","git_commits_url":"https://api.github.com/repos/acmorales/mystic-get-together/git/commits{/sha}","comments_url":"https://api.github.com/repos/acmorales/mystic-get-together/comments{/number}","issue_comment_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues/comments{/number}","contents_url":"https://api.github.com/repos/acmorales/mystic-get-together/contents/{+path}","compare_url":"https://api.github.com/repos/acmorales/mystic-get-together/compare/{base}...{head}","merges_url":"https://api.github.com/repos/acmorales/mystic-get-together/merges","archive_url":"https://api.github.com/repos/acmorales/mystic-get-together/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/acmorales/mystic-get-together/downloads","issues_url":"https://api.github.com/repos/acmorales/mystic-get-together/issues{/number}","pulls_url":"https://api.github.com/repos/acmorales/mystic-get-together/pulls{/number}","milestones_url":"https://api.github.com/repos/acmorales/mystic-get-together/milestones{/number}","notifications_url":"https://api.github.com/repos/acmorales/mystic-get-together/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/acmorales/mystic-get-together/labels{/name}","releases_url":"https://api.github.com/repos/acmorales/mystic-get-together/releases{/id}","deployments_url":"https://api.github.com/repos/acmorales/mystic-get-together/deployments","created_at":"2018-10-31T03:18:01Z","updated_at":"2018-12-06T04:07:52Z","pushed_at":"2018-12-10T04:05:02Z","git_url":"git://github.com/acmorales/mystic-get-together.git","ssh_url":"git@github.com:acmorales/mystic-get-together.git","clone_url":"https://github.com/acmorales/mystic-get-together.git","svn_url":"https://github.com/acmorales/mystic-get-together","homepage":"","size":800,"stargazers_count":3,"watchers_count":3,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"archived":false,"open_issues_count":3,"license":null,"forks":1,"open_issues":3,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3"},"html":{"href":"https://github.com/acmorales/mystic-get-together/pull/3"},"issue":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/issues/3"},"comments":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/acmorales/mystic-get-together/statuses/b76c6a85858c5e9d733f8cc2252041a3feaa7662"}},"author_association":"COLLABORATOR"}}
{"actor":{"display_login":"eeeeeric"}}