{"version":3,"sources":["serviceWorker.js","Helper.js","Config.js","Card.js","Deck.js","ScoreKeeper.js","IceColumn.js","ApexCardSlot.js","CardModal.js","EcoChains.js","index.js"],"names":["Boolean","window","location","hostname","match","data","JSON","parse","stringify","array","temporaryValue","randomIndex","currentIndex","length","Math","floor","random","string","target","replaceWith","newString","includes","replace","ICE_CARD","type","name","img","needsIce","diet","resolution","ICE_ALGEA_CARD","symbol","facts","trophicLevel","PHYTO_PLANKTON_CARD","ICE_COPEPOD_CARD","fullName","KRILL_CARD","CLAM_CARD","ARCTIC_COD","ARCTIC_COD_CARD","SQUID_CARD","RINGED_SEAL_CARD","BEARDED_SEAL_CARD","BELUGA_WHALE_CARD","BOWHEAD_WHALE_CARD","NARWHAL_CARD","EIDER_DUCK_CARD","WALRUS_CARD","HUMAN_CARD","POLAR_BEAR_CARD","CARBON_POLLUTION_CARD_ONE","footer","blockerText","iceDestroyed","CARBON_POLLUTION_CARD_TWO","CARBON_POLLUTION_CARD_THREE","CARBON_POLLUTION_CARD_FOUR","RAPID_SEA_ICE_LOSS_CARD","INVASIVE_KILLER_WHALE_TARGETS","INVASIVE_KILLER_WHALE_CARD","validTargets","join","OCEAN_ACIDIFICATION_CARD","OVER_HARVESTING_TARGETS","OVER_HARVESTING_CARD","GREEN_TRANSPORTATION_CARD","ALTERNATE_ENERGY_CARD","ENERGY_EFFICIENCY_CARD","PROTECT_A_SPECIES_CARD","loadingScreenTextTitle","loadingScreenTextBody","types","lifeform","apexPredator","worldEvent","action","resolutions","addIce","iceRestoration","removeIce","rapidSeaIceLoss","protectSpecies","removeSpecies","oceanAcid","overHarvesting","invasiveWhales","gameModes","layout","cards","ice","carbonPollution","protectASpecies","invasiveKillerWhale","oceanAcidification","phytoPlankton","iceAlgea","seaIceRestoration","initialPlayAreas","iceColumn1","Helper","iceColumn2","iceColumn3","iceColumn4","iceColumn5","iceColumn6","iceColumn7","decks","normal","Card","onMouseDown","bind","onDoubleClick","event","this","props","card","index","className","key","opacity","isProtected","map","createPreyIcon","wrapperClassName","isScared","protectedSpecies","protectedSpeciesName","Config","style","getOpacity","otherTitle","cardDom","isFaceDown","toLowerCase","extraClassNames","getApexPredatorDom","getSpeciesDom","getWorldEventDom","getActionDom","position","transform","x","y","zIndex","onDblClick","id","Component","Deck","onClick","createCardElement","isActive","isDiscarded","isPlacedInColumn","onMouseDownOnCard","children","ScoreKeeper","state","lastScore","setState","score","label","IceColumn","ApexCardSlot","createFoodChainCardElement","givenFoodChain","toString","CardModal","dietString","forEach","isProtectSpeciesCard","cardInfoTitle","cardInfoText","title","replaceAll","detailsTitle","detailsText","pointsTitle","pointsText","actionValidTargetListText","createValidTargetString","bonusClass","isPredator","tlOneClassName","tlTwoClassName","tlThreeClassName","tlFourClassName","tlFiveClassName","iceRequiredDom","modalClassName","infoDom","createDietString","dom","getProtectASpeciesDom","console","log","DRAWN_CARD_INITIAL_POSITION","EcoChains","currentGameMode","deck","discard","predatoryMammals","targetCardIndex","drawIndex","faceUpPosition","iceColumns","isDraggingCard","relativePosition","turnStep","speciesScore","iceScore","bonusScore","fedPredatorScoreBonus","species","cardParent","drawnApexPredators","apexPredatorFoodChains","zero","one","two","three","outOfPlay","fadingOut","otherCardsBeingDragged","uniqueSpeciesInPlay","cardToInspect","showInspectionModal","showEndGameScreen","showCreditsModal","showStopDrawCover","stopperCard","mouseX","mouseY","waitingToSpliceNullChildren","animatingCards","addIceRestoration","round","addRapidSeaIceLoss","debug","forceExtraCardsOff","forceExtraCardsOn","shakingCards","hideHelpButton","_iceColumnDoms","Object","assign","targetIndex","flipAndMoveCard","onMouseUp","onMouseMove","createIceColumn","onDoubleclick","closeModal","endGame","showCredits","hideCredits","document","addEventListener","ondblclick","a","board","prepareDeck","shuffleCards","putCardsInDrawDeck","setTimeout","clear","prepareBoard","anime","targets","querySelector","easing","duration","delay","complete","remove","flavorText","createElement","innerHTML","flavorTextBody","button","classList","add","onclick","removeLoadingScreen","appendChild","error","helpButton","Promise","resolve","prevState","splice","isDiscard","push","boardLayout","list","item","targetColumn","prepareCards","concat","realignCards","subList","subKey","cardIndex","colIndex","columnId","undefined","offset","prevProps","snapshot","iceCount","uniqueNames","column","update","predatorIceScore","fedScore","keys","clearColumn","isPlaceInColumn","cardsToFadeOut","fadeOutCardOutOfPlay","sortIceColumnsZIndex","targetCard","findCard","columnIndex","Number","split","foundCard","child","deckDom","validIndex","flipCard","getElementById","cardWidth","getBoundingClientRect","width","checkIceAmount","checkValidTargetForEvent","moveApexPredatorToSlot","moveCardToDiscard","bringCardToFront","incrementTurnStep","i","cardBoundsUnderOldParent","deckX","left","predX","hypot","destinationX","unshift","loop","dur","iceCol","crdParent","crdIndex","iceColIndex","iceColumnIndex","mainCard","col","otherCard","modifier","modified","abs","showCreditsScreen","reload","contains","pageX","pageY","stopPropagation","preventDefault","isIce","isAlgea","pos","validDrop","checkIfCardCanGoInColumn","crd","checkIfSpeciesCanGoInColumn","otherCards","oldParent","otherCardIndex","newParent","startIndex","newParentDom","newParentRect","destinationY","makeSureCardsBelongToCorrectColumn","iceColumn","sendBackToDiscard","iceAmount","changeIceAmount","cardToFade","newState","checkIceRemovedSurvivors","checkIceDependentSpecies","result","checkWhichCardToProtect","targetColumnIndex","cardToFadeOut","protectedCard","targetCards","speciesCard","cardsToFade","crdToFade","feedingPredator","checkIfFeedingPredator","canFeedPredator","closestCollision","draggingPartialStack","k","colX","predIndex","predRect","newPos","topCard","validTargetsAvailable","sendBackToIceColumn","predatorDom","worldEventCard","removeScaredClass","dietObject","parentElement","hasStartedFadeAnimation","ease","anim","c","progress","filter","cardCenter","columnACenter","columnBCenter","colAResult","colBResult","ceil","columns","hasAlgea","hasPlankton","columnDom","cardBounds","clientWidth","columnBounds","columnWidth","right","amountOfIce","earliestIndex","collisions","collision","checkForCollision","selectedColumn","findClosestColumn","predatorDoms","start","inDiet","checkForMouseCollision","mouseEvent","domBounds","withinX","withinY","top","bottom","topChild","eatsThatAnimal","isIceAlgea","eventCard","columnCheck","lowestIndex","validTargetName","targetY","closestY","closestIndex","validCard","ref","collectIceColumnDomRef","startTour","leftColumnElements","rightColumnElements","stopDrawCover","discardDeck","predatoryMammalSlots","warn","totalScore","src","href","class","renderFadingOutCards","newGame","ReactDOM","render","StrictMode","navigator","serviceWorker","ready","then","registration","unregister","catch","message"],"mappings":"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Ac/D,KAItB,CACI8D,WAAY,CACRC,EAActE,GACdsE,EAAcjE,GACdiE,EAAc5D,IAElB6D,WAAY,CACRD,EAActE,GACdsE,EAAcjE,GACdiE,EAAc5D,IAElB8D,WAAY,CACRF,EAActE,GACdsE,EAAcjE,IAElBoE,WAAY,CACRH,EAActE,IAElB0E,WAAY,CACRJ,EAAclE,IAElBuE,WAAY,CACRL,EAAclE,IAGlBwE,WAAY,CACRN,EAAclE,GACdkE,EAAc/D,MAM1BsE,MAAO,CAEHC,OAAQ,CAGJR,EAvtBmB,CAC3B5E,KAAM,GACNC,KAAM,GACNC,IAAK,GACLC,SAAU,EACVC,KAAM,GACNC,WAAY,KAktBJuE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAActE,GACdsE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAclE,GACdkE,EAAc/D,GACd+D,EAAc/D,GACd+D,EAAc/D,GACd+D,EAAc/D,GACd+D,EAAc/D,GACd+D,EAAc/D,GACd+D,EAAc9D,GACd8D,EAAc9D,GACd8D,EAAc9D,GACd8D,EAAc9D,GACd8D,EAAc9D,GACd8D,EAAc9D,GACd8D,EAAcjE,GACdiE,EAAcjE,GACdiE,EAAcjE,GACdiE,EAAcjE,GACdiE,EAAcjE,GACdiE,EAAcjE,GACdiE,EAAc5D,GACd4D,EAAc5D,GACd4D,EAAc5D,GACd4D,EAAc5D,GACd4D,EAAc3D,GACd2D,EAAc3D,GACd2D,EAAc3D,GACd2D,EAAc3D,GACd2D,EAAcxD,GACdwD,EAAcxD,GACdwD,EAAc1D,GACd0D,EAAc1D,GACd0D,EAAczD,GACdyD,EAAczD,GACdyD,EAAcvD,GACduD,EAAcvD,GACduD,EAActD,GACdsD,EAActD,GACdsD,EAAcrD,GACdqD,EAAcrD,GACdqD,EAAcpD,GACdoD,EAAcpD,GAGdoD,EAAcjD,GACd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","file":"static/js/main.5f1c6ba3.chunk.js","sourcesContent":["// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n  window.location.hostname === 'localhost' ||\r\n    // [::1] is the IPv6 localhost address.\r\n    window.location.hostname === '[::1]' ||\r\n    // 127.0.0.0/8 are considered localhost for IPv4.\r\n    window.location.hostname.match(\r\n      /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n    )\r\n);\r\n\r\nexport function register(config) {\r\n  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n    // The URL constructor is available in all browsers that support SW.\r\n    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\r\n    if (publicUrl.origin !== window.location.origin) {\r\n      // Our service worker won't work if PUBLIC_URL is on a different origin\r\n      // from what our page is served on. This might happen if a CDN is used to\r\n      // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n      return;\r\n    }\r\n\r\n    window.addEventListener('load', () => {\r\n      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n      if (isLocalhost) {\r\n        // This is running on localhost. Let's check if a service worker still exists or not.\r\n        checkValidServiceWorker(swUrl, config);\r\n\r\n        // Add some additional logging to localhost, pointing developers to the\r\n        // service worker/PWA documentation.\r\n        navigator.serviceWorker.ready.then(() => {\r\n          console.log(\r\n            'This web app is being served cache-first by a service ' +\r\n              'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n          );\r\n        });\r\n      } else {\r\n        // Is not localhost. Just register service worker\r\n        registerValidSW(swUrl, config);\r\n      }\r\n    });\r\n  }\r\n}\r\n\r\nfunction registerValidSW(swUrl, config) {\r\n  navigator.serviceWorker\r\n    .register(swUrl)\r\n    .then(registration => {\r\n      registration.onupdatefound = () => {\r\n        const installingWorker = registration.installing;\r\n        if (installingWorker == null) {\r\n          return;\r\n        }\r\n        installingWorker.onstatechange = () => {\r\n          if (installingWorker.state === 'installed') {\r\n            if (navigator.serviceWorker.controller) {\r\n              // At this point, the updated precached content has been fetched,\r\n              // but the previous service worker will still serve the older\r\n              // content until all client tabs are closed.\r\n              console.log(\r\n                'New content is available and will be used when all ' +\r\n                  'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n              );\r\n\r\n              // Execute callback\r\n              if (config && config.onUpdate) {\r\n                config.onUpdate(registration);\r\n              }\r\n            } else {\r\n              // At this point, everything has been precached.\r\n              // It's the perfect time to display a\r\n              // \"Content is cached for offline use.\" message.\r\n              console.log('Content is cached for offline use.');\r\n\r\n              // Execute callback\r\n              if (config && config.onSuccess) {\r\n                config.onSuccess(registration);\r\n              }\r\n            }\r\n          }\r\n        };\r\n      };\r\n    })\r\n    .catch(error => {\r\n      console.error('Error during service worker registration:', error);\r\n    });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl, config) {\r\n  // Check if the service worker can be found. If it can't reload the page.\r\n  fetch(swUrl, {\r\n    headers: { 'Service-Worker': 'script' },\r\n  })\r\n    .then(response => {\r\n      // Ensure service worker exists, and that we really are getting a JS file.\r\n      const contentType = response.headers.get('content-type');\r\n      if (\r\n        response.status === 404 ||\r\n        (contentType != null && contentType.indexOf('javascript') === -1)\r\n      ) {\r\n        // No service worker found. Probably a different app. Reload the page.\r\n        navigator.serviceWorker.ready.then(registration => {\r\n          registration.unregister().then(() => {\r\n            window.location.reload();\r\n          });\r\n        });\r\n      } else {\r\n        // Service worker found. Proceed as normal.\r\n        registerValidSW(swUrl, config);\r\n      }\r\n    })\r\n    .catch(() => {\r\n      console.log(\r\n        'No internet connection found. App is running in offline mode.'\r\n      );\r\n    });\r\n}\r\n\r\nexport function unregister() {\r\n  if ('serviceWorker' in navigator) {\r\n    navigator.serviceWorker.ready\r\n      .then(registration => {\r\n        registration.unregister();\r\n      })\r\n      .catch(error => {\r\n        console.error(error.message);\r\n      });\r\n  }\r\n}\r\n","// Holds useful functions\r\n\r\nexport default {\r\n    clone: function (data) {\r\n        return JSON.parse ( JSON.stringify (data) )\r\n    },\r\n\r\n    // The de-facto unbiased shuffle algorithm is the Fisher-Yates (aka Knuth) Shuffle.\r\n    // See https://github.com/coolaj86/knuth-shuffle\r\n    // Modifies original array\r\n    shuffle: function (array) {\r\n        var currentIndex = array.length, temporaryValue, randomIndex;\r\n\r\n        // While there remain elements to shuffle...\r\n        while (0 !== currentIndex) {\r\n            // Pick a remaining element...\r\n            randomIndex = Math.floor(Math.random() * currentIndex);\r\n            currentIndex -= 1;\r\n\r\n            // And swap it with the current element.\r\n            temporaryValue = array[currentIndex];\r\n            array[currentIndex] = array[randomIndex];\r\n            array[randomIndex] = temporaryValue;\r\n        }\r\n\r\n        return array;\r\n    },\r\n\r\n    replaceAll: function (string, target, replaceWith) {\r\n        let i = 0;\r\n        let end = string.length;\r\n        let newString = string;\r\n\r\n        while (newString.includes (target)) {\r\n            newString = newString.replace (target, replaceWith)\r\n        }\r\n\r\n        return newString;\r\n    }\r\n}\r\n","import Helper from './Helper';\r\n\r\n// Layout styles\r\nconst LAYOUT_DECK_ON_LEFT = 1;\r\nconst LAYOUT_DECK_ON_RIGHT = 2;\r\n\r\n// types\r\nconst LIFEFORM = 'species';\r\nconst APEX_PREDATOR = 'apex predator';\r\nconst WORLD_EVENT = 'event';\r\nconst ACTION = 'action';\r\n\r\n// Event Outcomes\r\nconst EO_NONE = 'none';\r\nconst EO_ADD_TO_PLAY = 'Add to play';\r\nconst EO_ADD_PREDATOR_TO_PLAY = 'Add predator to play';\r\nconst EO_REMOVE_TWO_ICE = 'Remove two ice';\r\nconst EO_REMOVE_THREE_ICE = 'Remove three ice';\r\nconst EO_ADD_ONE_ICE = 'Add one ice';\r\nconst EO_ADD_TWO_ICE = 'Add two ice';\r\nconst EO_PROTECT_SPECIES = 'Protect a Species';\r\nconst EO_REMOVE_SPECIES = 'Remove Species';\r\nconst EO_INVASIVE_WHALES = 'Invasive Whales'\r\nconst EO_OCEAN_ACID = 'Ocean Acid';\r\nconst EO_OVER_HARVESTING = 'Over Harvesting'\r\n\r\nconst TROPHIC_LEVEL_ONE = 1;\r\nconst TROPHIC_LEVEL_TWO = 2;\r\nconst TROPHIC_LEVEL_THREE = 3;\r\nconst TROPHIC_LEVEL_FOUR = 4;\r\nconst TROPHIC_LEVEL_FIVE = 5;\r\n\r\nconst DUMMY_INITIALIZER_CARD = {\r\n    type: '',\r\n    name: '',\r\n    img: '',\r\n    needsIce: 0,\r\n    diet: [],\r\n    resolution: ''\r\n}\r\n\r\n// Cards\r\n    // Ice\r\nconst ICE = 'Ice';\r\nconst ICE_IMG = './assets/ice.png';\r\nconst ICE_CARD = {\r\n    type: ICE,\r\n    name: ICE,\r\n    img: ICE_IMG,\r\n    needsIce: 0,\r\n    diet: [],\r\n    resolution: EO_NONE\r\n};\r\n\r\n    // Ice Algea\r\nconst ICE_ALGEA = 'Ice Algae';\r\nconst ICE_ALGEA_SYMBOL ='IA';\r\nconst ICE_ALGEA_DIET = [];\r\nconst ICE_ALGEA_IMG = './assets/ice-algae.png';\r\nconst ICE_ALGEA_CARD = {\r\n    type: LIFEFORM,\r\n    name: ICE_ALGEA,\r\n    img: ICE_ALGEA_IMG,\r\n    needsIce: 1,\r\n    diet: ICE_ALGEA_DIET,\r\n    resolution: EO_ADD_TO_PLAY,\r\n    symbol: ICE_ALGEA_SYMBOL,\r\n    facts: 'Ice algae are primary producers that grow directly on sea ice.',\r\n    trophicLevel: TROPHIC_LEVEL_ONE,\r\n};\r\n\r\n    // Phyto-plankton\r\nconst PHYTO_PLANKTON = 'Phytoplankton';\r\nconst PHYTO_PLANKTON_SYMBOL = 'P';\r\nconst PHYTO_PLANKTON_DIET = [];\r\nconst PHYTO_PLANKTON_CARD = {\r\n    type: LIFEFORM,\r\n    name: PHYTO_PLANKTON,\r\n    diet: PHYTO_PLANKTON_DIET,\r\n    img: '',\r\n    needsIce: 0,\r\n    symbol: PHYTO_PLANKTON_SYMBOL,\r\n    facts: 'Phytoplankton are primary producers and need nutrients, sunlight and stability to grow in seawater.',\r\n    trophicLevel: TROPHIC_LEVEL_ONE,\r\n}\r\n\r\n// Ice Copepod\r\nconst ICE_COPEPOD = 'Ice Copepod';\r\nconst ICE_COPEPOD_SYMBOL = 'IC';\r\nconst ICE_COPEPOD_IMG = '';\r\nconst ICE_COPEPOD_DIET = [\r\n    {name: ICE_ALGEA_SYMBOL, trophicLevel: 1, fullName: ICE_ALGEA},\r\n];\r\nconst ICE_COPEPOD_CARD = {\r\n    type: LIFEFORM,\r\n    name: ICE_COPEPOD,\r\n    img: ICE_COPEPOD_IMG,\r\n    needsIce: 0,\r\n    diet: ICE_COPEPOD_DIET,\r\n    symbol: ICE_COPEPOD_SYMBOL,\r\n    facts: 'The bodies of ice copepods are up to 70% fat to help them survive the long Arctic winters.',\r\n    trophicLevel: TROPHIC_LEVEL_TWO,\r\n};\r\n\r\n    // Krill\r\nconst KRILL = 'Krill';\r\nconst KRILL_SYMBOL = 'K';\r\nconst KRILL_IMG = './assets/krill.png';\r\nconst KRILL_DIET = [\r\n    {name: ICE_ALGEA_SYMBOL, trophicLevel: 1, fullName: ICE_ALGEA},\r\n    {name: PHYTO_PLANKTON_SYMBOL, trophicLevel: 1, fullName: PHYTO_PLANKTON},\r\n    // {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD},\r\n];\r\nconst KRILL_CARD = {\r\n    type: LIFEFORM,\r\n    name: KRILL,\r\n    img: KRILL_IMG,\r\n    needsIce: 0,\r\n    diet: KRILL_DIET,\r\n    resolution: EO_ADD_TO_PLAY,\r\n    symbol: KRILL_SYMBOL,\r\n    facts: 'These tiny shrimp-like creatures are a primary food source for many whales, seabirds, fish, squid & seals',\r\n    trophicLevel: TROPHIC_LEVEL_TWO,\r\n};\r\n\r\n    // Clam\r\nconst CLAM = 'Clam';\r\nconst CLAM_SYMBOL = 'C';\r\nconst CLAM_IMG = '';\r\nconst CLAM_DIET = [\r\n    {name: ICE_ALGEA_SYMBOL, trophicLevel: 1, fullName: ICE_ALGEA},\r\n    {name: PHYTO_PLANKTON_SYMBOL, trophicLevel: 1, fullName: PHYTO_PLANKTON},\r\n];\r\nconst CLAM_CARD = {\r\n    type: LIFEFORM,\r\n    name: CLAM,\r\n    img: CLAM_IMG,\r\n    needsIce: 0,\r\n    diet: CLAM_DIET,\r\n    symbol: CLAM_SYMBOL,\r\n    facts: 'Clams live in seafloor sediment, remaining connected to the water through snorkel-like siphons.',\r\n    trophicLevel: TROPHIC_LEVEL_TWO,\r\n};\r\n\r\n    // Arctic Cod\r\nconst ARCTIC_COD = 'Arctic Cod';\r\nconst ARCTIC_COD_SYMBOL = 'AC';\r\nconst ARCTIC_COD_IMG = './assets/arctic-cod.png';\r\nconst ARCTIC_COD_DIET = [\r\n    {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD}\r\n];\r\nconst ARCTIC_COD_CARD = {\r\n    type: LIFEFORM,\r\n    name: ARCTIC_COD,\r\n    img: ARCTIC_COD_IMG,\r\n    diet: ARCTIC_COD_DIET,\r\n    needsIce: 1,\r\n    symbol: ARCTIC_COD_SYMBOL,\r\n    facts: 'Sea ice contains nooks and crannies that provide the Arctic Cod refuge from predators.',\r\n    trophicLevel: TROPHIC_LEVEL_THREE,\r\n};\r\n\r\n    // Squid\r\nconst SQUID = 'Squid';\r\nconst SQUID_SYMBOL = 'S';\r\nconst SQUID_IMG = '';\r\nconst SQUID_DIET = [\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD},\r\n    {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n];\r\nconst SQUID_CARD = {\r\n    type: LIFEFORM,\r\n    name: SQUID,\r\n    img: SQUID_IMG,\r\n    needsIce: 0,\r\n    diet: SQUID_DIET,\r\n    symbol: SQUID_SYMBOL,\r\n    facts: 'Squid chase down their prey and capture them using suckers on their tentacles.',\r\n    trophicLevel: TROPHIC_LEVEL_THREE,\r\n};\r\n\r\n    // Ringed Seal\r\nconst RINGED_SEAL = 'Ringed Seal';\r\nconst RINGED_SEAL_SYMBOL = 'RS';\r\nconst RINGED_SEAL_IMG = '';\r\nconst RINGED_SEAL_DIET = [\r\n    {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n    // {name: SQUID_SYMBOL, trophicLevel: 3, fullName: SQUID},\r\n];\r\nconst RINGED_SEAL_CARD = {\r\n    type: LIFEFORM,\r\n    name: RINGED_SEAL,\r\n    img: RINGED_SEAL_IMG,\r\n    needsIce: 2,\r\n    diet: RINGED_SEAL_DIET,\r\n    symbol: RINGED_SEAL_SYMBOL,\r\n    facts: 'Ringed seals spend much of their lives on sea ice, giving birth and raising pups in dens under the snow.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Bearded Seal\r\nconst BEARDED_SEAL = 'Bearded Seal';\r\nconst BEARDED_SEAL_SYMBOL = 'BS';\r\nconst BEARDED_SEAL_IMG = '';\r\nconst BEARDED_SEAL_DIET = [\r\n    {name: CLAM_SYMBOL, trophicLevel: 2, fullName: CLAM},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n];\r\nconst BEARDED_SEAL_CARD = {\r\n    type: LIFEFORM,\r\n    name: BEARDED_SEAL,\r\n    img: BEARDED_SEAL_IMG,\r\n    needsIce: 2,\r\n    diet: BEARDED_SEAL_DIET,\r\n    symbol: BEARDED_SEAL_SYMBOL,\r\n    facts: 'Bearded seals use prominent whiskers to feel along the soft bottom sediment for prey.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Beluga Whale\r\nconst BELUGA_WHALE = 'Beluga Whale';\r\nconst BELUGA_WHALE_SYMBOL = 'BeW';\r\nconst BELUGA_WHALE_IMG = '';\r\nconst BELUGA_WHALE_DIET = [\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n    {name: SQUID_SYMBOL, trophicLevel: 3, fullName: SQUID},\r\n];\r\nconst BELUGA_WHALE_CARD = {\r\n    type: LIFEFORM,\r\n    name: BELUGA_WHALE,\r\n    img: BELUGA_WHALE_IMG,\r\n    needsIce: 0,\r\n    diet: BELUGA_WHALE_DIET,\r\n    symbol: BELUGA_WHALE_SYMBOL,\r\n    facts: 'Belugas are social creatures that can live, hunt, and migrate in groups of up to several hundred.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Bowhead Whale\r\nconst BOWHEAD_WHALE = 'Bowhead Whale';\r\nconst BOWHEAD_WHALE_SYMBOL = 'BoW';\r\nconst BOWHEAD_WHALE_IMG = '';\r\nconst BOWHEAD_WHALE_DIET = [\r\n    {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD},\r\n];\r\nconst BOWHEAD_WHALE_CARD = {\r\n    type: LIFEFORM,\r\n    name: BOWHEAD_WHALE,\r\n    img: BOWHEAD_WHALE_IMG,\r\n    needsIce: 0,\r\n    diet: BOWHEAD_WHALE_DIET,\r\n    symbol: BOWHEAD_WHALE_SYMBOL,\r\n    facts: 'If trapped under the ice and in need of air, Bowhead whales can break through up to 61 cm of ice.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Narwhal\r\nconst NARWHAL = 'Narwhal';\r\nconst NARWHAL_SYMBOL = 'NW';\r\nconst NARWHAL_IMG = './assets/narwhal.png';\r\nconst NARWHAL_DIET = [\r\n    {name:ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n    {name:SQUID_SYMBOL, trophicLevel: 3, fullName: SQUID},\r\n];\r\nconst NARWHAL_CARD = {\r\n    type: LIFEFORM,\r\n    name: NARWHAL,\r\n    img: NARWHAL_IMG,\r\n    needsIce: 0,\r\n    diet: NARWHAL_DIET,\r\n    symbol: NARWHAL_SYMBOL,\r\n    facts: 'Male Narwhals have a long ivory tusk that spirals counter-clockwise from their head.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Eider Duck\r\nconst EIDER_DUCK = 'Eider Duck';\r\nconst EIDER_DUCK_SYMBOL = 'ED';\r\nconst EIDER_DUCK_IMG = '';\r\nconst EIDER_DUCK_DIET = [\r\n    {name:CLAM_SYMBOL, trophicLevel: 2, fullName: CLAM},\r\n];\r\nconst EIDER_DUCK_CARD = {\r\n    type: LIFEFORM,\r\n    name: EIDER_DUCK,\r\n    img: EIDER_DUCK_IMG,\r\n    needsIce: 0,\r\n    diet: EIDER_DUCK_DIET,\r\n    symbol: EIDER_DUCK_SYMBOL,\r\n    facts: 'Eider down is highly valued as one of the lightest and most effective insulators known.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Walrus\r\nconst WALRUS = 'Walrus';\r\nconst WALRUS_SYMBOL = 'W';\r\nconst WALRUS_IMG = '';\r\nconst WALRUS_DIET = [\r\n    {name:CLAM_SYMBOL, trophicLevel: 2, fullName: CLAM},\r\n];\r\nconst WALRUS_CARD = {\r\n    type: LIFEFORM,\r\n    name: WALRUS,\r\n    img: WALRUS_IMG,\r\n    needsIce: 2,\r\n    diet: WALRUS_DIET,\r\n    symbol: WALRUS_SYMBOL,\r\n    facts: 'Walruses heft their large bodies, up to 1,900 kg, on to sea ice to rest and drift to new feeding grounds.',\r\n    trophicLevel: TROPHIC_LEVEL_FOUR,\r\n};\r\n\r\n    // Human\r\nconst HUMAN = 'Human Being';\r\nconst HUMAN_IMG = './assets/human.png';\r\nconst HUMAN_SYMBOL = 'HB';\r\nconst HUMAN_DIET = [\r\n    {name: EIDER_DUCK_SYMBOL, trophicLevel: 4, fullName: EIDER_DUCK},\r\n    {name: BEARDED_SEAL_SYMBOL, trophicLevel: 4, fullName: BEARDED_SEAL},\r\n    {name: RINGED_SEAL_SYMBOL, trophicLevel: 4, fullName: RINGED_SEAL},\r\n    {name: WALRUS_SYMBOL, trophicLevel: 4, fullName: WALRUS},\r\n    {name: BOWHEAD_WHALE_SYMBOL, trophicLevel: 4, fullName: BOWHEAD_WHALE},\r\n    {name: BELUGA_WHALE_SYMBOL, trophicLevel: 4, fullName: BELUGA_WHALE},\r\n    {name: NARWHAL_SYMBOL, trophicLevel: 4, fullName: NARWHAL},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n];\r\nconst HUMAN_CARD = {\r\n    type: APEX_PREDATOR,\r\n    name: HUMAN,\r\n    img: HUMAN_IMG,\r\n    diet: HUMAN_DIET,\r\n    symbol: HUMAN_SYMBOL,\r\n    resolution: EO_ADD_PREDATOR_TO_PLAY,\r\n    facts: 'Subsistence hunting and fishing play a key role in the way of life for many Arctic Indigenous people.',\r\n    trophicLevel: TROPHIC_LEVEL_FIVE,\r\n};\r\n\r\n    // Polar Bear\r\nconst POLAR_BEAR = 'Polar Bear';\r\nconst POLAR_BEAR_IMG = 'png';\r\nconst POLAR_BEAR_SYMBOL = 'PB';\r\nconst POLAR_BEAR_DIET = [\r\n    {name: BEARDED_SEAL_SYMBOL, trophicLevel: 4, fullName: BEARDED_SEAL},\r\n    {name: RINGED_SEAL_SYMBOL, trophicLevel: 4, fullName: RINGED_SEAL}\r\n];\r\nconst POLAR_BEAR_CARD = {\r\n    type: APEX_PREDATOR,\r\n    name: POLAR_BEAR,\r\n    img: POLAR_BEAR_IMG,\r\n    diet: POLAR_BEAR_DIET,\r\n    symbol: POLAR_BEAR_SYMBOL,\r\n    resolution: EO_ADD_PREDATOR_TO_PLAY,\r\n    facts: 'Polar bears, highly dependent on sea ice, are threatened by global warming due to loss of habitat and prey.',\r\n    trophicLevel: TROPHIC_LEVEL_FIVE,\r\n};\r\n\r\n    // Carbon pullution\r\nconst CARBON_POLLUTION = 'Carbon Pollution';\r\nconst CARBON_POLLUTION_SYMBOL = '-2';\r\nconst CARBON_POLLUTION_CARD_ONE = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Warming',\r\n    blockerText: 'Must melt ice to continue',\r\n    name: CARBON_POLLUTION,\r\n    img: 'e01',\r\n    diet: [],\r\n    resolution: EO_REMOVE_TWO_ICE,\r\n    symbol: CARBON_POLLUTION_SYMBOL,\r\n    iceDestroyed: 0,\r\n    facts: 'When coal, oil, and gas are burned to produce energy and electricity, they release carbon pollution that contributes to global warming.',\r\n};\r\nconst CARBON_POLLUTION_CARD_TWO = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Warming',\r\n    blockerText: 'Must melt ice to continue',\r\n    name: CARBON_POLLUTION,\r\n    img: 'e02',\r\n    diet: [],\r\n    resolution: EO_REMOVE_TWO_ICE,\r\n    symbol: CARBON_POLLUTION_SYMBOL,\r\n    iceDestroyed: 0,\r\n    facts: 'Carbon pollution from cars, trucks, SUV’s, and other passenger vehicles rapidly increases as more people choose to drive.',\r\n};\r\nconst CARBON_POLLUTION_CARD_THREE = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Warming',\r\n    blockerText: 'Must melt ice to continue',\r\n    name: CARBON_POLLUTION,\r\n    img: 'e03',\r\n    diet: [],\r\n    resolution: EO_REMOVE_TWO_ICE,\r\n    symbol: CARBON_POLLUTION_SYMBOL,\r\n    iceDestroyed: 0,\r\n    facts: 'Homes and businesses use large amounts of fossil fuel energy for heating, cooling, and lighting needs.',\r\n};\r\nconst CARBON_POLLUTION_CARD_FOUR = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Warming',\r\n    blockerText: 'Must melt ice to continue',\r\n    name: CARBON_POLLUTION,\r\n    img: 'e04',\r\n    diet: [],\r\n    resolution: EO_REMOVE_TWO_ICE,\r\n    symbol: CARBON_POLLUTION_SYMBOL,\r\n    iceDestroyed: 0,\r\n    facts: 'The use of fossil fuel energy for the production and distribution of consumer goods results in increased carbon pollution.',\r\n};\r\n\r\nconst RAPID_SEA_ICE_LOSS_CARD = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Warming',\r\n    blockerText: 'Must melt ice to continue',\r\n    name: 'Rapid Sea Ice Loss',\r\n    img: 'e04',\r\n    diet: [],\r\n    resolution: EO_REMOVE_THREE_ICE,\r\n    symbol: CARBON_POLLUTION_SYMBOL,\r\n    iceDestroyed: 0,\r\n    facts: 'Unusually warm summer temperatures heat up ocean waters and cause widespread melting of sea ice.',\r\n};\r\n\r\nconst SPECIES_EVENT_SYMBOL = '×';\r\n\r\nconst INVASIVE_KILLER_WHALE_TARGETS = [BEARDED_SEAL, RINGED_SEAL, BELUGA_WHALE, EIDER_DUCK, ARCTIC_COD, NARWHAL]\r\nconst INVASIVE_KILLER_WHALE_DIET = [\r\n    {name: RINGED_SEAL_SYMBOL, trophicLevel: 4, fullName: RINGED_SEAL},\r\n    {name: BEARDED_SEAL_SYMBOL, trophicLevel: 4, fullName: BEARDED_SEAL},\r\n    {name: BELUGA_WHALE_SYMBOL, trophicLevel: 4, fullName: BELUGA_WHALE},\r\n    {name: EIDER_DUCK_SYMBOL, trophicLevel: 4, fullName: EIDER_DUCK},\r\n    {name: NARWHAL_SYMBOL, trophicLevel: 4, fullName: NARWHAL},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n]\r\nconst INVASIVE_KILLER_WHALE_CARD = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Migration',\r\n    blockerText: 'Killer whales must attack to continue',\r\n    name: 'Invasive Killer Whale',\r\n    img: 's01',\r\n    diet: INVASIVE_KILLER_WHALE_DIET,\r\n    symbol: SPECIES_EVENT_SYMBOL,\r\n    resolution: EO_INVASIVE_WHALES,\r\n    validTargets: INVASIVE_KILLER_WHALE_TARGETS,\r\n    facts: 'As sea ice retreats, Orca Whales will move further north, threatening several large marine mammals.\\n To play this card, drop it on a column with any of the following species: ' + INVASIVE_KILLER_WHALE_TARGETS.join (', '),\r\n}\r\n\r\nconst OCEAN_ACIDIFICATION_DIET = [\r\n    {name: ICE_COPEPOD_SYMBOL, trophicLevel: 2, fullName: ICE_COPEPOD},\r\n    {name: KRILL_SYMBOL, trophicLevel: 2, fullName: KRILL},\r\n    {name: CLAM_SYMBOL, trophicLevel: 2, fullName: CLAM},\r\n]\r\nconst OCEAN_ACIDIFICATION_CARD = {\r\n    type: WORLD_EVENT,\r\n    footer: 'Weakens shells & skeletons',\r\n    name: 'Ocean Acidification',\r\n    img: 's02',\r\n    diet: OCEAN_ACIDIFICATION_DIET,\r\n    symbol: SPECIES_EVENT_SYMBOL,\r\n    resolution: EO_OCEAN_ACID,\r\n    validTargets: [ICE_COPEPOD, KRILL, CLAM],\r\n    facts: 'Changes in the ocean\\'s pH level, caused by rising CO2 levels, may weaken or kill clams and some zooplankton.\\n To play this card, drop it into a column with either Ice Copepods, krill, or clams.',\r\n}\r\n\r\nconst OVER_HARVESTING_TARGETS = [WALRUS, BEARDED_SEAL, RINGED_SEAL, BOWHEAD_WHALE, BELUGA_WHALE, EIDER_DUCK, ARCTIC_COD, NARWHAL];\r\n// Design changes in the cards now calls for \"dietary\" icons on the events, this may seem redundant, but that is due to poor planning on my part and the design goals of this app changing as it was being worked on\r\nconst OVER_HARVESTING_DIET = [\r\n    {name: WALRUS_SYMBOL, trophicLevel: 4, fullName: WALRUS},\r\n    {name: RINGED_SEAL_SYMBOL, trophicLevel: 4, fullName: RINGED_SEAL},\r\n    {name: BEARDED_SEAL_SYMBOL, trophicLevel: 4, fullName: BEARDED_SEAL},\r\n    {name: BOWHEAD_WHALE_SYMBOL, trophicLevel: 4, fullName: BOWHEAD_WHALE},\r\n    {name: BELUGA_WHALE_SYMBOL, trophicLevel: 4, fullName: BELUGA_WHALE},\r\n    {name: NARWHAL_SYMBOL, trophicLevel: 4, fullName: NARWHAL},\r\n    {name: EIDER_DUCK_SYMBOL, trophicLevel: 4, fullName: EIDER_DUCK},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n]\r\nconst OVER_HARVESTING_CARD = {\r\n    type: WORLD_EVENT,\r\n    name: 'Overharvesting',\r\n    img: 's03',\r\n    diet: OVER_HARVESTING_DIET,\r\n    symbol: SPECIES_EVENT_SYMBOL,\r\n    resolution: EO_OVER_HARVESTING,\r\n    validTargets: OVER_HARVESTING_TARGETS,\r\n    facts: 'Overharvesting occurs when larger numbers of a species are killed than the population can replace through natural reproduction.\\n To play this card, drop it into a column with any of the following species: ' + OVER_HARVESTING_TARGETS.join (', '),\r\n}\r\n\r\n    // Green Transportation\r\nconst ACTION_SYMBOL = '+1 ice'\r\nconst GREEN_TRANSPORTATION = 'Green Transportation';\r\nconst GREEN_TRANSPORTATION_IMG = '';\r\nconst GREEN_TRANSPORTATION_CARD = {\r\n    type: ACTION,\r\n    name: GREEN_TRANSPORTATION,\r\n    img: GREEN_TRANSPORTATION_IMG,\r\n    footer: 'Action',\r\n    diet: [],\r\n    symbol: ACTION_SYMBOL,\r\n    resolution: EO_ADD_ONE_ICE,\r\n    facts: 'Walking, biking, carpooling and using public transportation help combat global warming by cutting down on carbon pollution.'\r\n};\r\n\r\n    // Alternate Energy\r\nconst ALTERNATE_ENERGY = 'Alternate Energy';\r\nconst ALTERNATE_ENERGY_IMG = '';\r\nconst ALTERNATE_ENERGY_CARD = {\r\n    type: ACTION,\r\n    name: ALTERNATE_ENERGY,\r\n    img: ALTERNATE_ENERGY_IMG,\r\n    footer: 'Action',\r\n    diet: [],\r\n    symbol: ACTION_SYMBOL,\r\n    resolution: EO_ADD_ONE_ICE,\r\n    facts: 'Solar, wind, geothermal, and nuclear energy sources are used to produce clean energy and electricity that helps prevent global warming.',\r\n};\r\n\r\n    // Energy Efficiency\r\nconst ENERGY_EFFICIENCY = 'Energy Efficiency';\r\nconst ENERGY_EFFICIENCY_IMG = '';\r\nconst ENERGY_EFFICIENCY_CARD = {\r\n    type: ACTION,\r\n    name: ENERGY_EFFICIENCY,\r\n    img: ENERGY_EFFICIENCY_IMG,\r\n    footer: 'Action',\r\n    diet: [],\r\n    symbol: ACTION_SYMBOL,\r\n    resolution: EO_ADD_ONE_ICE,\r\n    facts: 'Homes and businesses use less energy when they improve building insulation and use energy-efficient appliances and products.',\r\n};\r\n\r\n    // Sea Ice Restoration\r\nconst SEA_ICE_RESTORATION = 'Carbon Capture and Sequestration';\r\nconst SEA_ICE_RESTORATION_IMG = '';\r\nconst SEA_ICE_RESTORATION_CARD = {\r\n    type: ACTION,\r\n    name: SEA_ICE_RESTORATION,\r\n    img: SEA_ICE_RESTORATION_IMG,\r\n    footer: 'Action',\r\n    diet: [],\r\n    symbol: '+2 ice',\r\n    resolution: EO_ADD_TWO_ICE,\r\n    facts: 'Trapping and storing carbon pollution reduces global warming, allowing for increased amounts of sea ice.',\r\n};\r\n\r\n// const PROTECT_A_SPECIES = 'Protect Species';\r\nconst PROTECT_A_SPECIES = 'Protect From Overharvesting';\r\nconst PROTECT_A_SPECIES_IMG = './assets/protect-a-species.png';\r\nconst PROTECT_A_SPECIES_DIET = [\r\n    {name: WALRUS_SYMBOL, trophicLevel: 4, fullName: WALRUS},\r\n    {name: RINGED_SEAL_SYMBOL, trophicLevel: 4, fullName: RINGED_SEAL},\r\n    {name: BEARDED_SEAL_SYMBOL, trophicLevel: 4, fullName: BEARDED_SEAL},\r\n    {name: BOWHEAD_WHALE_SYMBOL, trophicLevel: 4, fullName: BOWHEAD_WHALE},\r\n    {name: BELUGA_WHALE_SYMBOL, trophicLevel: 4, fullName: BELUGA_WHALE},\r\n    {name: NARWHAL_SYMBOL, trophicLevel: 4, fullName: NARWHAL},\r\n    {name: EIDER_DUCK_SYMBOL, trophicLevel: 4, fullName: EIDER_DUCK},\r\n    {name: ARCTIC_COD_SYMBOL, trophicLevel: 3, fullName: ARCTIC_COD},\r\n]\r\nconst PROTECT_A_SPECIES_CARD = {\r\n    type: ACTION,\r\n    name: PROTECT_A_SPECIES,\r\n    img: PROTECT_A_SPECIES_IMG,\r\n    resolution: EO_PROTECT_SPECIES,\r\n    symbol: '',\r\n    diet: PROTECT_A_SPECIES_DIET,\r\n    validTargets: [\r\n        ARCTIC_COD, SQUID, BOWHEAD_WHALE, BELUGA_WHALE, NARWHAL, RINGED_SEAL, BEARDED_SEAL, EIDER_DUCK, WALRUS\r\n    ],\r\n    facts: 'Legislation manages hunting and fishing using community- and ecosystem-based management.',\r\n}\r\n\r\nexport default {\r\n\r\n    // Stuff that appears on the landing screen\r\n    loadingScreenTextTitle: 'Sustain as many species as possible!',\r\n    loadingScreenTextBody: `<div>Strategically manage your sea ice</div>\r\n    <div>to support Arctic marine life</div>`,\r\n\r\n    types: {\r\n        lifeform: LIFEFORM,\r\n        apexPredator: APEX_PREDATOR,\r\n        worldEvent: WORLD_EVENT,\r\n        action: ACTION,\r\n    },\r\n    resolutions: {\r\n        addIce: EO_ADD_ONE_ICE,\r\n        iceRestoration: EO_ADD_TWO_ICE,\r\n        removeIce: EO_REMOVE_TWO_ICE,\r\n        rapidSeaIceLoss: EO_REMOVE_THREE_ICE,\r\n        protectSpecies: EO_PROTECT_SPECIES,\r\n        removeSpecies: EO_REMOVE_SPECIES,\r\n        oceanAcid: EO_OCEAN_ACID,\r\n        overHarvesting: EO_OVER_HARVESTING,\r\n        invasiveWhales: EO_INVASIVE_WHALES,\r\n    },\r\n    gameModes: ['normal'],\r\n    // This layout option broke once styling was implemented\r\n    layout: LAYOUT_DECK_ON_LEFT,\r\n\r\n    // Static reference to card information for checking what card is what during run-time\r\n    cards: {\r\n        ice: ICE_CARD,\r\n        carbonPollution: CARBON_POLLUTION_CARD_ONE,\r\n        protectASpecies: PROTECT_A_SPECIES_CARD,\r\n        overHarvesting: OVER_HARVESTING_CARD,\r\n        invasiveKillerWhale: INVASIVE_KILLER_WHALE_CARD,\r\n        oceanAcidification: OCEAN_ACIDIFICATION_CARD,\r\n        phytoPlankton: PHYTO_PLANKTON_CARD,\r\n        iceAlgea: ICE_ALGEA_CARD,\r\n\r\n        rapidSeaIceLoss: RAPID_SEA_ICE_LOSS_CARD,\r\n        seaIceRestoration: SEA_ICE_RESTORATION_CARD,\r\n    },\r\n    initialPlayAreas: [\r\n        {\r\n            iceColumn1: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n                Helper.clone (ARCTIC_COD_CARD),\r\n            ],\r\n            iceColumn2: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn3: [\r\n                // Helper.clone (ICE_ALGEA_CARD),\r\n                // Helper.clone (ICE_COPEPOD_CARD),\r\n\r\n            ],\r\n            iceColumn4: [],\r\n            iceColumn5: [],\r\n            iceColumn6: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n            ],\r\n            iceColumn7: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n            ],\r\n        },\r\n\r\n        {\r\n            iceColumn1: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn2: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn3: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn4: [],\r\n            iceColumn5: [],\r\n            iceColumn6: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n            ],\r\n            iceColumn7: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n            ],\r\n        },\r\n        {\r\n            iceColumn1: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn2: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn3: [\r\n                // Helper.clone (CLAM_CARD),\r\n            ],\r\n            iceColumn4: [],\r\n            iceColumn5: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n            ],\r\n            iceColumn6: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n\r\n            ],\r\n            iceColumn7: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n\r\n            ],\r\n        },\r\n        {\r\n            iceColumn1: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n                Helper.clone (ARCTIC_COD_CARD),\r\n            ],\r\n            iceColumn2: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n            ],\r\n            iceColumn3: [\r\n                // Helper.clone (CLAM_CARD),\r\n            ],\r\n            iceColumn4: [],\r\n            iceColumn5: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n            ],\r\n            iceColumn6: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (CLAM_CARD),\r\n            ],\r\n            iceColumn7: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n\r\n            ],\r\n        },\r\n        {\r\n            iceColumn1: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n                Helper.clone (ARCTIC_COD_CARD),\r\n            ],\r\n            iceColumn2: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n                Helper.clone (ARCTIC_COD_CARD),\r\n            ],\r\n            iceColumn3: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n                Helper.clone (ICE_COPEPOD_CARD),\r\n            ],\r\n            iceColumn4: [\r\n                Helper.clone (ICE_ALGEA_CARD),\r\n            ],\r\n            iceColumn5: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n            ],\r\n            iceColumn6: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n\r\n            ],\r\n            iceColumn7: [\r\n                Helper.clone (PHYTO_PLANKTON_CARD),\r\n                Helper.clone (KRILL_CARD),\r\n\r\n            ],\r\n        },\r\n\r\n    ],\r\n    decks: {\r\n        // Deck is shuffled at playtime\r\n        normal: [\r\n            // species\r\n                // This dummy card needs to be the first card in every deck\r\n            Helper.clone (DUMMY_INITIALIZER_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (ICE_ALGEA_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (PHYTO_PLANKTON_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (KRILL_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (CLAM_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ICE_COPEPOD_CARD),\r\n            Helper.clone (ARCTIC_COD_CARD),\r\n            Helper.clone (ARCTIC_COD_CARD),\r\n            Helper.clone (ARCTIC_COD_CARD),\r\n            Helper.clone (ARCTIC_COD_CARD),\r\n            Helper.clone (SQUID_CARD),\r\n            Helper.clone (SQUID_CARD),\r\n            Helper.clone (SQUID_CARD),\r\n            Helper.clone (SQUID_CARD),\r\n            Helper.clone (BELUGA_WHALE_CARD),\r\n            Helper.clone (BELUGA_WHALE_CARD),\r\n            Helper.clone (RINGED_SEAL_CARD),\r\n            Helper.clone (RINGED_SEAL_CARD),\r\n            Helper.clone (BEARDED_SEAL_CARD),\r\n            Helper.clone (BEARDED_SEAL_CARD),\r\n            Helper.clone (BOWHEAD_WHALE_CARD),\r\n            Helper.clone (BOWHEAD_WHALE_CARD),\r\n            Helper.clone (NARWHAL_CARD),\r\n            Helper.clone (NARWHAL_CARD),\r\n            Helper.clone (EIDER_DUCK_CARD),\r\n            Helper.clone (EIDER_DUCK_CARD),\r\n            Helper.clone (WALRUS_CARD),\r\n            Helper.clone (WALRUS_CARD),\r\n\r\n            // Events\r\n            Helper.clone (CARBON_POLLUTION_CARD_ONE),\r\n            Helper.clone (CARBON_POLLUTION_CARD_THREE),\r\n            Helper.clone (CARBON_POLLUTION_CARD_TWO),\r\n            Helper.clone (CARBON_POLLUTION_CARD_FOUR),\r\n\r\n            Helper.clone (INVASIVE_KILLER_WHALE_CARD),\r\n            Helper.clone (OCEAN_ACIDIFICATION_CARD),\r\n            Helper.clone (OVER_HARVESTING_CARD),\r\n\r\n            // Actions\r\n            Helper.clone (PROTECT_A_SPECIES_CARD),\r\n            Helper.clone (GREEN_TRANSPORTATION_CARD),\r\n            Helper.clone (ALTERNATE_ENERGY_CARD),\r\n            Helper.clone (ENERGY_EFFICIENCY_CARD),\r\n\r\n            // Predators\r\n            // App only supports up to 4 apex predator cards\r\n            Helper.clone (HUMAN_CARD),\r\n            Helper.clone (HUMAN_CARD),\r\n            Helper.clone (POLAR_BEAR_CARD),\r\n            Helper.clone (POLAR_BEAR_CARD),\r\n        ],\r\n    }\r\n}\r\n","import React, { Component } from 'react'\r\n\r\n// import './Card.css';\r\nimport './Card-Structure.css';\r\nimport './Card.css';\r\n\r\nimport Config from './Config';\r\nimport Helper from './Helper';\r\n\r\nexport default class Card extends Component {\r\n    constructor () {\r\n        super ();\r\n\r\n        this.onMouseDown = this.onMouseDown.bind (this);\r\n        this.onDoubleClick = this.onDoubleClick.bind (this);\r\n    }\r\n\r\n    onMouseDown (event) {\r\n        if (!this.props.onMouseDown) { return; }\r\n        this.props.onMouseDown ( {event, card: this.props} )\r\n    }\r\n\r\n    onDoubleClick (event) {\r\n        if (!this.props.onDoubleClick) { return; }\r\n        this.props.onDoubleClick ({ event, card: this.props })\r\n    }\r\n\r\n    createPreyIcon (data, index) {\r\n        let className = 'card-food' + ' ' + 't' + data.trophicLevel\r\n        return (\r\n            <div className={className} key={index}>\r\n                <span>{data.name}</span>\r\n            </div>\r\n        )\r\n    }\r\n\r\n    getOpacity () {\r\n        let opacity = 1;\r\n\r\n        if ('opacity' in this.props) { opacity = this.props.opacity }\r\n\r\n        return opacity;\r\n    }\r\n\r\n    getApexPredatorDom () {\r\n        return (\r\n            <section className=\"card-wrapper\">\r\n                <header>\r\n                    {this.props.isProtected === true &&\r\n                        <div className=\"card-protection\"></div>\r\n                    }\r\n                </header>\r\n                <div className=\"card-title\">\r\n                    <span>\r\n                        {this.props.name}\r\n                    </span>\r\n                </div>\r\n                <div className=\"card-image\"> </div>\r\n                <footer>\r\n                    { this.props.diet.map (this.createPreyIcon) }\r\n                </footer>\r\n            </section>\r\n        )\r\n    }\r\n\r\n    getSpeciesDom () {\r\n        let wrapperClassName = 'card-wrapper';\r\n        if (this.props.isScared === true) {\r\n            wrapperClassName += ' ' + 'scared';\r\n        }\r\n\r\n        let protectedSpecies = (this.props.protectedSpeciesName === this.props.name)\r\n\r\n        let name = this.props.name;\r\n        let needsIce = this.props.needsIce;\r\n\r\n        switch (name) {\r\n            case Config.cards.phytoPlankton.name:\r\n                name = 'Phyto-plankton';\r\n                break;\r\n            case Config.cards.iceAlgea.name:\r\n                needsIce = 0;\r\n                break;\r\n        }\r\n\r\n        let opacity = this.getOpacity ();\r\n\r\n        let style = { opacity }\r\n\r\n        return (\r\n            <section style={style} className={wrapperClassName}>\r\n                <header style={style}>\r\n                    {protectedSpecies === true &&\r\n                        <div style={style} className=\"card-protection\"></div>\r\n                    }\r\n                    <div style={style} className=\"card-symbol\">\r\n                        <span style={style}>{this.props.symbol}</span>\r\n                    </div>\r\n                    { needsIce > 0 &&\r\n                        <div style={style} className=\"card-ice-value\">\r\n                            <span>{needsIce}</span>\r\n                        </div>\r\n                    }\r\n                </header>\r\n                <div style={style} className=\"card-title\">\r\n                    <span style={style}>\r\n                        {name}\r\n                    </span>\r\n                </div>\r\n                <div style={style} className=\"card-image\"> </div>\r\n                <footer style={style}>\r\n                    { this.props.diet.map (this.createPreyIcon) }\r\n                </footer>\r\n            </section>\r\n        )\r\n    }\r\n\r\n    getWorldEventDom () {\r\n        let symbol = this.props.symbol\r\n\r\n        // if (symbol === '-2') { symbol = -2 + this.props.iceDestroyed }\r\n        if (symbol === '-2') { symbol = '-2 ice' }\r\n        if (this.props.name === Config.cards.rapidSeaIceLoss.name) { symbol = '-3 ice' }\r\n\r\n        let footer = this.props.footer;\r\n\r\n        if (!footer) { footer = 'Event' }\r\n\r\n        if (this.props.name === Config.cards.overHarvesting.name) { footer = '' }\r\n\r\n        let validTargets = [];\r\n\r\n        if (\r\n            this.props.validTargets &&\r\n            this.props.validTargets.length &&\r\n            this.props.diet &&\r\n            this.props.diet.length\r\n        ) {\r\n            validTargets = this.props.diet\r\n        }\r\n\r\n        let opacity = this.getOpacity ();\r\n\r\n        let style = { opacity }\r\n\r\n        return (\r\n            <section style={style}>\r\n                <header style={style}>\r\n                    {this.props.isProtected === true &&\r\n                        <div style={style} className=\"card-protection\"></div>\r\n                    }\r\n                    <div style={style} className=\"card-symbol\">\r\n                        <span style={style}>{ symbol }</span>\r\n                    </div>\r\n                </header>\r\n                <div style={style} className=\"card-title\">\r\n                    <span style={style}>{this.props.name}</span>\r\n                </div>\r\n                <div style={style} className=\"card-image\"></div>\r\n                <footer>\r\n                    { validTargets.map (this.createPreyIcon) }\r\n                    { this.props.type === Config.types.action &&\r\n                        <div className=\"card-badge\">2</div>\r\n                    }\r\n                    <div className=\"card-type\">\r\n                        <span>{ footer }</span>\r\n                    </div>\r\n                </footer>\r\n            </section>\r\n        )\r\n    }\r\n\r\n    getActionDom () {\r\n        let opacity = this.getOpacity ();\r\n\r\n        let style = { opacity }\r\n\r\n        let validTargets = [];\r\n\r\n        let footer = this.props.footer;\r\n\r\n        if (this.props.validTargets &&\r\n            this.props.validTargets.length &&\r\n            this.props.diet &&\r\n            this.props.diet.length)\r\n        {\r\n            validTargets = this.props.diet\r\n        }\r\n\r\n        // console.clear ()\r\n        // console.log (this.props.name, 'targets:', validTargets)\r\n        let otherTitle = false;\r\n\r\n        if (this.props.name !== Config.cards.protectASpecies.name) {\r\n            otherTitle = 'Reduce Carbon Emissions';\r\n            footer = 'Restore 1 Sea Ice';\r\n        }\r\n\r\n        if (this.props.name === Config.cards.seaIceRestoration.name) {\r\n            otherTitle = 'Remove Atmospheric Carbon'\r\n            footer = 'Restore 2 Sea Ice';\r\n        }\r\n\r\n        return (\r\n            <section style={style}>\r\n                <header style={style}>\r\n                    {this.props.isProtected === true &&\r\n                        <div style={style} className=\"card-protection\"></div>\r\n                    }\r\n                    <div style={style} className=\"card-symbol\">\r\n                        { this.props.symbol }\r\n                    </div>\r\n                </header>\r\n                <div style={style} className=\"card-title\">\r\n                    {otherTitle &&\r\n                        <span>{otherTitle}</span>\r\n                    }\r\n                    <span style={style}>{this.props.name}</span>\r\n                </div>\r\n                <div style={style} className=\"card-image\"></div>\r\n                <div style={style} className=\"\">\r\n                    <div style={style}></div>\r\n                    <div style={style}></div>\r\n                    <div style={style}></div>\r\n                    <div style={style}></div>\r\n                </div>\r\n                <footer>\r\n                    { validTargets.map (this.createPreyIcon) }\r\n                    { this.props.type === Config.types.action &&\r\n                        <div className=\"card-badge\">2 pts</div>\r\n                    }\r\n                    <div className=\"card-type\">\r\n                        <span>{ footer }</span>\r\n                    </div>\r\n                </footer>\r\n            </section>\r\n        )\r\n    }\r\n\r\n    render () {\r\n        let cardDom, className;\r\n\r\n        if (!this.props.isFaceDown) {\r\n            let type = this.props.type;\r\n            let name = this.props.name;\r\n\r\n            if (!type) { type = '' }\r\n            if (!name) { name = '' }\r\n\r\n            className = 'card-container ';\r\n            className += Helper.replaceAll (type, ' ', '-').toLowerCase ();\r\n            className += ' ';\r\n            className += Helper.replaceAll (name, ' ', '-').toLowerCase ();\r\n            // className = 'card-container' + ' ' + type.replaceAll (' ', '-').toLowerCase () + ' ' + name.toLowerCase ().replaceAll (' ', '-');\r\n\r\n            if (this.props.extraClassNames) {\r\n                className += ' ' + this.props.extraClassNames;\r\n            }\r\n\r\n            if (this.props.name === Config.cards.carbonPollution.name) {\r\n                className += ' ' + this.props.img;\r\n            }\r\n\r\n            switch (this.props.type) {\r\n                case Config.types.apexPredator:\r\n                    className += ' pm'\r\n                    cardDom = this.getApexPredatorDom ();\r\n                    break;\r\n                case Config.types.lifeform:\r\n                    cardDom = this.getSpeciesDom ();\r\n                    break;\r\n                case Config.types.worldEvent:\r\n                    className += ' ' + this.props.img;\r\n                    cardDom = this.getWorldEventDom ();\r\n                    break;\r\n                case Config.types.action:\r\n                    cardDom = this.getActionDom ();\r\n                    break;\r\n            }\r\n\r\n        }\r\n        else {\r\n            className = 'facedown'\r\n            cardDom = (\r\n                <div className=\"facedown-container\">\r\n                    <div className=\"gradient\"> </div>\r\n                    <div className=\"image\"> </div>\r\n                </div>\r\n            )\r\n        }\r\n\r\n        let style = {\r\n            position: 'absolute',\r\n            transform: 'translateX(' + this.props.position.x + 'px) translateY(' + this.props.position.y + 'px)',\r\n            zIndex: this.props.zIndex,\r\n            opacity: 1\r\n        }\r\n\r\n        if ('opacity ' in this.props) {\r\n            style.opacity = this.props.opacity;\r\n        }\r\n\r\n        if (this.props.type === Config.cards.ice.type) {\r\n            delete style.position;\r\n            delete style.transform;\r\n        }\r\n\r\n        return (\r\n            <div\r\n                className={className}\r\n                style={style}\r\n                onMouseDown={this.onMouseDown}\r\n                onDblClick={this.onDoubleClick}\r\n                id={this.props.id}\r\n            >\r\n                {cardDom}\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","// This probably should manage cards, but I'm not familiar enough with react\r\n// to set this up that way\r\nimport React, { Component } from 'react'\r\nimport './Deck.css';\r\nimport Card from './Card';\r\n\r\nexport default class Deck extends Component {\r\n    constructor () {\r\n        super ();\r\n\r\n        this.onClick = this.onClick.bind (this);\r\n        this.createCardElement = this.createCardElement.bind (this);\r\n    }\r\n\r\n    onClick (event) {\r\n        // console.log ('deck clicked')\r\n        if (this.props.onClick) {\r\n            this.props.onClick (event);\r\n        }\r\n    }\r\n\r\n    // componentDidMount () {\r\n    //     console.log (this.props.children)\r\n    // }\r\n\r\n    createCardElement (data, index) {\r\n        if (data === null) { return (<div></div>) }\r\n        if (!data.position) { data.position = {x: 0, y: 0} }\r\n\r\n        return (\r\n            <Card\r\n                key={this.props.name + index}\r\n                id={data.id}\r\n                name={data.name}\r\n                img={data.img}\r\n                zIndex={data.zIndex}\r\n                isActive={data.isActive}\r\n                position={data.position}\r\n                isFaceDown={data.isFaceDown}\r\n                isDiscarded={data.isDiscarded}\r\n                isPlacedInColumn={data.isPlacedInColumn}\r\n                isProtected={data.isProtected}\r\n                type={data.type}\r\n                index={index}\r\n                diet={data.diet}\r\n                symbol={data.symbol}\r\n                iceDestroyed={this.props.iceDestroyed}\r\n                facts={data.facts}\r\n                trophicLevel={data.trophicLevel}\r\n                needsIce={data.needsIce}\r\n                validTargets={data.validTargets}\r\n                footer={data.footer}\r\n                blockerText={data.blockerText}\r\n                validTargets={data.validTargets}\r\n\r\n                onMouseDown={this.props.onMouseDownOnCard}\r\n                protectedSpeciesName={this.props.protectedSpeciesName}\r\n            />\r\n        )\r\n    }\r\n\r\n    render () {\r\n        let className = 'deck' + ' ' + this.props.name;\r\n\r\n        if (this.props.type === 'ice deck') { className = 'ice-deck' }\r\n\r\n        // console.log (this.props.name, this.props.children)\r\n\r\n        return (\r\n            <div className={className}>\r\n                <div className=\"header-bar\">\r\n                    {this.props.name}\r\n                </div>\r\n                <div className=\"event-holder\"  onClick={this.onClick}>\r\n                    {this.props.children.map (this.createCardElement)}\r\n                </div>\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","import React, { Component } from 'react'\r\nimport './ScoreKeeper.css';\r\n\r\nexport default class ScoreKeeper extends Component{\r\n    constructor () {\r\n        super ();\r\n\r\n        this.state = {\r\n            lastScore: 0\r\n        }\r\n    }\r\n    animateScore () {\r\n        this.setState ({ lastScore: this.props.score });\r\n    }\r\n\r\n    render () {\r\n        let className = 'score-keeper';\r\n\r\n        if (this.props.type === 'total') { className += ' total' }\r\n\r\n        return (\r\n            <div className={className}>\r\n                <div className=\"label\">\r\n                    { this.props.label }\r\n                </div>\r\n                <div className=\"score\">\r\n                    { this.props.score }\r\n                </div>\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","// Creates a column that cards can be dropped into.\r\n// Maybe holds a compare function for its top most child and a card that is being\r\n// dropped into it\r\n// Responsible for organizing cards into a neat column\r\n\r\nimport React, { Component } from 'react';\r\nimport Card from './Card';\r\nimport Deck from './Deck';\r\n\r\nimport './Card-Structure.css';\r\nimport './Card-Top-Level.css';\r\nimport './IceColumn.css';\r\n\r\nexport default class IceColumn extends Component {\r\n    constructor () {\r\n        super ();\r\n\r\n        this.state = {\r\n            ice: 'ice'\r\n        }\r\n\r\n        this.createCardElement = this.createCardElement.bind (this);\r\n    }\r\n\r\n    createCardElement (data, index) {\r\n        if (data === null) { return }\r\n        if (!data.key) { data.key = Math.random ()*1000 }\r\n        if (!data.position) { data.position = {x: 0, y: 0} }\r\n        // if (!data.key || !data.position) {\r\n        //     return (<div key={index}></div>)\r\n        // }\r\n\r\n        return (\r\n            <Card\r\n                key={index}\r\n                id={data.id}\r\n                name={data.name}\r\n                img={data.img}\r\n                zIndex={data.zIndex}\r\n                isActive={data.isActive}\r\n                position={data.position}\r\n                isFaceDown={data.isFaceDown}\r\n                isDiscarded={data.isDiscarded}\r\n                isPlacedInColumn={data.isPlacedInColumn}\r\n                isProtected={data.isProtected}\r\n                type={data.type}\r\n                index={index}\r\n                diet={data.diet}\r\n                symbol={data.symbol}\r\n                iceDestroyed={this.props.iceDestroyed}\r\n                facts={data.facts}\r\n                trophicLevel={data.trophicLevel}\r\n                needsIce={data.needsIce}\r\n                validTargets={data.validTargets}\r\n                footer={data.footer}\r\n                blockerText={data.blockerText}\r\n                validTargets={data.validTargets}\r\n                isScared={data.isScared}\r\n\r\n                onMouseDown={this.props.onMouseDownOnCard}\r\n                protectedSpeciesName={this.props.protectedSpeciesName}\r\n            />\r\n        )\r\n    }\r\n\r\n    render () {\r\n        let className = 'card-container top-level ';\r\n        className += this.props.ice ? 'ice' : 'ice-melted';\r\n\r\n        return (\r\n            <div className=\"ice-column\" id={this.props.id}>\r\n                <div className={className}>\r\n                    <section className=\"card-wrapper\"></section>\r\n                </div>\r\n                <div className=\"column\">\r\n                    {this.props.children.map ( this.createCardElement )}\r\n                </div>\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","//Holds an apex predator card\r\nimport React, { Component } from 'react';\r\nimport Card from './Card';\r\n\r\nimport './ApexCardSlot.css'\r\nimport './Card-Structure.css';\r\nimport './Card.css';\r\n\r\nexport default class ApexCardSlot extends Component {\r\n    constructor () {\r\n        super();\r\n\r\n        this.createCardElement = this.createCardElement.bind (this);\r\n        this.createFoodChainCardElement = this.createFoodChainCardElement.bind (this);\r\n    }\r\n\r\n    createCardElement (data, index) {\r\n        if (!data.key || !data.position) {\r\n            return (<div key={index}></div>)\r\n        }\r\n\r\n        let isFed = (this.props.givenFoodChain.length > 0)\r\n\r\n        let extraClassNames = '';\r\n\r\n        if (isFed) { extraClassNames = 'locked' }\r\n\r\n        return (\r\n            <Card\r\n                key={this.props.name + index.toString () + Math.random ().toString ()}\r\n                id={data.id}\r\n                name={data.name}\r\n                img={data.img}\r\n                zIndex={data.zIndex}\r\n                isActive={data.isActive}\r\n                position={data.position}\r\n                isFaceDown={data.isFaceDown}\r\n                isDiscarded={data.isDiscarded}\r\n                isPlacedInColumn={data.isPlacedInColumn}\r\n                isProtected={data.isProtected}\r\n                type={data.type}\r\n                index={index}\r\n                diet={data.diet}\r\n                symbol={data.symbol}\r\n                iceDestroyed={this.props.iceDestroyed}\r\n                facts={data.facts}\r\n                trophicLevel={data.trophicLevel}\r\n                needsIce={data.needsIce}\r\n\r\n                onMouseDown={this.props.onMouseDownOnCard}\r\n                extraClassNames={extraClassNames}\r\n            />\r\n        )\r\n    }\r\n\r\n    createFoodChainCardElement (data, index) {\r\n        let position = {\r\n            x: -55,\r\n            y: 10 * index + 40\r\n        }\r\n\r\n        data.position.y = position.y\r\n\r\n        let zIndex = 100 + index\r\n        let isFed = (this.props.givenFoodChain.length > 0)\r\n\r\n        let extraClassNames = '';\r\n\r\n        if (isFed) {\r\n            extraClassNames = 'locked'\r\n        }\r\n        return (\r\n            <Card\r\n                key={this.props.name + index.toString () + Math.random ().toString ()}\r\n                id={data.id}\r\n                name={data.name}\r\n                img={data.img}\r\n                zIndex={zIndex}\r\n                isActive={data.isActive}\r\n                position={data.position}\r\n                isFaceDown={data.isFaceDown}\r\n                isDiscarded={data.isDiscarded}\r\n                isPlacedInColumn={data.isPlacedInColumn}\r\n                isProtected={data.isProtected}\r\n                type={data.type}\r\n                index={index}\r\n                diet={data.diet}\r\n                symbol={data.symbol}\r\n                iceDestroyed={this.props.iceDestroyed}\r\n                facts={data.facts}\r\n                trophicLevel={data.trophicLevel}\r\n                needsIce={data.needsIce}\r\n\r\n                onMouseDown={() => {}}\r\n                extraClassNames={extraClassNames}\r\n            />\r\n        )\r\n    }\r\n\r\n    render () {\r\n        let children = this.props.children;\r\n\r\n        if (!children) { children = [] }\r\n        if (!children.map) { children = [children] }\r\n\r\n        return (\r\n            <div id={this.props.id} className=\"apex-card-slot\">\r\n                { children.map (this.createCardElement) }\r\n                { this.props.givenFoodChain.map (this.createFoodChainCardElement) }\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","import React, { Component } from 'react';\r\n\r\nimport Config from './Config';\r\nimport './Modal-Structure.css';\r\n\r\nconst CLOSE_BUTTON_SYMBOL = 'x'\r\n\r\nexport default class CardModal extends Component {\r\n\r\n    createPreyIcon (data, index) {\r\n        let className = 'card-food' + ' ' + 't' + data.trophicLevel\r\n        return (\r\n            <div className={className} key={index}>\r\n                <span>{data.name}</span>\r\n            </div>\r\n        )\r\n    }\r\n\r\n    createDietString () {\r\n        let card = this.props.card;\r\n        let dietString = '';\r\n\r\n        card.diet.forEach ((diet, index) => {\r\n            dietString += diet.fullName\r\n\r\n            if (card.diet [index + 1]) {\r\n                dietString += ', '\r\n            }\r\n        })\r\n\r\n        return dietString\r\n    }\r\n\r\n    createValidTargetString () {\r\n        let card = this.props.card;\r\n        let dietString = '';\r\n\r\n        Config.cards.protectASpecies.validTargets.forEach ((target, index) => {\r\n            dietString += target\r\n\r\n            if (Config.cards.protectASpecies.validTargets [index + 1]) {\r\n                dietString += ', '\r\n            }\r\n        })\r\n\r\n        return dietString\r\n    }\r\n\r\n    getActionDom (isProtectSpeciesCard) {\r\n        let card = this.props.card;\r\n        let title = 'Action Card';\r\n        let type = 'Action'\r\n        let className = 'card-container' + ' ' + card.type.replaceAll (' ', '-').toLowerCase () + ' ' + card.name.toLowerCase ().replaceAll (' ', '-');\r\n        let symbol = card.symbol;\r\n\r\n        // if (symbol === '-2') { symbol = 'x' }\r\n        if (symbol === '-2') { symbol = '-2 ice' }\r\n        if (card.name === Config.cards.rapidSeaIceLoss.name) { symbol = '-3 ice' }\r\n\r\n        let cardInfoTitle, cardInfoText;\r\n\r\n        if (!isProtectSpeciesCard) {\r\n            cardInfoTitle = 'Ice Restored';\r\n            cardInfoText = ' Select one Sea Card to convert to an Ice Card.';\r\n        }\r\n        else {\r\n            cardInfoTitle = 'Species Protection';\r\n            cardInfoText = ' Select one Species Card to Protect from Over Harvesting.';\r\n        }\r\n\r\n        let detailsTitle = 'Action Details';\r\n        let detailsText = card.facts;\r\n\r\n        let pointsTitle = 'Action Points';\r\n        let pointsText = 'Humans can take helpful actions to protect and conserve the Arctic ecosystem. Each Action card is worth 2 Action Points.'\r\n\r\n        if (card.type === Config.types.worldEvent) {\r\n            title = 'Event Card';\r\n            type = 'Event'\r\n            className += ' ' + this.props.img;\r\n            cardInfoTitle = 'Ice Destroyed'\r\n            cardInfoText = ' Select two Ice Cards to convert to Sea Cards by dragging and dropping this card twice.';\r\n            detailsTitle = 'Event Details';\r\n            pointsTitle = 'Event Points';\r\n            pointsText = '';\r\n\r\n            if (card.name === Config.cards.carbonPollution.name) {\r\n                pointsText = 'Harmful events such as carbon pollution do not award points and the destruction of ice costs points.'\r\n                className += ' ' + card.img\r\n            }\r\n            else if (card.name === Config.cards.invasiveKillerWhale.name) {\r\n                className += ' s01'\r\n                cardInfoTitle = 'Hunted Animal'\r\n                cardInfoText = 'Select a column of animals to be targeted by invasive killer whales. Species protection does not help against natural events like this one.'\r\n            }\r\n            else if (card.name === Config.cards.oceanAcidification.name) {\r\n                className += ' s02'\r\n                cardInfoTitle = 'Uninhabitable Waters'\r\n                cardInfoText = 'Select a column of animals to be targeted by ocean acidification. Species protection does not help against events like this one.'\r\n            }\r\n            else if (card.name === Config.cards.overHarvesting.name) {\r\n                className += ' s03'\r\n                cardInfoTitle = 'Over Harvested Animal'\r\n                cardInfoText = 'Select a column of animals to be targeted by over-harvesting.'\r\n            }\r\n        }\r\n\r\n        let footer = card.footer;\r\n\r\n        if (!footer) { footer = type }\r\n\r\n        let validTargets = [];\r\n\r\n        if (card.validTargets &&\r\n            card.validTargets.length &&\r\n            card.diet &&\r\n            card.diet.length)\r\n        {\r\n            validTargets = card.diet\r\n        }\r\n\r\n        let actionValidTargetListText = ''\r\n        if (card.name === Config.cards.protectASpecies.name) {\r\n            actionValidTargetListText = this.createValidTargetString ();\r\n            footer = '';\r\n        }\r\n\r\n        let otherTitle = false\r\n        if (card.name !== Config.cards.protectASpecies.name && card.type ===Config.types.action) {\r\n            otherTitle = 'Reduce Carbon Emissions';\r\n            footer = 'Restore 1 Sea Ice';\r\n        }\r\n\r\n        let bonusClass = '';\r\n        if (card.name === Config.cards.seaIceRestoration.name) {\r\n            otherTitle = 'Remove Atmospheric Carbon'\r\n            bonusClass = 'sea-ice-restoration-action'\r\n            footer = 'Restore 2 Sea Ice';\r\n        }\r\n\r\n        if (footer === 'Event') { footer = '' }\r\n\r\n        return (\r\n            <div className=\"modal action\">\r\n                <div className=\"modal-overlay\">\r\n                <section>\r\n                    <header className=\"modal-header\">\r\n                        <h1>{ title }</h1>\r\n                        <button className=\"close\" onClick={this.props.onClick}>{CLOSE_BUTTON_SYMBOL}</button>\r\n                    </header>\r\n                    <div className=\"modal-content\">\r\n\r\n                        <div className=\"card-view\">\r\n                            <div className={className}>\r\n                                <section>\r\n                                    <header>\r\n                                        <div className=\"card-symbol\">\r\n                                            <span>{ symbol }</span>\r\n                                        </div>\r\n                                    </header>\r\n                                    <div className=\"card-title\">\r\n                                    {otherTitle &&\r\n                                        <span>{otherTitle}</span>\r\n                                    }\r\n                                        <span>{ card.name }</span>\r\n                                    </div>\r\n                                    <div className=\"card-image\"></div>\r\n                                    { card.type === Config.types.action &&\r\n                                        <div className=\"\">\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                        </div>\r\n                                    }\r\n                                    <footer>\r\n                                    { validTargets.map (this.createPreyIcon) }\r\n\r\n                                        { card.type === Config.types.action &&\r\n                                            <div className=\"card-badge\">2 pts</div>\r\n                                        }\r\n                                        <div className=\"card-type\">\r\n                                            <span>{ footer }</span>\r\n                                        </div>\r\n                                    </footer>\r\n                                </section>\r\n                            </div>\r\n                        </div>\r\n\r\n                        <div className=\"card-info\">\r\n                            <div id=\"info-ice\">\r\n                                <h2>{ cardInfoTitle }</h2>\r\n                                <p>{ cardInfoText }</p>\r\n                            </div>\r\n                            { actionValidTargetListText.length > 0 &&\r\n                                <div id=\"info-details\">\r\n                                    <h2>{ detailsTitle }</h2>\r\n                                    <p>{ detailsText }</p>\r\n                                    { actionValidTargetListText.length > 0 &&\r\n                                        <p>This can impact the following species: {actionValidTargetListText}</p>\r\n                                    }\r\n                                </div>\r\n                            }\r\n                            { actionValidTargetListText.length === 0 &&\r\n                                <div id=\"info-details\">\r\n                                    <h2>{ detailsTitle }</h2>\r\n                                    <p>{ detailsText }</p>\r\n                                </div>\r\n                            }\r\n                            { actionValidTargetListText.length > 0 &&\r\n                                <div id=\"info-points\" className=\"contains-target-list\">\r\n                                    <h2>{ pointsTitle }</h2>\r\n                                    <p>{ pointsText }</p>\r\n                                </div>\r\n                            }\r\n                            {   actionValidTargetListText.length === 0 &&\r\n                                pointsText.length > 0 &&\r\n                                bonusClass.length === 0 &&\r\n                                    <div id=\"info-points\">\r\n                                        <h2>{ pointsTitle }</h2>\r\n                                        <p>{ pointsText }</p>\r\n                                    </div>\r\n                            }\r\n                            {   actionValidTargetListText.length === 0 &&\r\n                                pointsText.length > 0 &&\r\n                                bonusClass.length > 0 &&\r\n                                    <div id=\"info-points\" className=\"sea-ice-restoration-action\">\r\n                                        <h2>{ pointsTitle }</h2>\r\n                                        <p>{ pointsText }</p>\r\n                                    </div>\r\n                            }\r\n                        </div>\r\n                    </div>\r\n\r\n                </section>\r\n                </div>\r\n            </div>\r\n        )\r\n    }\r\n\r\n    getSpeciesDom (isPredator) {\r\n        let card = this.props.card;\r\n        let className = 'card-container' + ' ' + card.type.replaceAll (' ', '-').toLowerCase () + ' ' + card.name.toLowerCase ().replaceAll (' ', '-') + ' species';\r\n\r\n        if (isPredator) { className += ' pm' }\r\n\r\n        let tlOneClassName = 'card-food t1'\r\n        let tlTwoClassName = 'card-food t2'\r\n        let tlThreeClassName = 'card-food t3'\r\n        let tlFourClassName = 'card-food t4'\r\n        let tlFiveClassName = 'card-food t5'\r\n\r\n        switch (card.trophicLevel) {\r\n            case 1: tlOneClassName = 'card-food t1 highlight'; break;\r\n            case 2: tlTwoClassName = 'card-food t2 highlight'; break;\r\n            case 3: tlThreeClassName = 'card-food t3 highlight'; break;\r\n            case 4: tlFourClassName = 'card-food t4 highlight'; break;\r\n            case 5: tlFiveClassName = 'card-food t5 highlight'; break;\r\n        }\r\n\r\n        let iceRequiredDom = (\r\n            <div id=\"info-ice\">\r\n                <h2>Ice Required</h2>\r\n                <p>This species requires { card.needsIce } ice card{card.needsIce > 1 && (<span>s</span>)} to be played.</p>\r\n            </div>\r\n        )\r\n\r\n        if (card.needsIce === 0) {\r\n            iceRequiredDom = (\r\n                <div id=\"info-ice\">\r\n                    <h2>Ice Not Required</h2>\r\n                    <p>This species does not require ice to play.</p>\r\n                </div>\r\n            )\r\n        }\r\n\r\n        let modalClassName = 'modal species';\r\n\r\n        if (isPredator) { modalClassName += ' pm' }\r\n\r\n        let infoDom = (<div id=\"info-title\">\r\n          <h2>Name and Initials</h2>\r\n          <p>{card.symbol} – {card.name}</p>\r\n        </div>)\r\n\r\n        let dietString = this.createDietString ()\r\n\r\n        let name = card.name;\r\n\r\n        if (name === Config.cards.phytoPlankton.name) { name = 'Phyto-plankton' }\r\n\r\n        return (\r\n            <div className={modalClassName}>\r\n                <div className=\"modal-overlay\">\r\n                  <section>\r\n                    <header className=\"modal-header\">\r\n                      <h1>Species Card</h1>\r\n                      <button className=\"close\" onClick={this.props.onClick}>{CLOSE_BUTTON_SYMBOL}</button>\r\n                    </header>\r\n                    <div className=\"modal-content\">\r\n                      <div className=\"card-info\">\r\n\r\n                    { card.isProtected === true &&\r\n                          <div id=\"info-protect\">\r\n                              <h2>Protection Symbol</h2>\r\n                              <p>This species has been protected.</p>\r\n                          </div>\r\n                    }\r\n\r\n                    {isPredator != true &&\r\n                        infoDom\r\n                    }\r\n\r\n                        <div id=\"info-facts\">\r\n                          <h2>Species Facts</h2>\r\n                          <p>{ card.facts }</p>\r\n                        </div>\r\n\r\n                      </div>\r\n                      <div className=\"card-view\">\r\n                        <div id=\"\" className={className}>\r\n                          <section className=\"card-wrapper\">\r\n                            <header>\r\n                                {card.isProtected === true &&\r\n                                    <div className=\"card-protection\"></div>\r\n                                }\r\n\r\n                                {isPredator != true &&\r\n                                    <div className=\"card-symbol\"><span>{card.symbol}</span></div>\r\n                                }\r\n                              { card.needsIce > 0 &&\r\n                                isPredator != true &&\r\n                                  <div className=\"card-ice-value\"><span>{ card.needsIce }</span></div>\r\n                              }\r\n                            </header>\r\n                            <div className=\"card-title\"><span>{ name }</span></div>\r\n                            <div className=\"card-image\"></div>\r\n                            <footer>\r\n                              { card.diet.map (this.createPreyIcon) }\r\n                            </footer>\r\n                          </section>\r\n                        </div>\r\n                      </div>\r\n                      <div className=\"card-info\">\r\n\r\n                      {isPredator != true &&\r\n                          iceRequiredDom\r\n                      }\r\n\r\n                      {isPredator === true &&\r\n                          infoDom\r\n                      }\r\n\r\n                        <div id=\"info-trophic\">\r\n                          <h2>Trophic Level</h2>\r\n                          <div className=\"trophic-level\">\r\n                            <div className={ tlOneClassName }><span>1</span></div>\r\n                            <div className={ tlTwoClassName }><span>2</span></div>\r\n                            <div className={ tlThreeClassName }><span>3</span></div>\r\n                            <div className={ tlFourClassName }><span>4</span></div>\r\n                            <div className={ tlFiveClassName }><span>5</span></div>\r\n                          </div>\r\n                          <p>The trophic level of an organism is the position it occupies in a food web.</p>\r\n                        </div>\r\n\r\n                        {dietString.length > 0 &&\r\n                            <div id=\"info-food\">\r\n                                <h2>Food Sources</h2>\r\n                                <p>{ dietString }</p>\r\n                            </div>\r\n\r\n                        }\r\n                      </div>\r\n                    </div>\r\n                  </section>\r\n                </div>\r\n              </div>\r\n        )\r\n    }\r\n\r\n    getProtectASpeciesDom () {\r\n        let card = this.props.card;\r\n        let title = 'Action Card';\r\n        let type = 'Action'\r\n        let className = 'card-container' + ' ' + card.type.replaceAll (' ', '-').toLowerCase () + ' ' + card.name.toLowerCase ().replaceAll (' ', '-');\r\n\r\n        let cardInfoTitle = 'Species Protection';\r\n        let cardInfoText = ' Select one Species Card to Protect from Over Harvesting.';\r\n\r\n        let detailsTitle = 'Action Details';\r\n        let detailsText = card.facts;\r\n\r\n        let pointsTitle = 'Action Points';\r\n        let pointsText = 'Humans can take helpful actions to protect and conserve the Arctic ecosystem. Each Action card is worth 2 Action Points.'\r\n\r\n        let validTargets = [];\r\n\r\n        if (card.validTargets &&\r\n            card.validTargets.length &&\r\n            card.diet &&\r\n            card.diet.length)\r\n        {\r\n            validTargets = card.diet\r\n        }\r\n\r\n        let footer = '';\r\n        let actionValidTargetListText = ''\r\n        actionValidTargetListText = this.createValidTargetString ();\r\n\r\n        return (\r\n            <div className=\"modal action\">\r\n                <div className=\"modal-overlay\">\r\n                <section>\r\n                    <header className=\"modal-header\">\r\n                        <h1>{ title }</h1>\r\n                        <button className=\"close\" onClick={this.props.onClick}>{CLOSE_BUTTON_SYMBOL}</button>\r\n                    </header>\r\n                    <div className=\"modal-content\">\r\n\r\n                        <div className=\"card-info\">\r\n                        <div id=\"info-ice\">\r\n                            <h2>{ cardInfoTitle }</h2>\r\n                            <p>{ cardInfoText }</p>\r\n                        </div>\r\n                        { actionValidTargetListText.length > 0 &&\r\n                            <div id=\"info-details\">\r\n                                <h2>{ detailsTitle }</h2>\r\n                                <p>{ detailsText }</p>\r\n                                { actionValidTargetListText.length > 0 &&\r\n                                    <p>This can impact the following species: {actionValidTargetListText}</p>\r\n                                }\r\n                            </div>\r\n                        }\r\n                        { actionValidTargetListText.length === 0 &&\r\n                            <div id=\"info-details\">\r\n                                <h2>{ detailsTitle }</h2>\r\n                                <p>{ detailsText }</p>\r\n                            </div>\r\n                        }\r\n\r\n                        </div>\r\n\r\n                        <div className=\"card-view\">\r\n                            <div className={className}>\r\n                                <section>\r\n                                    <header>\r\n                                        <div className=\"card-symbol\">\r\n                                            <span>{ card.symbol }</span>\r\n                                        </div>\r\n                                    </header>\r\n                                    <div className=\"card-title\">\r\n                                        <span>{ card.name }</span>\r\n                                    </div>\r\n                                    <div className=\"card-image\"></div>\r\n                                    { card.type === Config.types.action &&\r\n                                        <div className=\"\">\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                            <div></div>\r\n                                        </div>\r\n                                    }\r\n                                    <footer>\r\n                                    { validTargets.map (this.createPreyIcon) }\r\n\r\n                                        { card.type === Config.types.action &&\r\n                                            <div className=\"card-badge\">2 pts</div>\r\n                                        }\r\n                                        <div className=\"card-type\">\r\n                                            <span>{ footer }</span>\r\n                                        </div>\r\n                                    </footer>\r\n                                </section>\r\n                            </div>\r\n                        </div>\r\n\r\n                        <div className=\"card-info\">\r\n                        { actionValidTargetListText.length > 0 &&\r\n                            <div id=\"info-points\" className=\"protect-a-species contains-target-list\">\r\n                                <h2>{ pointsTitle }</h2>\r\n                                <p>{ pointsText }</p>\r\n                            </div>\r\n                        }\r\n                            {   actionValidTargetListText.length === 0 &&\r\n                                pointsText.length > 0 &&\r\n                                    <div id=\"info-points\">\r\n                                        <h2>{ pointsTitle }</h2>\r\n                                        <p>{ pointsText }</p>\r\n                                    </div>\r\n                            }\r\n                        </div>\r\n                    </div>\r\n\r\n                </section>\r\n                </div>\r\n            </div>\r\n        )\r\n    }\r\n\r\n    render () {\r\n        let card = this.props.card;\r\n        let dom = (<div></div>);\r\n\r\n        if (card && card.type) {\r\n            if (card.name === Config.cards.protectASpecies.name) {\r\n                dom = this.getProtectASpeciesDom ();\r\n            }\r\n            else {\r\n                switch (card.type) {\r\n                    case Config.types.action:\r\n                    case Config.types.worldEvent:\r\n                        dom = this.getActionDom ();\r\n                        break\r\n                    case Config.types.lifeform:\r\n                        dom = this.getSpeciesDom ();\r\n                        break\r\n                    case Config.types.apexPredator:\r\n                        dom = this.getSpeciesDom (true);\r\n                        break\r\n                    default: console.log ('Missing card type. Card:', card)\r\n                }\r\n            }\r\n        }\r\n\r\n        return dom\r\n    }\r\n}\r\n","// Framework dependeices\r\nimport React, { Component } from 'react';\r\nimport anime from 'animejs/lib/anime.es.js';\r\n// import * as $ from './jquery-3.6.0.min.js';\r\n\r\n// Styling for this Object\r\nimport './EcoChains.css';\r\nimport './ScoreKeeper.css';\r\n\r\n// Imports for this project\r\nimport Config from './Config'\r\nimport Helper from './Helper';\r\n\r\nimport Deck from './Deck';\r\nimport ScoreKeeper from './ScoreKeeper';\r\nimport IceColumn from './IceColumn';\r\nimport ApexCardSlot from './ApexCardSlot';\r\nimport CardModal from './CardModal';\r\nimport Card from './Card';\r\n\r\n/*\r\n    Pregame Setup:\r\n        Shuffle deck\r\n        Place Ice Cards\r\n\r\n    Game steps:\r\n        Draw a card\r\n        Assess what kind of card it is\r\n        (optional) Put the card in play\r\n        Resolve card\r\n        Draw next card\r\n\r\n    Game ends when no more cards\r\n\r\n    Cards go into a face-up pile and an out-of-play\r\n    area. Not being able to play it right away means\r\n    it goes face up and certain events knock cards\r\n    out of play\r\n\r\n    Need:\r\n        - Something to manage current step in turn\r\n        - Event handler\r\n        - Card\r\n        - Card pile locations\r\n        - Play area\r\n        - Data structure to read in to generate content\r\n\r\n    Scoring:\r\n        Species - 1 point per lifeform card\r\n\r\n        Ice - * points per card in play that\r\n                has an ice requirement where\r\n                * is the ice requirement\r\n\r\n        Bonus - Protected species and positive\r\n                actions award victory points\r\n\r\n    Action Cards\r\n        - Sit in the play pile\r\n        - Need a valid target in order to be played\r\n        - This applies to negative events\r\n        - Carbon pollution cards are the exception\r\n\r\n    Apex Predators\r\n        - Automatically find an open apex predator slot when drawn\r\n*/\r\n\r\nconst STEP_DRAW_CARD = 1;\r\nconst STEP_ASSESS_CARD = 2;\r\nconst STEP_PLAY_CARD = 3;\r\nconst STEP_RESOLVE_CARD = 4;\r\nconst STEP_END_TURN = 5;\r\n\r\nconst DRAWN_CARD_INITIAL_POSITION = { x: 50, y: 10 };\r\n\r\nconst APEX_PREDATOR_SLOT_ID_ZERO = \"apexCardSlot0\"\r\nconst APEX_PREDATOR_SLOT_ID_ONE = \"apexCardSlot1\"\r\nconst APEX_PREDATOR_SLOT_ID_TWO = \"apexCardSlot2\"\r\nconst APEX_PREDATOR_SLOT_ID_THREE = \"apexCardSlot3\"\r\n\r\nconst CARBON_ICE_DESTRUCTION_AMOUNT = -2;\r\n\r\n// used when putCadsInDrawDeck is called. Adjusts the height and width of stacked cards\r\nconst DECK_SIZE_MODIFIER = 2.5;\r\n\r\nconst OFFSET_FROM_ICE_CARD = 35;\r\nconst ICE_STACK_POSITION_MULTIPLIER = 38;\r\nconst MAGIC_NUMBER_OFFSET = 11;\r\n\r\nconst FADE_OUT_TIME = 1500;\r\nconst APEX_PRED_ANIMATION_DURATION = 2000\r\n\r\n// Used for the fade out. A work around for poor object management and bashing anime into react without thinking about how the interaction is supposed to work\r\nvar __fadeOutFrameData = [];\r\n\r\nexport default class EcoChains extends Component {\r\n    constructor () {\r\n        super ();\r\n\r\n        // When more difficulties get added, change this later\r\n        let currentGameMode = Config.gameModes [0];\r\n\r\n        // Create initial state\r\n        this.state = {\r\n            deck: Helper.clone (Config.decks [currentGameMode]),\r\n            discard: [],\r\n            predatoryMammals: [],\r\n            targetCardIndex: -1,\r\n            drawIndex: -1,\r\n            faceUpPosition: DRAWN_CARD_INITIAL_POSITION,\r\n            iceColumns: [\r\n                { id: 'column0', children: [], ice: true },\r\n                { id: 'column1', children: [], ice: true },\r\n                { id: 'column2', children: [], ice: true },\r\n                { id: 'column3', children: [], ice: true },\r\n                { id: 'column4', children: [], ice: false },\r\n                { id: 'column5', children: [], ice: false },\r\n                { id: 'column6', children: [], ice: false },\r\n            ],\r\n            isDraggingCard: false,\r\n            relativePosition: { x: 0, y: 0 },\r\n            turnStep: 0,\r\n            speciesScore: 0,\r\n            iceScore: 0,\r\n            bonusScore: 0,\r\n            fedPredatorScoreBonus: {\r\n                ice: 0,\r\n                species: 0\r\n            },\r\n            cardParent: 'discard',\r\n            drawnApexPredators: [],\r\n            apexPredatorFoodChains: {\r\n                zero: [],\r\n                one: [],\r\n                two: [],\r\n                three: [],\r\n            },\r\n            outOfPlay: [],\r\n            fadingOut: [],\r\n            otherCardsBeingDragged: [],\r\n            iceDestroyed: 0,\r\n            uniqueSpeciesInPlay: {},\r\n            cardToInspect: {},\r\n            showInspectionModal: false,\r\n            showEndGameScreen: false,\r\n            showCreditsModal: false,\r\n            showStopDrawCover: false,\r\n            protectedSpeciesName: '',\r\n            stopperCard: {},\r\n            mouseX: 0,\r\n            mouseY: 0,\r\n            waitingToSpliceNullChildren: false,\r\n            animatingCards: false,\r\n            addIceRestoration: (Math.round (Math.random ())) ? true : false,\r\n            addRapidSeaIceLoss: (Math.round (Math.random ())) ? true : false,\r\n            debug: {\r\n                forceExtraCardsOff: false,\r\n                forceExtraCardsOn: false\r\n            },\r\n            shakingCards: false,\r\n            hideHelpButton: false,\r\n        }\r\n\r\n        this._iceColumnDoms = [];\r\n\r\n        // React is complaining about this but I literally cannot\r\n        // setState before a component mounts\r\n        this.state.deck.forEach (\r\n            (card, index) => {\r\n                this.state.deck [index] = Object.assign ({key: index}, card)\r\n            }\r\n        );\r\n\r\n        let targetIndex = this.state.deck.length;\r\n        let card;\r\n\r\n        if (\r\n            (this.state.addIceRestoration && this.state.debug.forceExtraCardsOff === false) ||\r\n            this.state.debug.forceExtraCardsOn === true\r\n        ) {\r\n            card = Helper.clone (Config.cards.seaIceRestoration)\r\n            card.key = targetIndex;\r\n            this.state.deck [targetIndex] = card\r\n        }\r\n        if (\r\n            (this.state.addRapidSeaIceLoss && this.state.debug.forceExtraCardsOff === false) ||\r\n            this.state.debug.forceExtraCardsOn === true\r\n        ) {\r\n            card = Helper.clone (Config.cards.rapidSeaIceLoss)\r\n            card.key = targetIndex + 1;\r\n            this.state.deck [targetIndex + 1] = card\r\n        }\r\n\r\n        // Function binds to ensure reference to \"this\" exists\r\n        this.flipAndMoveCard = this.flipAndMoveCard.bind (this);\r\n        this.onMouseDownOnCard = this.onMouseDownOnCard.bind (this);\r\n        this.onMouseUp = this.onMouseUp.bind (this);\r\n        this.onMouseMove = this.onMouseMove.bind (this);\r\n        this.createIceColumn = this.createIceColumn.bind (this);\r\n        this.onDoubleclick = this.onDoubleClick.bind (this);\r\n        this.closeModal = this.closeModal.bind (this);\r\n        this.endGame = this.endGame.bind (this);\r\n        this.showCredits = this.showCredits.bind (this);\r\n        this.hideCredits = this.hideCredits.bind (this);\r\n\r\n        // Global event listeners\r\n        // document.body.addEventListener ('keydown', (event) => { this.handleKeyPress (event); })\r\n        document.addEventListener ('mousemove', (event) => {\r\n            this.onMouseMove (event)\r\n         })\r\n        document.addEventListener ('mouseup', (event) => {\r\n            this.onMouseUp (event) })\r\n        document.ondblclick = (event) => { this.onDoubleClick (event) }\r\n    }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Set up functions\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    async componentDidMount () {\r\n        let board = Config.initialPlayAreas [\r\n            Math.floor (Math.random () * Config.initialPlayAreas.length)\r\n        ]\r\n\r\n        await this.prepareDeck ();\r\n        await this.shuffleCards ();\r\n        await this.putCardsInDrawDeck ();\r\n\r\n        window.setTimeout (async () => {\r\n            console.clear ();\r\n            console.log ('Clearing away linter warnings')\r\n            await this.prepareBoard (board);\r\n        }, 50);\r\n\r\n        // Show loading screen at least for a little\r\n        // To ENSURE that components are actually mounting. REACT\r\n        anime ({\r\n            targets: document.querySelector ('.loading-screen > .loader'),\r\n            opacity: 0,\r\n            easing: 'easeOutExpo',\r\n            duration: 500,\r\n            delay: 1500,\r\n            complete: () => {\r\n                try {\r\n                    document.querySelector ('.loader').remove ();\r\n\r\n                    let flavorText = document.createElement ('h1');\r\n                    flavorText.innerHTML = Config.loadingScreenTextTitle;\r\n                    flavorText.style = 'opacity: 0';\r\n\r\n                    let flavorTextBody = document.createElement ('p');\r\n                    flavorTextBody.innerHTML = Config.loadingScreenTextBody;\r\n                    flavorTextBody.style = 'opacity: 0';\r\n\r\n                    let button = document.createElement ('div');\r\n                    button.classList.add ('loading-screen-button');\r\n                    button.innerHTML = 'Play';\r\n                    button.style = 'opacity: 0';\r\n\r\n                    // let howToPlayButton = document.createElement ('div');\r\n                    // howToPlayButton.classList.add ('loading-screen-button');\r\n                    // howToPlayButton.classList.add ('how-to-play');\r\n                    // howToPlayButton.innerHTML = 'How to Play';\r\n                    // howToPlayButton.style = 'opacity: 0';\r\n                    // howToPlayButton.addEventListener ('click', () => { window.open('/ecochains/how-to-play/index.html') })\r\n\r\n                    button.onclick = () => {\r\n                        // console.log ('here')\r\n                        this.removeLoadingScreen ();\r\n                    }\r\n\r\n                    document.querySelector ('.loading-screen > .container').appendChild (flavorText);\r\n                    document.querySelector ('.loading-screen > .container').appendChild (flavorTextBody);\r\n                    document.querySelector ('.loading-screen > .container').appendChild (button);\r\n                    // document.querySelector ('.loading-screen > .container').appendChild (howToPlayButton);\r\n\r\n                    anime ({\r\n                        targets: [flavorText, flavorTextBody, button],\r\n                        opacity: 1,\r\n                        easing: 'easeOutExpo',\r\n                        duration: 500,\r\n                    })\r\n                }\r\n                catch (error) {}\r\n\r\n            }\r\n        })\r\n    }\r\n\r\n    removeLoadingScreen () {\r\n        anime ({\r\n            targets: document.querySelector ('.loading-screen'),\r\n            opacity: 0,\r\n            easing: 'easeOutExpo',\r\n            duration: 500,\r\n            delay: 0,\r\n            complete: () => {\r\n                try {\r\n                    document.querySelector ('.loading-screen').remove ();\r\n                    let helpButton = document.querySelector ('.help-button');\r\n\r\n                    anime ({\r\n                        targets: [helpButton],\r\n                        opacity: 1,\r\n                        easing: 'easeOutExpo',\r\n                        duration: 500,\r\n                        delay: 0\r\n                    })\r\n\r\n                }\r\n                catch (error) {}\r\n            }\r\n        })\r\n    }\r\n\r\n    prepareDeck () {\r\n        return new Promise ( (resolve) => {\r\n            this.setState ((prevState) => {\r\n                // Add additional data to objects in deck\r\n                let state = Helper.clone (prevState);\r\n                let deck = [];\r\n\r\n                // First, pull out the dummy card\r\n                    /*\r\n                        This needs to be done because of something weird with react that I don't understand.\r\n                        For whatever reason, the for-each function call that happens just below skips the first\r\n                        element of an array, but it works fine if that element is removed before the interaction.\r\n                    */\r\n                state.deck.splice (0, 1)\r\n\r\n                // now prepare the deck as normal\r\n                state.deck.forEach ( (card, index) => {\r\n                    if (card && card.name) {\r\n                        card.zIndex = this.state.deck.length - index + 10;\r\n                        card.isFaceDown = true;\r\n                        card.position = { x: 10, y: 10 };\r\n                        card.isDiscard = false;\r\n                        card.isPlacedInColumn = false;\r\n                        card.id = Helper.replaceAll (card.name, ' ', '-') + index;\r\n                        card.isProtected = false;\r\n\r\n                        deck.push (card);\r\n                    }\r\n                });\r\n\r\n                // console.log (deck [0])\r\n\r\n                return { deck, turnStep: STEP_DRAW_CARD }\r\n            }, () => { resolve (); });\r\n        })\r\n    }\r\n\r\n    // iterate over given config cards for ice columns\r\n    // and pre-set info\r\n    prepareBoard (boardLayout) {\r\n        return new Promise ((resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    let iceColumns = Helper.clone (prevState.iceColumns);\r\n\r\n                    let item, key, list, index;\r\n                    index = 0;\r\n                    list = boardLayout\r\n\r\n                    // iceColumns = this.injectStartLayout ()\r\n                    for (key in list) {\r\n                        let item = list [key];\r\n\r\n                        let targetColumn = iceColumns [index]\r\n\r\n\r\n                        let cards = this.prepareCards (item, targetColumn.id);\r\n\r\n                        targetColumn.children = targetColumn.children.concat (cards);\r\n\r\n                        index++;\r\n                    }\r\n\r\n                    // console.log ('IceColumns', iceColumns)\r\n\r\n                    return { iceColumns }\r\n                },\r\n                async () => {\r\n                    // Run the previously established cards through the various functions to make them think they need to go back to their columns\r\n                    await this.realignCards ();\r\n                }\r\n            )\r\n        })\r\n    }\r\n\r\n    realignCards () {\r\n        return new Promise ((resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    let state = Helper.clone (prevState)\r\n                    let list = state.iceColumns;\r\n                    let item, key, colIndex = 0;\r\n                    for (key in list) {\r\n                        item = list [key];\r\n\r\n                        let subList = item.children;\r\n                        let subItem, subKey;\r\n                        let cardIndex = 0;\r\n                        for (subKey in subList) {\r\n                            subItem = subList [subKey];\r\n\r\n                            subItem.position = {\r\n                                x: -55,\r\n                                y: (ICE_STACK_POSITION_MULTIPLIER * cardIndex) + OFFSET_FROM_ICE_CARD\r\n                            }\r\n                            cardIndex++\r\n                        }\r\n                        colIndex++\r\n                        // item.children.forEach (async (card, index) => {\r\n                        //     console.log ('setting', item.id, index, colIndex)\r\n                        // })\r\n\r\n                    }\r\n\r\n                    return {iceColumns: list}\r\n                },\r\n                () => { resolve (); }\r\n            )\r\n        })\r\n    }\r\n\r\n    prepareCards (cards, columnId) {\r\n        let list = Helper.clone (cards);\r\n\r\n        if (columnId === undefined) { columnId = '' }\r\n\r\n        list.forEach ((card, cardIndex) => {\r\n            card.zIndex = cardIndex;\r\n            card.isFaceDown = false;\r\n            card.position = { x: 0, y: 0 };\r\n            card.isDiscard = true;\r\n            card.isPlacedInColumn = columnId;\r\n            card.id = Helper.replaceAll (card.name, ' ', '-') + cardIndex + columnId;\r\n            card.isProtected = false;\r\n\r\n            if (!('footer' in card)) { card.footer = ''; }\r\n            if (!('blockerText' in card)) { card.blockerText = ''; }\r\n            if (!('validTargets' in card)) { card.validTargets = []; }\r\n            if (!('diet' in card)) { card.diet = []; }\r\n\r\n            // console.log (card)\r\n\r\n            list [cardIndex] = card;\r\n        })\r\n\r\n        return list\r\n    }\r\n\r\n    // Organize cards into top left corner and create a cool little stacking effect\r\n    putCardsInDrawDeck () {\r\n        return new Promise ( (resolve) => {\r\n            this.setState ( (prevState) => {\r\n                // start from the bottom of the deck and go backwards\r\n                let offset;\r\n                let deck = Helper.clone (prevState.deck)\r\n\r\n                deck.forEach ( (card, index) => {\r\n                    offset = index / DECK_SIZE_MODIFIER;\r\n\r\n                    card.position = { x: 0, y: offset}\r\n                    card.isFaceDown = true;\r\n                    card.zIndex = deck.length - index;\r\n                })\r\n                return { deck }\r\n            }, () => { resolve (); })\r\n        })\r\n    }\r\n\r\n    // Randomize array of cards and adjust z-index accordingly\r\n    shuffleCards () {\r\n        // Re-arrange card array\r\n        return new Promise ( (resolve) => {\r\n\r\n            this.setState (\r\n                (prevState) => {\r\n                    // Randomize orderof cards\r\n                    let deck = Helper.clone (prevState.deck);\r\n                    Helper.shuffle (deck);\r\n                    return { deck }\r\n                },\r\n                () => {\r\n                    // Assign new z-index but only if card is not in a column or in the discard pile\r\n                    // by modifying a clone of the deck array\r\n                    let deck = Helper.clone (this.state.deck);\r\n\r\n                    // Modify data on the clone\r\n                    deck.forEach ( (card, index) => {\r\n                        let canShuffle = (card.isPlacedInColumn === false && card.isDiscarded === false);\r\n\r\n                        if (canShuffle) { card.zIndex = this.state.deck.length - index }\r\n                    })\r\n\r\n                    // Resolve when state change is done\r\n                    this.setState ( () => { return {deck} }, () => { resolve (); } )\r\n                }\r\n            )\r\n        });\r\n    }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Runtime functions\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    // Called whenever a setState function finishes\r\n    componentDidUpdate (prevProps, prevState, snapshot) {\r\n        if (prevState.turnStep !== this.state.turnStep) {\r\n            // We've moved to the next part of the turn\r\n            let currentStep = this.state.turnStep\r\n            switch (currentStep) {\r\n                case STEP_DRAW_CARD: // Draw a new card\r\n                    // console.log ('Drawing a card');\r\n                    break;\r\n                case STEP_ASSESS_CARD: // Player is reviewing card\r\n                    // console.log ('Assessing card');\r\n                    break;\r\n                case STEP_PLAY_CARD: // Depends on card type\r\n                    // console.log ('Playing card');\r\n                    break;\r\n                case STEP_RESOLVE_CARD: // After-play affects of card\r\n                    // console.log ('Resolving card');\r\n                    break;\r\n                case STEP_END_TURN: // Do stuff to prepare for next round?\r\n                    // console.log ('Turn end events');\r\n                    break;\r\n                default:\r\n                    // We've iterated passed possible steps\r\n                    // start new turn\r\n                    console.log ('New turn');\r\n                    this.setState ({ turnStep: STEP_DRAW_CARD })\r\n            }\r\n        }\r\n\r\n        // Iterate over our columns and check how many of them are ice\r\n        let iceCount = 0;\r\n        let uniqueNames = {};\r\n\r\n        this.state.iceColumns.forEach ((column) => {\r\n            if (column.ice === true) { iceCount++ }\r\n\r\n            // iterate over children in columns to get names of unique species\r\n            column.children.forEach ((species) => {\r\n                uniqueNames [species.name] = true;\r\n            })\r\n        })\r\n\r\n        let update = {}\r\n\r\n        // iterate over fed predators and count the ice in them\r\n        let predatorIceScore = 0;\r\n        this.state.apexPredatorFoodChains.zero.forEach ((card) => {\r\n            predatorIceScore += card.needsIce\r\n        })\r\n        this.state.apexPredatorFoodChains.one.forEach ((card) => {\r\n            predatorIceScore += card.needsIce\r\n        })\r\n        this.state.apexPredatorFoodChains.two.forEach ((card) => {\r\n            predatorIceScore += card.needsIce\r\n        })\r\n        this.state.apexPredatorFoodChains.three.forEach ((card) => {\r\n            predatorIceScore += card.needsIce\r\n        })\r\n\r\n        if ((iceCount + predatorIceScore) !== this.state.iceScore) {\r\n            update.iceScore = iceCount + predatorIceScore\r\n        }\r\n\r\n        let fedScore = this.state.apexPredatorFoodChains.zero.length + this.state.apexPredatorFoodChains.one.length + this.state.apexPredatorFoodChains.two.length + this.state.apexPredatorFoodChains.three.length\r\n\r\n        if ((Object.keys (uniqueNames).length + fedScore) !== this.state.speciesScore) {\r\n            update.uniqueSpeciesInPlay = uniqueNames\r\n            update.speciesScore = Object.keys (this.state.uniqueSpeciesInPlay).length\r\n            update.speciesScore += fedScore;\r\n        }\r\n\r\n        if (Object.keys (update).length) {\r\n            this.setState (update)\r\n        }\r\n    }\r\n\r\n    makeSureCardsBelongToCorrectColumn () {\r\n        return new Promise ((resolve) => {\r\n            this.setState ((prevState) => {\r\n                let state = Helper.clone (prevState);\r\n                let iceColumns = state.iceColumns;\r\n\r\n                // console.clear ()\r\n                iceColumns.forEach ((column, index) => {\r\n                    let clearColumn = false;\r\n                    // console.log ('Checking', column.id, 'which is ice?', column.ice)\r\n                    column.children.forEach ((card) => {\r\n                        // console.log ('Checking', card.name, 'which requires', card.needsIce, 'ice')\r\n                        card.isPlaceInColumn = column.id\r\n\r\n                        if (\r\n                            (card.name === Config.cards.phytoPlankton.name && column.ice) ||\r\n                            (card.name === Config.cards.iceAlgea.name && !column.ice)\r\n                        ) {\r\n                            console.log ('Clearing column')\r\n                            clearColumn = true;\r\n                        }\r\n                    })\r\n\r\n                    if (clearColumn) {\r\n                        let cardsToFadeOut = Helper.clone (iceColumns [index].children);\r\n                        iceColumns [index].children = [];\r\n\r\n                        cardsToFadeOut.forEach ((card) => {\r\n                            this.fadeOutCardOutOfPlay (card)\r\n                        })\r\n                    }\r\n                })\r\n\r\n                return {iceColumns};\r\n            })\r\n        })\r\n    }\r\n\r\n    // Makes whatever card is being dragged render on top of\r\n    // every other card\r\n    bringCardToFront () {\r\n        return new Promise ( async (resolve) => {\r\n            await this.sortIceColumnsZIndex ();\r\n\r\n            this.setState (\r\n                (prevState) => {\r\n                    let discard = Helper.clone (prevState.discard);\r\n                    let iceColumns = Helper.clone (prevState.iceColumns);\r\n                    let cardParent = prevState.cardParent;\r\n                    let targetCardIndex = prevState.targetCardIndex;\r\n\r\n                    // This will probably make things look weird later, keep an eye on it\r\n                    // console.warn ('Running possibly flawed z-ordering operation');\r\n                    discard.forEach ((card, index) => {\r\n                        card.zIndex = discard.length - index;\r\n                    });\r\n\r\n                    // Make sure we are even dragging a card;\r\n                    let targetCard = this.findCard ();\r\n                    if (targetCard) {\r\n                        // Check where the card was before we started dragging it\r\n                        switch (cardParent) {\r\n                            case 'discard': discard [targetCardIndex].zIndex = 100; break;\r\n                            default:\r\n                                let columnIndex = Number (cardParent.split ('column') [1])\r\n                                let foundCard = false;\r\n\r\n                                console.log ('here?', columnIndex)\r\n                                iceColumns [columnIndex].children.forEach ((card, index) => {\r\n                                    if (card.id === targetCard.id) {\r\n                                        foundCard = true\r\n                                    }\r\n\r\n                                    if (foundCard) {\r\n                                        iceColumns [columnIndex].children [index].zIndex = 1000 + index\r\n                                    }\r\n\r\n                                })\r\n                        }\r\n                    }\r\n\r\n\r\n                    return { discard, iceColumns }\r\n                },\r\n                () => { resolve (); }\r\n            )\r\n        })\r\n    }\r\n\r\n    // Makes sure every card renders correctly in ice columns\r\n    sortIceColumnsZIndex () {\r\n        return new Promise ( (resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    let state = Helper.clone (prevState);\r\n                    let iceColumns = state.iceColumns\r\n\r\n                    iceColumns.forEach ((column) => {\r\n                        column.children.forEach (( child, index ) => {\r\n                            child.zIndex = index;\r\n                            column [index] = child;\r\n                        })\r\n                    })\r\n\r\n                    return { iceColumns }\r\n                },\r\n                () => { resolve (); }\r\n            )\r\n        })\r\n    }\r\n\r\n    flipCard (cardIndex) {\r\n        return new Promise ( (resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    let deck = Helper.clone (prevState.deck);\r\n                    deck [cardIndex].isFaceDown = !deck [cardIndex].isFaceDown;\r\n                    return { deck };\r\n                },\r\n                () => { resolve (); })\r\n        })\r\n    }\r\n\r\n    incrementTurnStep () {\r\n        return new Promise ( (resolve) => {\r\n            this.setState ((prevState) => { return { turnStep: prevState.turnStep + 1 } }, () => { resolve (); })\r\n        })\r\n    }\r\n\r\n    async flipAndMoveCard (event) {\r\n        // if (this.state.turnStep !== STEP_DRAW_CARD) { return; }\r\n\r\n        let deckDom = document.querySelector ('div.deck.Draw > .event-holder')\r\n        let target = event.target;\r\n\r\n        // If the deck is not what was clicked, don't do anything\r\n        if (deckDom !== target) { return; }\r\n\r\n        // If we can't draw a card, reshuffle any cards not placed\r\n        // back into the draw deck and randomize the deck\r\n\r\n        // await this.incrementDrawIndex ();\r\n\r\n        let validIndex = this.state.deck [this.state.deck.length - 1];\r\n\r\n        if (validIndex === undefined) {\r\n            console.log ('end game')\r\n            return;\r\n        }\r\n\r\n        let index = this.state.deck.length - 1;\r\n\r\n        await new Promise ( (resolve) => {\r\n            this.setState ({drawIndex: index}, () => { resolve (); })\r\n        })\r\n\r\n        await this.flipCard (index);\r\n\r\n        let card = validIndex;\r\n        let cardDom = document.getElementById (card.id);\r\n\r\n        // console.log ('getting card:', card.id, cardDom)\r\n\r\n        let cardWidth = cardDom.getBoundingClientRect ().width;\r\n\r\n        switch (validIndex.type) {\r\n            case Config.types.lifeform:\r\n                // console.log ('This card is a lifeform');\r\n                break;\r\n            case Config.types.worldEvent:\r\n                // console.log ('This card is a world event');\r\n\r\n                let carbonPollution = Config.cards.carbonPollution.name;\r\n                let rapidSeaIceLoss = Config.cards.rapidSeaIceLoss.name;\r\n\r\n                switch (card.name) {\r\n                    case rapidSeaIceLoss:\r\n                    case carbonPollution:\r\n                        let iceAmount = this.checkIceAmount (this.state.iceColumns);\r\n\r\n                        if (iceAmount > 0) {\r\n                            this.setState ({\r\n                                showStopDrawCover: true,\r\n                                stopperCard: card\r\n                            })\r\n                        }\r\n                        break;\r\n                    default:\r\n                        window.setTimeout (() => {\r\n                            let validTargetsAvailable = this.checkValidTargetForEvent (card);\r\n\r\n                            if (validTargetsAvailable) {\r\n                                this.setState ({\r\n                                    showStopDrawCover: true,\r\n                                    stopperCard: card\r\n                                })\r\n                            }\r\n\r\n                        }, 10)\r\n                }\r\n\r\n                break;\r\n            case Config.types.apexPredator:\r\n                // console.log ('This card is an apex predator');\r\n                // console.log ('moving card into an open apex predator slot');\r\n                this.moveApexPredatorToSlot (index, cardDom);\r\n\r\n                return;\r\n            default:\r\n                console.log ('Uuuuuuh?');\r\n                break;\r\n        }\r\n\r\n        let position = {\r\n            x: -cardWidth / 2,\r\n            y: 0\r\n        }\r\n\r\n        await this.moveCardToDiscard (index, position);\r\n        await this.bringCardToFront (0);\r\n        await this.incrementTurnStep ();\r\n    }\r\n\r\n    moveApexPredatorToSlot (i, cardDom) {\r\n        let cardBoundsUnderOldParent = cardDom.getBoundingClientRect ();\r\n        let index = i;\r\n\r\n        this.setState ((prevState) => {\r\n            let state = Helper.clone (prevState);\r\n            let deck = state.deck;\r\n            let drawnApexPredators = state.drawnApexPredators\r\n            let newParentRect = document.getElementById ('apexCardSlot' + state.drawnApexPredators.length)\r\n\r\n            // apex predator cards never leave the deck until this point\r\n            // so just assume the parent\r\n            //splice card out of deck and into the drawnApexPredators list\r\n            let card = deck.splice (index, 1) [0];\r\n\r\n            // card.position.x = cardBoundsUnderOldParent.x - newParentRect.x;\r\n            // card.position.y = cardBoundsUnderOldParent.y - newParentRect.y;\r\n\r\n            let deckX = document.querySelector ('.deck.Draw').getBoundingClientRect ().left;\r\n            let predX = document.getElementById ('apexCardSlot' + drawnApexPredators.length).getBoundingClientRect ().left;\r\n\r\n            card.position.x = Math.hypot (deckX - predX, 0) * -1;\r\n            card.position.y = 0;\r\n            card.isFaceDown = false;\r\n\r\n            drawnApexPredators.push (card);\r\n\r\n            let destinationX = -cardBoundsUnderOldParent.width/2;\r\n            let destinationY = 0;\r\n\r\n            this.setState ({ deck }, () => {\r\n                anime ({\r\n                    targets: card.position,\r\n                    x: destinationX,\r\n                    y: destinationY,\r\n                    easing: 'easeInOutExpo',\r\n                    duration: APEX_PRED_ANIMATION_DURATION,\r\n                    // easing: 'easeOutElastic(1, .8)',\r\n                    update: () => {\r\n                        card.zIndex = 1100;\r\n                        console.log (drawnApexPredators [0].zIndex);\r\n                        this.setState ({ drawnApexPredators, animatingCards: true, showStopDrawCover: true, stopperCard: { blockerText: ' ', id:'apex-tracker-card' } });\r\n                    },\r\n                    complete: () => {\r\n                        card.zIndex = 0;\r\n                        this.setState ({ drawnApexPredators, animatingCards: false, showStopDrawCover: false, stopperCard: {} });\r\n                    }\r\n                })\r\n            })\r\n        })\r\n    }\r\n\r\n    incrementDrawIndex () {\r\n        return new Promise ( (resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    let validIndex = prevState.deck [prevState.drawIndex + 1];\r\n                    let drawIndex;\r\n\r\n                    if (validIndex) { drawIndex = prevState.drawIndex + 1; }\r\n                    else { drawIndex = -1; }\r\n\r\n                    return { drawIndex }\r\n                },\r\n                () => { resolve (); }\r\n            );\r\n        })\r\n    }\r\n\r\n    moveCardToDiscard (cardIndex, position) {\r\n        return new Promise ( (resolve) => {\r\n            this.setState (\r\n                (prevState) => {\r\n                    // Pull the card out of the deck and move it to the discard\r\n                    let deck = Helper.clone (prevState.deck);\r\n                    let discard = Helper.clone (prevState.discard);\r\n\r\n                    let card = deck.splice (cardIndex, 1) [0];\r\n\r\n                    card.position = position;\r\n\r\n                    discard.unshift ( card );\r\n\r\n                    // console.log (card)\r\n\r\n                    return { deck, discard };\r\n                },\r\n                () => { resolve (); })\r\n        })\r\n    }\r\n\r\n    // This only works on cards already in the discard pile\r\n    // NOTE: The discard pile is really the play pile.\r\n    // This is just due to poor planning\r\n    sendBackToDiscard () {\r\n        let discard = Helper.clone (this.state.discard);\r\n        let cardIndex = this.state.targetCardIndex;\r\n\r\n        anime ({\r\n            targets: discard [cardIndex].position,\r\n            // this is negative of half the width of a card\r\n            x: -53,\r\n            y: 0,\r\n            easing: 'easeOutExpo',\r\n            duration: 300,\r\n            loop: false,\r\n            update: () => {\r\n                this.setState ({ discard });\r\n            },\r\n            complete: () => {\r\n                this.setState ({ animatingCards: false })\r\n            }\r\n        })\r\n    }\r\n\r\n    sendBackToIceColumn (dur, iceCol, crdParent, crdIndex, iceColIndex) {\r\n        return new Promise ((resolve) => {\r\n            // I should just figure out how to use destructured parameters here, but I am stressed for time\r\n            let duration = dur;\r\n            let iceColumns = iceCol;\r\n            let cardParent = crdParent;\r\n            let cardIndex = crdIndex\r\n\r\n            if (duration === undefined) { duration = 300; }\r\n            if (iceColumns === undefined) {\r\n                iceColumns = Helper.clone (this.state.iceColumns);\r\n            }\r\n            if (cardParent === undefined) {\r\n                cardParent = Helper.clone (this.state.cardParent);\r\n            }\r\n            if (cardIndex === undefined) {\r\n                cardIndex = this.state.targetCardIndex;\r\n            }\r\n\r\n            let iceColumnIndex = iceColIndex;\r\n\r\n            if (iceColumnIndex === undefined) {\r\n                iceColumns.forEach ( (column, index) => {\r\n                    if (column.id === cardParent) { iceColumnIndex = index }\r\n                })\r\n            }\r\n\r\n            console.log ('Returning card', duration, iceColumns, cardParent, cardIndex, iceColumnIndex)\r\n\r\n            anime ({\r\n                targets: iceColumns [iceColumnIndex].children [cardIndex].position,\r\n                // this is negative of half the width of a card\r\n                x: -55,\r\n                y: (ICE_STACK_POSITION_MULTIPLIER * cardIndex) + OFFSET_FROM_ICE_CARD,\r\n                easing: 'easeOutExpo',\r\n                duration,\r\n                loop: false,\r\n                update: () => {\r\n                    console.log ('Animating cards?', this.state.animatingCards)\r\n                    if (this.state.otherCardsBeingDragged.length === 0) {\r\n                        this.setState ({ iceColumns });\r\n                    }\r\n                    else {\r\n                        this.setState ((prevState) => {\r\n                            // find what column has this card\r\n                            let mainCard = iceColumns [iceColumnIndex].children [prevState.targetCardIndex]\r\n                            let column, columnIndex;\r\n\r\n                            iceColumns.forEach ((col, index) => {\r\n                                if (col.id === prevState.cardParent) {\r\n                                    column = col;\r\n                                    columnIndex = index;\r\n                                }\r\n                            })\r\n\r\n                            // Iterate over other cards being moved and set\r\n                            // their position too.\r\n                            // We already know they belong to the same column\r\n                            // Set the position of the other cards being dragged\r\n                            // relative to the moved card\r\n                            prevState.otherCardsBeingDragged.forEach ( (cardIndex) => {\r\n                                let otherCard = iceColumns [columnIndex].children [cardIndex]\r\n\r\n                                otherCard.position.x = mainCard.position.x\r\n                                otherCard.position.y = mainCard.position.y + (ICE_STACK_POSITION_MULTIPLIER * (cardIndex -prevState.targetCardIndex))\r\n\r\n                                // console.log (cardIndex, otherCard.position)\r\n\r\n                                iceColumns [columnIndex].children [cardIndex] = otherCard\r\n                            })\r\n\r\n                            return { iceColumns }\r\n                        })\r\n                    }\r\n                },\r\n                complete: () => {\r\n                    this.setState (\r\n                        { otherCardsBeingDragged: [], animatingCards: false },\r\n                        async () => {\r\n                            await this.realignCards ();\r\n                            resolve ();\r\n                        }\r\n                    )\r\n                }\r\n            })\r\n        })\r\n\r\n    }\r\n\r\n    closeModal () { this.setState ({showInspectionModal: false}) }\r\n\r\n    changeIceAmount (modifier, iceColumns) {\r\n        let currentIceAmount = this.checkIceAmount (iceColumns);\r\n        let modified = 0;\r\n\r\n        // Set ice to true on water cards next to ice cards\r\n        if (modifier > 0) {\r\n            // iterating from left to right\r\n            iceColumns.forEach ((column) => {\r\n                if (\r\n                    column.ice === false &&\r\n                    modified < Math.abs (modifier)\r\n                ) {\r\n                    column.ice = true;\r\n                    modified++;\r\n                }\r\n            })\r\n        }\r\n        // Set ice to false on ice cards next to water cards\r\n        else if (modifier < 0) {\r\n            // iterating from right to left\r\n            let i = iceColumns.length - 1;\r\n            let start = 0;\r\n\r\n            while (i >= start) {\r\n                let column = iceColumns [i];\r\n\r\n                if (\r\n                    column.ice === true &&\r\n                    modified < Math.abs (modifier)\r\n                ) {\r\n                    column.ice = false;\r\n                    modified++;\r\n                }\r\n\r\n                i--\r\n            }\r\n        }\r\n\r\n        return iceColumns\r\n    }\r\n\r\n    endGame () { this.setState ({ showEndGameScreen: true }) }\r\n    showCredits () { this.setState ({ showCreditsScreen: true }) }\r\n    hideCredits () { this.setState ({ showCreditsScreen: false }) }\r\n\r\n    newGame () { window.location.reload (); }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Mouse Event Handlers\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    onDoubleClick (event) {\r\n        if (this.state.showInspectionModal) { return; }\r\n\r\n        console.log ('double click detected. Target:', event)\r\n        console.log ('looking for', this.state.cardToInspect.id)\r\n        let cardDom = document.getElementById (this.state.cardToInspect.id);\r\n\r\n        console.log ('Found element?', cardDom)\r\n\r\n        if (!cardDom) { return }\r\n\r\n        let targetInCard = cardDom.contains (event.target);\r\n\r\n        if (targetInCard) {\r\n            this.setState ({ showInspectionModal: true })\r\n        }\r\n    }\r\n\r\n    onMouseMove (event) {\r\n        if (!this.state.isDraggingCard) { return }\r\n\r\n        let position = {\r\n            x: event.pageX - this.state.relativePosition.x,\r\n            y: event.pageY - this.state.relativePosition.y\r\n        }\r\n\r\n        this.setState ((prevState) => {\r\n            if (prevState.cardParent === 'discard') {\r\n                let discard = Helper.clone (prevState.discard);\r\n\r\n                discard [prevState.targetCardIndex].position = position\r\n\r\n                return { discard }\r\n            }\r\n            else {\r\n                // find what column has this card\r\n                let iceColumns = Helper.clone (prevState.iceColumns);\r\n\r\n                let column, columnIndex;\r\n\r\n                iceColumns.forEach ((col, index) => {\r\n                    if (col.id === prevState.cardParent) {\r\n                        column = col;\r\n                        columnIndex = index;\r\n                    }\r\n                })\r\n\r\n                // console.log (column.id);\r\n                // console.log (column.children);\r\n                // console.log (prevState.targetCardIndex);\r\n\r\n                // Just don't do anything if information is missing\r\n                if (\r\n                    !column ||\r\n                    !column.children ||\r\n                    !column.children [prevState.targetCardIndex]\r\n                ) { return; }\r\n\r\n                column.children [prevState.targetCardIndex].position = position;\r\n\r\n                // Iterate over other cards being moved and set\r\n                // their position too.\r\n                // We already know they belong to the same column\r\n                if (prevState.otherCardsBeingDragged.length > 0) {\r\n                    // Set the position of the other cards being dragged\r\n                    // relative to the moved card\r\n\r\n                    prevState.otherCardsBeingDragged.forEach ( (cardIndex) => {\r\n                        let otherCard = iceColumns [columnIndex].children [cardIndex]\r\n\r\n                        otherCard.position.x = position.x\r\n                        otherCard.position.y = position.y + (ICE_STACK_POSITION_MULTIPLIER * (cardIndex -prevState.targetCardIndex))\r\n\r\n                        iceColumns [columnIndex].children [cardIndex] = otherCard\r\n                    })\r\n                }\r\n\r\n                iceColumns [columnIndex] = column;\r\n\r\n                return { iceColumns, mouseX: event.pageX, mouseY: event.pageY }\r\n            }\r\n        })\r\n\r\n        event.stopPropagation ()\r\n        event.preventDefault ()\r\n    }\r\n\r\n    // calculate relative position to the mouse and set dragging=true\r\n    onMouseDownOnCard ({ event, card }) {\r\n        // Don't do anything if cards are moving\r\n        console.log ('Animating a card?', this.state.animatingCards)\r\n        if (this.state.animatingCards === true) { return; }\r\n\r\n        let target = event.target;\r\n        let isFaceDown = target.classList.contains ('facedown');\r\n        let isIce = target.classList.contains ('ice');\r\n        let isAlgea = target.classList.contains ('algea');\r\n        let isPredator = (card.type === Config.types.apexPredator);\r\n        let otherCardsBeingDragged = [];\r\n        let cardType = card.type;\r\n\r\n        // Make sure the card isn't facedown\r\n        if (isFaceDown) { return; }\r\n\r\n        // Make sure this card isn't one of the ice cards\r\n        if (isIce && !isAlgea) { return; }\r\n\r\n        // Don't do anything if a predator was click\r\n        if (isPredator) {\r\n            this.setState ({\r\n                cardToInspect: card\r\n            })\r\n            return;\r\n        }\r\n\r\n        let pos = Helper.clone (card.position);\r\n\r\n        // Assume the discard pile is the parent\r\n        let cardParent = 'discard';\r\n\r\n        // then check if the card is placed in a column\r\n        if (card.isPlacedInColumn) { cardParent = card.isPlacedInColumn }\r\n\r\n        if (cardType === Config.types.worldEvent) {\r\n            //Iterate over cards that match the diet\r\n            // this.applyScaredClassToCards (card)\r\n        }\r\n\r\n        this.setState({\r\n            cardParent, otherCardsBeingDragged,\r\n            isDraggingCard: true,\r\n            targetCardIndex: card.index,\r\n            relativePosition: {\r\n                x: event.pageX - pos.x,\r\n                y: event.pageY - pos.y\r\n            },\r\n            cardToInspect: card\r\n        }, async () => {\r\n            // If the target is an apex predator, stop dragging from\r\n            // happening\r\n            console.log (this.state.targetCardIndex);\r\n\r\n            // Make sure we are dragging a card befre we check\r\n            // for other cards that need to be dragged\r\n            if (!this.state.isDraggingCard) { return }\r\n\r\n            await this.bringCardToFront ();\r\n\r\n            this.setState ((prevState) => {\r\n                let state = Helper.clone (prevState);\r\n                let card = this.findCard (prevState);\r\n                let iceColumns = state.iceColumns;\r\n                let cardParent = state.cardParent;\r\n                let otherCardsBeingDragged = state.otherCardsBeingDragged;\r\n                let cardIndex = state.targetCardIndex;\r\n\r\n                // Check that column to see if the card grabbed\r\n                // is not the top of the stack\r\n                if (cardParent !== 'discard') {\r\n                    iceColumns.forEach ((column, index) => {\r\n                        if (\r\n                            column.id === cardParent &&\r\n                            cardIndex < (column.children.length - 1)\r\n                        ) {\r\n                            // Grab every card after this card too\r\n                            column.children.forEach  ( (child, index) => {\r\n                                if (cardIndex < index) {\r\n                                    // We only need the indexes\r\n                                    // of the other cards\r\n                                    otherCardsBeingDragged.push (index)\r\n                                }\r\n                            })\r\n                        }\r\n                    })\r\n\r\n                    return { iceColumns, otherCardsBeingDragged }\r\n                }\r\n\r\n                // Don't update state if we are pulling a card\r\n                // from the discard pile\r\n                return {}\r\n            })\r\n\r\n        })\r\n\r\n        event.stopPropagation ();\r\n        event.preventDefault ();\r\n    }\r\n\r\n    onMouseUp (event) {\r\n        // console.log ('Dragging card?', this.state.isDraggingCard)\r\n\r\n        if (this.state.shakingCards) {\r\n            // this.applyScaredClassToCards (null, true)\r\n        }\r\n\r\n        if (this.state.isDraggingCard) {\r\n            this.setState ({ animatingCards: true })\r\n\r\n            let validDrop = false;\r\n\r\n            validDrop = this.checkIfCardCanGoInColumn ();\r\n\r\n            console.log ('Valid drop?', validDrop)\r\n\r\n            // Have to use \"crd\" instead of \"card\" here\r\n            // because this app is poorly planned around\r\n            // how react wants things done\r\n            let crd = this.findCard ();\r\n\r\n            if (validDrop && crd.type === Config.types.lifeform) {\r\n                // look through the column that this card\r\n                // is about to be dropped in to make sure\r\n                // it can go ontop of the possible other\r\n                // cards that go in there\r\n                let result = this.checkIfSpeciesCanGoInColumn (\r\n                    crd,\r\n                    this.state.iceColumns [validDrop.iceColumnIndex]\r\n                )\r\n\r\n                if (!result) { validDrop = null }\r\n            }\r\n\r\n            // Up to this point, we are only checking if the\r\n            // player tried to put a card in an ice column\r\n            if (!validDrop) {\r\n                // Now check if the player tried to feed an apex predator\r\n                let feedingPredator = this.checkIfFeedingPredator (crd, event)\r\n                let canFeedPredator = false;\r\n\r\n                if (feedingPredator && feedingPredator.closestCollision) {\r\n                    let key = Object.keys (this.state.apexPredatorFoodChains) [feedingPredator.colIndex];\r\n\r\n                    if (this.state.apexPredatorFoodChains [key].length === 0) {\r\n                        canFeedPredator = true\r\n                    }\r\n                }\r\n\r\n                // First check to see if we are dragging the whole column before moving on\r\n                let parentColumn;\r\n                this.state.iceColumns.forEach ((col) => { if (col.id === this.state.cardParent) { parentColumn = col } })\r\n\r\n                // console.log ('Dragging:', this.state.otherCardsBeingDragged, 'ice column children:', parentColumn.children)\r\n\r\n\r\n                // let draggedCardCount = this.state.otherCardsBeingDragged.length + 1;\r\n                // // console.log ('Amount of cards being dragged:', draggedCardCount)\r\n                // // console.log ('Amount of children ice column has:', parentColumn.children.length)\r\n                // if (!parentColumn || draggedCardCount != parentColumn.children.length) {\r\n                //     canFeedPredator = false;\r\n                // }\r\n\r\n                // Now feed the predator if we can\r\n                if (canFeedPredator &&  this.state.cardParent != 'discard') {\r\n                    this.setState ((prevState) => {\r\n                        let state = Helper.clone (prevState);\r\n                        let apexPredatorFoodChains = state.apexPredatorFoodChains\r\n                        let iceColumns = state.iceColumns;\r\n\r\n                        let column\r\n                        state.iceColumns.forEach ((col) => { if (col.id === state.cardParent) { column = col; } })\r\n\r\n                        // Check if we have the full stack\r\n                        let draggedCardCount = state.otherCardsBeingDragged.length + 1;\r\n                        let draggingPartialStack = false;\r\n\r\n\r\n                        if (draggedCardCount !== column.children.length) { draggingPartialStack = true }\r\n\r\n                        // Take cards from column\r\n                        let otherCards = column.children.splice (0, column.children.length)\r\n\r\n                        // splice card out of prev parent\r\n                        // let oldParent = iceColumns [ Number (state.cardParent.split ('column') [1]) ]\r\n\r\n                        // let card = oldParent.children.splice (state.targetCardIndex, 1) [0];\r\n                        // let otherCards = [];\r\n\r\n                        // otherCards.push (card);\r\n\r\n                        // Move the other cards into this new parent\r\n                        // if (state.otherCardsBeingDragged.length > 0) {\r\n                            // Collect the data of the other cards\r\n                            // otherCards.forEach ( (otherCard, index) => {\r\n                            //     if (index )\r\n                            //     otherCards.push (\r\n                            //         // Subtract 1 since the dragged card was\r\n                            //         // already spliced out\r\n                            //         Helper.clone (otherCards [index])\r\n                            //     )\r\n                            // })\r\n\r\n                        // }\r\n\r\n                        let key = Object.keys (apexPredatorFoodChains) [feedingPredator.colIndex]\r\n\r\n                        apexPredatorFoodChains [key] = otherCards\r\n\r\n                        let colX = document.getElementById (state.cardParent).getBoundingClientRect ().left;\r\n\r\n                        let predIndex = 0;\r\n\r\n                        let item, k;\r\n                        for (k in apexPredatorFoodChains) {\r\n                            item = apexPredatorFoodChains [k];\r\n\r\n                            if (k === key) { break; }\r\n\r\n                            predIndex++;\r\n                        }\r\n\r\n                        let predRect = document.getElementById ('apexCardSlot' + predIndex).getBoundingClientRect ();\r\n                        let predX = predRect.left;\r\n\r\n                        // console.log (otherCards, apexPredatorFoodChains)\r\n                        let newPos = { x: Math.hypot (colX - predX, 0) * -1, y: 0 }\r\n\r\n                        if (draggingPartialStack) {\r\n                            window.setTimeout (() => {\r\n                                anime ({\r\n                                    targets: [newPos],\r\n                                    x: -(predRect.width / 2) + 12,\r\n                                    y: 0,\r\n                                    easing: 'easeOutExpo',\r\n                                    duration: 1500,\r\n                                    update: () => {\r\n                                        this.setState ((prevState) => {\r\n                                            let state = Helper.clone (prevState);\r\n                                            let apexPredatorFoodChains = state.apexPredatorFoodChains;\r\n\r\n                                            apexPredatorFoodChains [key].forEach ((card, index) => {\r\n                                                apexPredatorFoodChains [key] [index].position.x = newPos.x\r\n                                            })\r\n\r\n                                            console.log ('updating cards to', newPos.x, apexPredatorFoodChains [key] [0].position.x)\r\n\r\n                                            return { apexPredatorFoodChains }\r\n                                        })\r\n                                    },\r\n                                    complete: () => {\r\n                                        this.setState ({ animatingCards: false })\r\n                                    }\r\n                                })\r\n                            })\r\n                            return {iceColumns, apexPredatorFoodChains, animatingCards: true}\r\n                        }\r\n                        else {\r\n                            apexPredatorFoodChains [key].forEach ((card, index) => {\r\n                                apexPredatorFoodChains [key] [index].position.x = -(predRect.width / 2) + 12\r\n                            })\r\n                        }\r\n\r\n                        return {iceColumns, apexPredatorFoodChains, animatingCards: false}\r\n                    }, () => {\r\n                        console.log ('Top card on discard', this.state.discard [0])\r\n                        console.log ('Stopper card?', this.state.stopperCard)\r\n                        if (this.state.showStopDrawCover) {\r\n                            let topCard = this.state.discard [0];\r\n                            // re-check ice columns for valid targets\r\n                            let validTargetsAvailable = this.checkValidTargetForEvent (topCard);\r\n\r\n                            console.log ('found valid targets?', validTargetsAvailable)\r\n\r\n                            if (!validTargetsAvailable) {\r\n                                this.setState ({ showStopDrawCover: false })\r\n                            }\r\n                        }\r\n                    })\r\n                }\r\n                else {\r\n                    // if not, put things back\r\n                    if (this.state.cardParent === 'discard') { this.sendBackToDiscard (); }\r\n                    else { this.sendBackToIceColumn (); }\r\n                }\r\n            }\r\n            else {\r\n                // Move card into that column\r\n                this.setState (async (prevState) => {\r\n                    let state = Helper.clone (prevState);\r\n                    let iceColumns = state.iceColumns;\r\n                    let cardIndex = state.targetCardIndex;\r\n                    let index = validDrop.iceColumnIndex;\r\n\r\n                    let discard = state.discard\r\n\r\n                    let targets;\r\n                    let newParent;\r\n\r\n                    let card = this.findCard ();\r\n                    let otherCards = [];\r\n\r\n                    if (card.type === Config.types.lifeform) {\r\n                        // The card needs to spliced out of any arrays so its\r\n                        // position is absolute and it doesn't mess with\r\n                        // calculations related to children count\r\n                        if (state.cardParent === 'discard') {\r\n                            card = discard.splice (cardIndex, 1) [0];\r\n                        }\r\n                        else {\r\n                            let oldParent = state.iceColumns [ Number (state.cardParent.split ('column') [1]) ]\r\n\r\n                            card = oldParent.children.splice (cardIndex, 1) [0];\r\n\r\n                            // Move the other cards into this new parent\r\n                            if (state.otherCardsBeingDragged.length > 0) {\r\n                                // Collect the data of the other cards\r\n                                state.otherCardsBeingDragged.forEach ( (otherCardIndex) => {\r\n                                    otherCards.push (\r\n                                        // Subtract 1 since the dragged card was\r\n                                        // already spliced out\r\n                                        Helper.clone (oldParent.children [otherCardIndex - 1])\r\n                                    )\r\n                                })\r\n\r\n                                oldParent.children.splice (cardIndex, oldParent.children.length)\r\n                            }\r\n                        }\r\n\r\n                        targets = card.position;\r\n\r\n                        let cardDom = document.getElementById (card.id);\r\n                        let cardBoundsUnderOldParent = cardDom.getBoundingClientRect ();\r\n\r\n                        // The new parent can only ever be an ice column\r\n                        newParent = iceColumns [index].children;\r\n\r\n                        // console.log ('moving', card, 'to', JSON.stringify (newParent, null, 4))\r\n                        card.isPlacedInColumn = iceColumns [index].id;\r\n                        newParent.push (card);\r\n\r\n                        // Push the other cards being dragged if there are any\r\n                        if (otherCards.length > 0) {\r\n                            // console.log ('Also moving these cards:', JSON.stringify (otherCards, null, 4))\r\n\r\n                            let startIndex = newParent.length - 1;\r\n\r\n                            otherCards.forEach ((otherCard) => {\r\n                                otherCard.isPlacedInColumn = iceColumns [index].id;\r\n                                newParent.push (otherCard)\r\n                            })\r\n\r\n                            state.otherCardsBeingDragged = [];\r\n                            otherCards.forEach ((item, index) => {\r\n                                // item.isPlacedInColumn = iceColumns [index].id;\r\n                                state.otherCardsBeingDragged.push (index + startIndex);\r\n                            })\r\n                        }\r\n\r\n                        iceColumns [index].children = newParent;\r\n\r\n                        let newParentDom = document.getElementById (iceColumns [index].id);\r\n                        let newParentRect = newParentDom.getBoundingClientRect ();\r\n\r\n                        targets.x = cardBoundsUnderOldParent.x - newParentRect.x;\r\n                        targets.y = cardBoundsUnderOldParent.y - newParentRect.y;\r\n\r\n                        let destinationX = 0 - (validDrop.cardWidth/2) - 5;\r\n                        let destinationY = ((ICE_STACK_POSITION_MULTIPLIER + MAGIC_NUMBER_OFFSET) * (newParent.length - otherCards.length)) - OFFSET_FROM_ICE_CARD;\r\n\r\n                        // Animate card into position\r\n                        anime ({\r\n                            targets,\r\n                            x: destinationX,\r\n                            y: destinationY,\r\n                            easing: 'easeOutExpo',\r\n                            duration: 300,\r\n                            loop: false,\r\n                            update: async () => {\r\n                                if (state.otherCardsBeingDragged.length === 0) {\r\n                                    this.setState ({ discard, iceColumns });\r\n                                }\r\n                                else {\r\n                                    this.setState (async (prevState) => {\r\n                                        let state = Helper.clone (prevState);\r\n\r\n                                        // console.log ('Grabbing a card from', state.iceColumns [index].children)\r\n\r\n                                        // The children have somehow already moved\r\n                                        if (state.iceColumns [index].children.length === 0) {\r\n                                            return { discard, iceColumns }\r\n                                        }\r\n\r\n                                        // find what column has this card\r\n                                        let mainCard = state.iceColumns [index].children [state.targetCardIndex]\r\n\r\n                                        // If this is undefined, grab the base card.\r\n                                        if (mainCard === undefined) {\r\n                                            mainCard = state.iceColumns [index].children [0]\r\n                                        }\r\n\r\n                                        // Iterate over other cards being moved and set\r\n                                        // their position too.\r\n                                        // We already know they belong to the same column\r\n                                        // Set the position of the other cards being dragged\r\n                                        // relative to the moved card\r\n                                        state.otherCardsBeingDragged.forEach ( (cardIndex) => {\r\n                                            // console.log (iceColumns, index)\r\n                                            let otherCard = iceColumns [index].children [cardIndex]\r\n\r\n                                            // console.log (otherCard)\r\n\r\n                                            otherCard.position.x = mainCard.position.x + 4\r\n                                            otherCard.position.y = mainCard.position.y + (ICE_STACK_POSITION_MULTIPLIER * cardIndex)\r\n\r\n                                            // console.log (cardIndex, otherCard.position)\r\n\r\n                                            iceColumns [index].children [cardIndex] = otherCard\r\n                                        })\r\n\r\n                                        return { iceColumns, discard }\r\n                                    }, () => { this.makeSureCardsBelongToCorrectColumn (); })\r\n                                }\r\n                            },\r\n                            complete: () => {\r\n\r\n                                card.position.x = -validDrop.cardWidth / 2;\r\n                                card.position.y = destinationY;\r\n\r\n                                this.setState (\r\n                                    {\r\n                                        iceColumns,\r\n                                        discard,\r\n                                        turnStep: STEP_DRAW_CARD,\r\n                                        otherCardsBeingDragged: [],\r\n                                        animatingCards: false\r\n                                    },\r\n                                    async () => {\r\n                                        await this.sortIceColumnsZIndex ();\r\n                                        // console.log (targets, destinationX, destinationY)\r\n                                        await this.realignCards ();\r\n                                        await this.makeSureCardsBelongToCorrectColumn ();\r\n                                    }\r\n                                )\r\n                            }\r\n                        })\r\n\r\n                        return { iceColumns, discard }\r\n                    }\r\n                    else if (\r\n                        card.type === Config.types.worldEvent ||\r\n                        card.type === Config.types.action\r\n                    ) {\r\n                        let resolution = card.resolution;\r\n                        let iceColumn = iceColumns [validDrop.iceColumnIndex]\r\n                        let outOfPlay = state.outOfPlay;\r\n                        let result;\r\n                        let animatingCards = false;\r\n\r\n                        switch (resolution) {\r\n                            case Config.resolutions.removeIce:\r\n                            case Config.resolutions.rapidSeaIceLoss:\r\n\r\n                                console.log ('Removing sea ice with resolution of', resolution)\r\n\r\n                                let iceToRemove = this.checkIceAmount (iceColumns);\r\n\r\n                                // The player can't play this card yet\r\n                                if (iceToRemove === 0) {\r\n                                    this.sendBackToDiscard ();\r\n                                }\r\n                                else {\r\n                                    let iceAmount = CARBON_ICE_DESTRUCTION_AMOUNT;\r\n\r\n                                    if (resolution === Config.resolutions.rapidSeaIceLoss) { iceAmount = -3 }\r\n\r\n                                    iceColumns = this.changeIceAmount (iceAmount, iceColumns);\r\n\r\n                                    let cardToFade = discard.splice (state.targetCardIndex, 1) [0]\r\n                                    this.fadeOutCardOutOfPlay (cardToFade, document.querySelector ('.deck.play'))\r\n\r\n                                    // splice card out of play\r\n                                    let newState = {\r\n                                        iceColumns,\r\n                                        discard,\r\n                                        animatingCards,\r\n                                        // outOfPlay,\r\n                                        showStopDrawCover: false,\r\n                                    }\r\n\r\n                                    // NOT SURE WHY I HAVE TO DO THIS\r\n                                    window.setTimeout (() => {\r\n\r\n                                        // newState.discard = discard;\r\n                                        iceColumns = this.checkIceRemovedSurvivors (iceColumns);\r\n                                        newState.iceColumns = iceColumns;\r\n\r\n                                        this.setState (newState, () => {\r\n\r\n                                            window.setTimeout (async () => {\r\n                                                await this.makeSureCardsBelongToCorrectColumn ()\r\n                                                this.checkIceDependentSpecies ();\r\n                                                // this.setState ({iceColumns})\r\n                                            }, 100)\r\n                                        })\r\n                                    })\r\n\r\n                                    return\r\n                                }\r\n\r\n                                break;\r\n                            case Config.resolutions.addIce:\r\n                            case Config.resolutions.iceRestoration:\r\n                                let iceAmount = 1;\r\n\r\n                                if (resolution === Config.resolutions.iceRestoration) { iceAmount = 2 }\r\n\r\n                                iceColumns = this.changeIceAmount (iceAmount, iceColumns);\r\n                                let cardToFade = discard.splice (state.targetCardIndex, 1) [0];\r\n                                this.fadeOutCardOutOfPlay (cardToFade, document.querySelector ('.deck.play'))\r\n\r\n                                state.bonusScore += 2\r\n\r\n                                iceColumns = this.checkIceRemovedSurvivors (iceColumns);\r\n\r\n                                let newState = {\r\n                                    animatingCards,\r\n                                    discard,\r\n                                    iceColumns,\r\n                                    outOfPlay,\r\n                                    bonusScore: state.bonusScore\r\n                                };\r\n\r\n                                // NOT SURE WHY I HAVE TO DO THIS\r\n                                window.setTimeout (() => {\r\n\r\n                                    this.setState (newState, () => {\r\n                                        window.setTimeout (async () => {\r\n                                            await this.makeSureCardsBelongToCorrectColumn ();\r\n                                            await this.checkIceDependentSpecies ();\r\n                                        }, 100)\r\n                                    });\r\n                                })\r\n\r\n                                return\r\n                            case Config.resolutions.protectSpecies:\r\n                                result = this.checkWhichCardToProtect (event);\r\n\r\n                                if (!result) { this.sendBackToDiscard (); }\r\n                                else {\r\n                                    iceColumn = iceColumns [result.targetColumnIndex];\r\n\r\n                                    // outOfPlay.push (discard.splice (state.targetCardIndex, 1) [0]);\r\n                                    let cardToFadeOut = discard.splice (state.targetCardIndex, 1) [0];\r\n                                    this.fadeOutCardOutOfPlay (cardToFadeOut);\r\n\r\n                                    let protectedCard = iceColumn.children [result.targetCardIndex];\r\n\r\n                                    iceColumn.children [result.targetCardIndex].isProtected = true;\r\n\r\n                                    let newState ={\r\n                                        animatingCards,\r\n                                        discard,\r\n                                        outOfPlay,\r\n                                        iceColumns,\r\n                                        protectedSpeciesName: protectedCard.name\r\n                                     }\r\n\r\n                                    let targetCardIndex = state.targetCardIndex;\r\n\r\n                                    // NOT SURE WHY I HAVE TO DO THIS\r\n                                    window.setTimeout (() => {\r\n                                        this.setState (newState);\r\n                                    })\r\n\r\n                                    return\r\n                                }\r\n                                break;\r\n                            case Config.resolutions.oceanAcid:\r\n                            case Config.resolutions.overHarvesting:\r\n                            case Config.resolutions.invasiveWhales:\r\n                                result = this.checkValidTargetForEvent ();\r\n\r\n                                // No valid targets found, send it back to the play area\r\n                                if (!result) { this.sendBackToDiscard () }\r\n                                else {\r\n                                    let targetCards = iceColumns [result.targetColumnIndex].children\r\n                                    let cardToFade = discard.splice (state.targetCardIndex, 1) [0];\r\n\r\n                                    let protectedCard = -1;\r\n\r\n                                    // console.log (state.protectedSpeciesName, cardToFade.name)\r\n\r\n                                    let cardsToFade\r\n                                    if (state.protectedSpeciesName && cardToFade.name === Config.cards.overHarvesting.name) {\r\n                                        console.log ('The cards that are being iterated over', targetCards)\r\n                                        targetCards.forEach ((speciesCard, index) => {\r\n                                            console.log ('Species card name:', speciesCard.name, 'vs the protected species name:', state.protectedSpeciesName)\r\n                                            if (speciesCard.name === state.protectedSpeciesName) {\r\n                                                protectedCard = index;\r\n                                            }\r\n                                        })\r\n\r\n                                        console.log ('Was there a protected species in this list?', protectedCard)\r\n\r\n                                        // We found a protected card in this stack\r\n                                        if (protectedCard > -1) {\r\n                                            // Prevent playing overharvesting on the top card\r\n                                            if (protectedCard === targetCards.length - 1) {\r\n                                                this.sendBackToDiscard ();\r\n                                                return;\r\n                                            }\r\n                                            // If the protected has stuff stacked on it, then eat those instead\r\n                                            // since anything that eats protected cards can also be over-harvested\r\n                                            else {\r\n                                                // So just remove every card after that card\r\n                                                cardsToFade = targetCards.splice (protectedCard + 1, targetCards.length)\r\n                                            }\r\n                                        }\r\n                                        // We didn't find a protected card, so remove everything\r\n                                        else {\r\n                                            cardsToFade = targetCards.splice (result.targetCardIndex, targetCards.length)\r\n                                        }\r\n                                    }\r\n                                    else {\r\n                                        cardsToFade = targetCards.splice (result.targetCardIndex, targetCards.length)\r\n                                    }\r\n\r\n                                    if (cardsToFade && cardsToFade.length) {\r\n                                        cardsToFade.forEach ((crdToFade, index) => {\r\n                                            window.setTimeout (() => {\r\n                                                this.fadeOutCardOutOfPlay (crdToFade)\r\n                                            })\r\n                                        })\r\n                                    }\r\n\r\n                                    // outOfPlay.concat (\r\n                                    // )\r\n\r\n                                    // outOfPlay.push (discard.splice (state.targetCardIndex, 1) [0]);\r\n\r\n                                    this.fadeOutCardOutOfPlay (cardToFade)\r\n\r\n                                    let newState = {\r\n                                        animatingCards,\r\n                                        discard,\r\n                                        outOfPlay,\r\n                                        iceColumns,\r\n                                        showStopDrawCover: false\r\n                                    }\r\n\r\n                                    // NOT SURE WHY I HAVE TO DO THIS\r\n                                    window.setTimeout (() => {\r\n                                        // this.fadeOutCardOutOfPlay ('discard', discardTargetIndex)\r\n                                        // this.fadeOutCardOutOfPlay ('iceColumns', targetIndex, iceColIndex)\r\n\r\n                                        this.setState (newState);\r\n                                    })\r\n\r\n                                    return\r\n                                }\r\n                                break;\r\n                            default:\r\n                                console.log ('where did you find this card?');\r\n                                break;\r\n                        }\r\n                    }\r\n                }, async () => {\r\n                    await this.makeSureCardsBelongToCorrectColumn ();\r\n                    await this.checkIceDependentSpecies ();\r\n\r\n                });\r\n            }\r\n        }\r\n        else {\r\n            // see if we clicked on a predator card\r\n            if (\r\n                this.state.cardToInspect &&\r\n                this.state.cardToInspect.type === Config.types.apexPredator\r\n            ) {\r\n                // Now check to see if the click event target is within the dom of the card\r\n\r\n                let predatorDom = document.getElementById (this.state.cardToInspect.id);\r\n\r\n                if (predatorDom && predatorDom.contains (event.target)) {\r\n                    this.onDoubleClick (event)\r\n                }\r\n\r\n                this.setState ({ animatingCards: false });\r\n            }\r\n        }\r\n\r\n        this.setState ({ isDraggingCard: false });\r\n\r\n        // event.stopPropagation ();\r\n        // event.preventDefault ();\r\n    }\r\n\r\n    applyScaredClassToCards (worldEventCard, removeScaredClass) {\r\n        if (removeScaredClass === undefined) { removeScaredClass = false; }\r\n        // Don't do anything if the card has no specific target like the ice cards\r\n        if (worldEventCard === null) {\r\n            worldEventCard = { diet: [] }\r\n        }\r\n        else if (worldEventCard.diet.length === 0) { return; }\r\n\r\n        var targetCards = worldEventCard.diet\r\n        this.setState ((prevState) => {\r\n            let state = Helper.clone (prevState);\r\n            let iceColumns = state.iceColumns;\r\n\r\n            iceColumns.forEach ((iceColumn) => {\r\n                iceColumn.children.forEach ((card) => {\r\n\r\n                    if (removeScaredClass === false) {\r\n                        targetCards.forEach ((dietObject) => {\r\n                            if (dietObject.fullName === card.name) { card.isScared = true }\r\n                        })\r\n                    }\r\n                    else {\r\n                        card.isScared = false\r\n                    }\r\n                })\r\n            })\r\n\r\n            return { iceColumns, shakingCards: !removeScaredClass }\r\n        })\r\n    }\r\n\r\n    fadeOutCardOutOfPlay (crd, parentElement) {\r\n        let card = crd; // store reference in this scope\r\n        if (!card || (card && card.hasStartedFadeAnimation)) { return }\r\n\r\n        // let alreadyHasThisCard = false;\r\n\r\n        // console.log (fadingOut)\r\n        let fadingOut = Helper.clone (this.state.fadingOut)\r\n\r\n        // fadingOut.forEach ((c) => {\r\n        //     if (c != null && card.id === c.id) { alreadyHasThisCard = true; }\r\n        // })\r\n\r\n        // console.log ('already has card?', alreadyHasThisCard)\r\n\r\n        // if (alreadyHasThisCard) { return }\r\n\r\n        // card.hasStartedFadeAnimation = true;\r\n        card.opacity = 1;\r\n\r\n        let newParentDom\r\n        let newParentRect\r\n        let cardBoundsUnderOldParent\r\n        let targets\r\n\r\n        try {\r\n            newParentDom = document.getElementById ('fade-out');\r\n            newParentRect = newParentDom.getBoundingClientRect ();\r\n            cardBoundsUnderOldParent = document.getElementById (card.id).getBoundingClientRect ();\r\n            targets = {}\r\n            targets.x = cardBoundsUnderOldParent.x - newParentRect.x;\r\n            targets.y = cardBoundsUnderOldParent.y - newParentRect.y;\r\n        }\r\n        catch (error) {\r\n            console.clear ();\r\n            console.log (error);\r\n            console.log ('Card that caused a problem:', card)\r\n            console.log ('Looking for card with an ID of', card.id);\r\n            console.log (document.getElementById (card.id))\r\n            return;\r\n        }\r\n\r\n        // console.clear ();\r\n        // console.log ('Gathering stuff to move card into position');\r\n        // console.log (newParentDom)\r\n        // console.log (newParentRect)\r\n        // console.log (targets)\r\n        // console.log (cardBoundsUnderOldParent)\r\n\r\n        card.position = targets;\r\n        fadingOut.push (card);\r\n        let cardIndex = fadingOut.length - 1;\r\n\r\n        let newState = {};\r\n\r\n        newState.fadingOut = fadingOut;\r\n\r\n        this.setState (newState, () => {\r\n            anime ({\r\n                targets: [card],\r\n                opacity: 0,\r\n                delay: 1,\r\n                duration: FADE_OUT_TIME,\r\n                ease: 'easeOutExpo',\r\n                update: (anim) => {\r\n                    window.setTimeout (() => {\r\n                        this.setState ((prevState) => {\r\n                            let state = Helper.clone (prevState);\r\n                            let fadingOut = state.fadingOut;\r\n\r\n                            fadingOut.forEach ((c, index) => {\r\n                                if (c != null && c.id === card.id) {\r\n                                    c.opacity = 1 - (anim.progress / 100)\r\n                                    // console.log ('setting card opacity to', c.opacity)\r\n                                    fadingOut [index] = c;\r\n                                }\r\n                            })\r\n\r\n                            return { fadingOut }\r\n                        })\r\n                    })\r\n                },\r\n                complete: () => {\r\n                    window.setTimeout (() => {\r\n                        this.setState ((prevState) => {\r\n                            let state = Helper.clone (prevState);\r\n                            let fadingOut = state.fadingOut;\r\n                            let filteredFadingOut = [];\r\n\r\n                            filteredFadingOut = fadingOut.filter ((c) => {\r\n                                return c.opacity != 0;\r\n                            })\r\n\r\n                            return { fadingOut: filteredFadingOut }\r\n                        })\r\n                    })\r\n                }\r\n            })\r\n        })\r\n    }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Find Functions\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    // Looks through the discard and columns depending on currently set card parent\r\n    findCard (prevState) {\r\n        let state = this.state;\r\n\r\n        if (prevState) { state = prevState }\r\n\r\n        let card;\r\n\r\n        if (state.cardParent === 'discard') {\r\n            card = state.discard [state.targetCardIndex];\r\n        }\r\n        else {\r\n            // find what column has this card\r\n            let column, columnIndex;\r\n\r\n            state.iceColumns.forEach ((col, index) => {\r\n                if (col.id === state.cardParent) {\r\n                    column = col;\r\n                    columnIndex = index;\r\n                }\r\n            })\r\n\r\n            card = column.children [state.targetCardIndex];\r\n        }\r\n\r\n        return card;\r\n    }\r\n\r\n    findClosestColumn (cardCenter, columnACenter, columnBCenter) {\r\n        // subtract the cardCenter from the other two cards\r\n        // whichever result is closer to zero is the closer column\r\n\r\n        let colAResult = Math.abs (columnACenter - cardCenter);\r\n        let colBResult = Math.abs (columnBCenter - cardCenter);\r\n\r\n        if (colAResult < colBResult) { return 1 }\r\n        else if (colBResult < colAResult) { return 2 }\r\n        else if (colAResult === colBResult) { return Math.ceil (Math.random () * 2) }\r\n    }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Check Functions\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    checkIceRemovedSurvivors (iceColumns) {\r\n        // iterate over ice columns\r\n        // remove any ice algea on water and remove any phyto plankton on ice\r\n        let iceAmount = this.checkIceAmount (iceColumns);\r\n\r\n        let columns = Helper.clone (iceColumns);\r\n        columns.forEach ((column, colIndex) => {\r\n            let ice = column.ice;\r\n            let hasAlgea = false;\r\n            let hasPlankton = false;\r\n\r\n            if (column.children.length) {\r\n                if (column.children [0].name === Config.cards.iceAlgea.name ) { hasAlgea = true }\r\n                else if (column.children [0].name === Config.cards.phytoPlankton.name) { hasPlankton = true }\r\n                // console.log (column.children)\r\n                // console.log ('Column', column.id, 'has children?', column.children.length, 'and needs to remove children?', ice != hasAlgea)\r\n\r\n                // iterate over the children and remove specific children\r\n                let item, key;\r\n                for (key in column.children) {\r\n                    item = column.children [key];\r\n\r\n                    // console.log ('checking: ', item.name, 'which needs', item.needsIce, 'ice and there is', iceAmount, 'ice left')\r\n                    if (item.needsIce > iceAmount) {\r\n                        let result = Helper.clone (column.children);\r\n                        result.forEach ((crdToFade) => {\r\n                            // window.setTimeout (() => {\r\n                                this.fadeOutCardOutOfPlay (crdToFade)\r\n                            // })\r\n                        })\r\n\r\n                        window.setTimeout (() => {\r\n                            column.children.splice (Number (key), 10);\r\n                            //     column.children.splice (Number(key), 10)\r\n                            // }, FADE_OUT_TIME)\r\n                        })\r\n                        break;\r\n                    }\r\n\r\n                }\r\n\r\n                if (\r\n                    (!ice && hasAlgea) ||\r\n                    (ice && hasPlankton)\r\n                ) {\r\n                    if (column.children.length) {\r\n                        let cardsToFade = Helper.clone (column.children);\r\n                        cardsToFade.forEach ((crdToFade, index) => {\r\n                            this.fadeOutCardOutOfPlay (crdToFade)\r\n                            // window.setTimeout (() => {\r\n                            // })\r\n                        })\r\n                    }\r\n\r\n                    window.setTimeout (() => {\r\n                        column.children = []\r\n\r\n                    })\r\n                }\r\n            }\r\n        })\r\n\r\n        return columns;\r\n    }\r\n\r\n    checkForCollision (cardDom, columnDom) {\r\n        let cardBounds = cardDom.getBoundingClientRect ();\r\n        let cardWidth = cardDom.clientWidth;\r\n        let columnBounds = columnDom.getBoundingClientRect ();\r\n        let columnWidth = columnDom.clientWidth;\r\n\r\n        // console.log ('Checking for collision between', cardDom, 'and', columnDom)\r\n\r\n        if (\r\n            cardBounds.right > columnBounds.x &&\r\n            cardBounds.x < columnBounds.right\r\n        ) {\r\n            return { cardBounds, cardWidth, columnBounds, columnWidth }\r\n        }\r\n    }\r\n\r\n    checkIceAmount (iceColumns) {\r\n        let amountOfIce = 0;\r\n\r\n        iceColumns.forEach ((column) => { if (column.ice === true) { amountOfIce++ } })\r\n\r\n        return amountOfIce\r\n    }\r\n\r\n    // Overloading this functions responsibilities for the sake of time\r\n    checkIceDependentSpecies () {\r\n        this.setState ((prevState) => {\r\n            // get ice amount\r\n            let state = Helper.clone (this.state);\r\n            let iceColumns = state.iceColumns;\r\n            let iceAmount = this.checkIceAmount (iceColumns);\r\n\r\n            // Iterate over ice columns and splice out any animals that need\r\n            // more ice than what is available\r\n            iceColumns.forEach ((column, colIndex) => {\r\n\r\n                // console.log ('CHECKING ICE COLUMN????')\r\n\r\n                let earliestIndex = null;\r\n                column.children.forEach ((child, index) => {\r\n                    // console.log (child.name, '===', Config.cards.phytoPlankton.name, '?', 'and column is ice?', column.ice)\r\n                    // console.log ('Looking at', child.name, 'that needs', child.needsIce, 'ice to live')\r\n                    if (child.needsIce > iceAmount && earliestIndex === null) {\r\n                        earliestIndex = index;\r\n                    }\r\n                    else if (child.name === Config.cards.phytoPlankton.name && column.ice === true) {\r\n                        earliestIndex = -1\r\n                    }\r\n                    else if (child.name === Config.cards.iceAlgea.name && column.ice === false) {\r\n                        earliestIndex = -1\r\n                    }\r\n                })\r\n\r\n                // console.log ('FOUND AN EARLIEST INDEX?', earliestIndex)\r\n\r\n                if (earliestIndex != null) {\r\n                    // let end = column.children.length - 1;\r\n                    // Need to iterate backwards because fadeOutFunction splices cards from columns\r\n                    // for (let i = end; i >= earliestIndex; i--) {\r\n                    //     console.log ('!!!')\r\n                    //     console.log ('fading out card...', i)\r\n                    //     console.log ('!!!')\r\n                    //     this.fadeOutCardOutOfPlay ('iceColumns', i, colIndex)\r\n                    // }\r\n\r\n                    let cardsToFade = Helper.clone (column.children);\r\n\r\n                    column.children.splice (earliestIndex, column.children.length);\r\n\r\n                    cardsToFade.forEach ((crdToFade, index) => {\r\n                        if (index >= earliestIndex) {\r\n                            window.setTimeout (() => {\r\n                                this.fadeOutCardOutOfPlay (crdToFade)\r\n                            })\r\n                        }\r\n                    })\r\n                }\r\n            })\r\n\r\n            return { iceColumns }\r\n        }, () => {\r\n            this.setState ((prevState) => {\r\n                let iceColumns = Helper.clone (prevState.iceColumns)\r\n                iceColumns = this.checkIceRemovedSurvivors (prevState.iceColumns);\r\n\r\n                return { iceColumns }\r\n            })\r\n        })\r\n    }\r\n\r\n    // checkIfAnimalsNeedIce (iceColumns) {\r\n    //     let amountOfIce = this.checkIceAmount (iceColumns);\r\n    //\r\n    //     iceColumns.forEach ((column) => {\r\n    //         let killIndex = 99;\r\n    //         // Iterate over cards in column and look for any\r\n    //         // cards that can't live anymore\r\n    //         column.children.forEach ((child, index) => {\r\n    //             // Remove the earliest match in the chain\r\n    //             if (\r\n    //                 child.needsIce > amountOfIce &&\r\n    //                 killIndex > index\r\n    //             ) {\r\n    //                 killIndex = index;\r\n    //             }\r\n    //         })\r\n    //\r\n    //         //Send those cards to the shadow realm\r\n    //         column.children.splice (killIndex, column.children.length);\r\n    //     })\r\n    //\r\n    //     return iceColumns;\r\n    // }\r\n\r\n    checkIfCardCanGoInColumn (crd) {\r\n        //find where our card is\r\n        let card = this.findCard ();\r\n\r\n        if (crd) { card = crd }\r\n\r\n        // Do nothing if no card is found\r\n        if (!card) { return }\r\n\r\n        let iceAmount = this.checkIceAmount (this.state.iceColumns);\r\n\r\n        console.log ('Card that is being moved:', card);\r\n\r\n        let cardDom = document.querySelector ('#' + card.id);\r\n\r\n        let collisions = [];\r\n\r\n        this.state.iceColumns.forEach ((iceColumn, index) => {\r\n            let columnDom = document.querySelector ('#' + iceColumn.id);\r\n\r\n            let collision = this.checkForCollision (cardDom, columnDom)\r\n            if (collision) {\r\n                collision.iceColumnIndex = index;\r\n                collisions.push (collision)\r\n            }\r\n        })\r\n\r\n        let selectedColumn = null;\r\n\r\n        if (collisions.length === 1) {\r\n            // Don't bother checking for most matched column,\r\n            //just use the one that was collided with\r\n            selectedColumn = collisions [0];\r\n        }\r\n        else if (collisions.length > 1) {\r\n            // compare every collision against each other\r\n            // to see which column the card is most over\r\n            // ...though I'm not sure that a card is large\r\n            // enought to cover more than 2 columns, but still...\r\n\r\n            // for now, just assume that only two collisions are happening\r\n            let cardCenter = collisions [0].cardBounds.x + (collisions [0].cardWidth / 2);\r\n            let columnACenter = collisions [0].columnBounds.x + (collisions [0].columnWidth / 2);\r\n            let columnBCenter = collisions [1].columnBounds.x + (collisions [1].columnWidth / 2);\r\n            let result = this.findClosestColumn (cardCenter, columnACenter, columnBCenter);\r\n\r\n            if (result === 1) { selectedColumn = collisions [0] }\r\n            else if (result === 2) { selectedColumn = collisions [1] }\r\n        }\r\n\r\n        // Now that we have the closest match\r\n        // See if that card can even go into that column\r\n        // ...\r\n        if (card.needsIce > iceAmount) { return false }\r\n\r\n        if (selectedColumn) {\r\n\r\n            // Finally return the result\r\n            return selectedColumn\r\n        }\r\n    }\r\n\r\n    checkIfFeedingPredator (card, event) {\r\n        console.log ('Checking for viable predator targets')\r\n        // iterate over apex predator doms\r\n        let predatorDoms = [\r\n            document.getElementById (APEX_PREDATOR_SLOT_ID_ZERO),\r\n            document.getElementById (APEX_PREDATOR_SLOT_ID_ONE),\r\n            document.getElementById (APEX_PREDATOR_SLOT_ID_TWO),\r\n            document.getElementById (APEX_PREDATOR_SLOT_ID_THREE),\r\n        ]\r\n\r\n        // don't bother checking doms that don't have predators\r\n        if (this.state.drawnApexPredators.length < 4) {\r\n            let start = this.state.drawnApexPredators.length;\r\n            let end = 4;\r\n\r\n            console.log ('splicing from', start)\r\n\r\n            predatorDoms.splice (start, end);\r\n        }\r\n\r\n        // console.log (predatorDoms)\r\n\r\n        // If there are no predators to check against, then don't do the rest\r\n        if (predatorDoms.length === 0) { return null }\r\n\r\n        let cardDom = document.getElementById (card.id);\r\n\r\n        let inDiet = false;\r\n\r\n        let crd = card;\r\n        if (this.state.otherCardsBeingDragged.length > 0) {\r\n            let cardParent = this.state.cardParent;\r\n            let iceCols = this.state.iceColumns\r\n            let iceCol\r\n\r\n            iceCols.forEach ((col) => { if (col.id === cardParent) { iceCol = col; } })\r\n\r\n            crd = iceCol.children [iceCol.children.length - 1]\r\n            console.log ('Top card:',crd)\r\n        }\r\n\r\n        // Iterate over doms and check for a collision\r\n        let collision, closestCollision, colIndex;\r\n        predatorDoms.forEach ((dom, index) => {\r\n            collision = this.checkForMouseCollision (event, dom)\r\n\r\n            if (!closestCollision) {\r\n                closestCollision = collision;\r\n                colIndex = index;\r\n\r\n                console.log (this.state.drawnApexPredators [index])\r\n\r\n                // Also check to see if the predator can eat this animal\r\n                if (\r\n                    this.state.drawnApexPredators [index] &&\r\n                    this.state.drawnApexPredators [index].diet\r\n                ) {\r\n                    this.state.drawnApexPredators [index].diet.forEach ((species) => {\r\n                        console.log ('comparing', species.fullName, 'to', crd.name)\r\n                        if (species.fullName === crd.name) { inDiet = true }\r\n                    })\r\n                }\r\n            }\r\n        })\r\n\r\n        if (inDiet) {\r\n            return {closestCollision, colIndex}\r\n        }\r\n        else {\r\n            return false\r\n        }\r\n    }\r\n\r\n    checkForMouseCollision (mouseEvent, dom) {\r\n        let mouseX = mouseEvent.pageX;\r\n        let mouseY = mouseEvent.pageY;\r\n\r\n        let domBounds = dom.getBoundingClientRect ();\r\n\r\n        let withinX = (mouseX > domBounds.left && mouseX < domBounds.right);\r\n        let withinY = (mouseY > domBounds.top && mouseY < domBounds.bottom)\r\n\r\n        return (withinX && withinY)\r\n    }\r\n\r\n    checkIfSpeciesCanGoInColumn (card, column) {\r\n        // Look at the top most child to see if the card being dropped can eat\r\n        // that card, if there are no children, check if this card needs ice\r\n        // if that card needs ice, iterate over all the ice columns to see\r\n        // if enough ice exists\r\n\r\n        // console.log (card.name, Config.cards.iceAlgea.name)\r\n\r\n        if (column.children.length) {\r\n            let children = column.children;\r\n            let topChild = children [children.length - 1];\r\n            // console.log ('check one')\r\n\r\n            let eatsThatAnimal = false;\r\n\r\n            card.diet.forEach ( (item) => {\r\n                if (item.name === topChild.symbol) { eatsThatAnimal = true }\r\n            })\r\n\r\n            return eatsThatAnimal;\r\n        }\r\n        else if (card.needsIce > 0 && card.diet.length === 0 && card.name != Config.cards.iceAlgea.name) {\r\n            let columns = this.state.iceColumns\r\n\r\n            // console.log ('check two')\r\n\r\n            let currentIce = this.checkIceAmount ();\r\n\r\n            return currentIce >= card.needsIce\r\n        }\r\n        else if (column.children.length === 0) {\r\n            // check to see if this is phyto plankton or ice algea\r\n            // Ice algea can only go on ice and phyto plankton can only go on water\r\n\r\n            if (card.name !== Config.cards.iceAlgea.name &&\r\n                card.name !== Config.cards.phytoPlankton.name\r\n            ) { return false }\r\n\r\n            let isIceAlgea = false;\r\n\r\n            if (card.name === Config.cards.iceAlgea.name) {\r\n                isIceAlgea = true;\r\n            }\r\n\r\n            // console.log ('Trying to put', card.name, 'in a frozen column?', column.ice)\r\n\r\n            return ( isIceAlgea === column.ice );\r\n        }\r\n        else if (card.diet.length === 0 && card.needsIce === 0) {\r\n            // console.log ('Check four')\r\n            return true\r\n        }\r\n    }\r\n\r\n    checkValidTargetForEvent (crd) {\r\n        // Looks at the column the whale was dropped in and if it has\r\n        // any of the valid targets to hunt\r\n        let result = false;\r\n\r\n        let eventCard = this.findCard ();\r\n\r\n        let columnCheck = false;\r\n\r\n        if (eventCard) {\r\n            columnCheck = this.checkIfCardCanGoInColumn (eventCard);\r\n        }\r\n\r\n        let iceColumnIndex\r\n        let lowestIndex = 9999;\r\n        // We are dragging and dropping a card\r\n        if (columnCheck) {\r\n            if (crd && !eventCard) { eventCard = crd; }\r\n            if (!crd && !eventCard) { return result; }\r\n\r\n            iceColumnIndex = columnCheck.iceColumnIndex;\r\n\r\n            let iceColumn = this.state.iceColumns [iceColumnIndex]\r\n\r\n            if (eventCard.validTargets === undefined) { return result }\r\n\r\n            if (iceColumn && iceColumn.children.length) {\r\n                iceColumn.children.forEach ((child, index) => {\r\n                    if (eventCard && eventCard.validTargets) {\r\n                        eventCard.validTargets.forEach ((validTargetName) => {\r\n                            if (child.name === validTargetName && index < lowestIndex) {\r\n                                lowestIndex = index\r\n                            }\r\n                        })\r\n                    }\r\n                })\r\n            }\r\n        }\r\n        // This is a check across every ice column\r\n        else {\r\n            let iceColumns = this.state.iceColumns\r\n            eventCard = crd;\r\n\r\n            iceColumns.forEach ((iceColumn) => {\r\n                iceColumn.children.forEach ((child, index) => {\r\n                    if (eventCard && eventCard.validTargets) {\r\n                        eventCard.validTargets.forEach ((validTargetName) => {\r\n                            if (child.name === validTargetName && index < lowestIndex) {\r\n                                lowestIndex = index\r\n                            }\r\n                        })\r\n                    }\r\n                })\r\n            })\r\n        }\r\n\r\n\r\n        if (lowestIndex !== 9999) {\r\n\r\n            result = {\r\n                targetColumnIndex: iceColumnIndex,\r\n                targetCardIndex: lowestIndex\r\n            }\r\n        }\r\n\r\n        return result\r\n    }\r\n\r\n    // Looks for which card the \"Protect a Species\" card is most\r\n    // on top of\r\n    checkWhichCardToProtect (event) {\r\n        let result = false;\r\n        // Get our card, which we already know is our protect-a-species card\r\n        let card = this.findCard ();\r\n        // See which column this card is going to land it\r\n        let targetColumnIndex = this.checkIfCardCanGoInColumn ().iceColumnIndex\r\n        let column = this.state.iceColumns [targetColumnIndex];\r\n\r\n        if (column && column.children.length) {\r\n            // The discard deck is always a fixed position from the top of the screen\r\n            // So offset... should probably update this in the future but time in sparse atm\r\n            let targetY;\r\n\r\n            if (event && event.pageY) { targetY = event.pageY - 120; }\r\n            else { targetY = card.position.y + 350; }\r\n\r\n            let closestY = 9999;\r\n            let closestIndex = null;\r\n            let y;\r\n\r\n            // Iterate over children of that column\r\n            column.children.forEach ( (child, index) => {\r\n                // 35 pixels is about the height of overlap on a card\r\n                // this also assumes we are getting out Y from the mouse\r\n                y = Math.abs ((child.position.y + 35) - targetY);\r\n\r\n                if (y < closestY) {\r\n                    closestY = y;\r\n                    closestIndex = index;\r\n                }\r\n            })\r\n\r\n            result = {\r\n                targetColumnIndex,\r\n                targetCardIndex: closestIndex,\r\n                targetCard: column.children [closestIndex]\r\n            }\r\n\r\n            let validCard = false;\r\n            Config.cards.protectASpecies.validTargets.forEach ((name) => {\r\n                if (name === result.targetCard.name) { validCard = true; }\r\n            })\r\n\r\n            if (!validCard) { result = false }\r\n        }\r\n\r\n        return result\r\n    }\r\n\r\n    // ---\r\n    // ---\r\n    // ---\r\n//      Rendering Functions\r\n    // ---\r\n    // ---\r\n    // ---\r\n\r\n    collectIceColumnDomRef (index, dom) { this._iceColumnDoms [index] = dom; }\r\n\r\n    createIceColumn (item, index) {\r\n        // console.log ('Rendering ice columns with protected species name:', this.state.protectedSpeciesName)\r\n        return (\r\n            <IceColumn\r\n                id={item.id}\r\n                ref={(dom) => { this.collectIceColumnDomRef (index, dom); }}\r\n                ice={item.ice}\r\n                onMouseDownOnCard={this.onMouseDownOnCard}\r\n                protectedSpeciesName={this.state.protectedSpeciesName}\r\n                // onDoubleClick={this.onDoubleClick}\r\n            >\r\n                {item.children}\r\n            </IceColumn>\r\n        )\r\n    }\r\n\r\n    renderFadingOutCards (data, index) {\r\n        if (data === null) {\r\n            return (<span></span>)\r\n        }\r\n\r\n        // console.log ('Rendering card with an opacity of:', data.opacity)\r\n\r\n        return (\r\n            <Card\r\n                key={index}\r\n                id={data.id}\r\n                name={data.name}\r\n                img={data.img}\r\n                zIndex={data.zIndex}\r\n                isActive={data.isActive}\r\n                position={data.position}\r\n                isFaceDown={data.isFaceDown}\r\n                isDiscarded={data.isDiscarded}\r\n                isPlacedInColumn={data.isPlacedInColumn}\r\n                isProtected={data.isProtected}\r\n                type={data.type}\r\n                index={index}\r\n                diet={data.diet}\r\n                iceDestroyed={data.iceDestroyed}\r\n                symbol={data.symbol}\r\n                facts={data.facts}\r\n                trophicLevel={data.trophicLevel}\r\n                needsIce={data.needsIce}\r\n                validTargets={data.validTargets}\r\n                footer={data.footer}\r\n                blockerText={data.blockerText}\r\n                opacity={data.opacity}\r\n\r\n                onMouseDown={() => {}}\r\n                protectedSpeciesName={() => {}}\r\n            />\r\n        )\r\n    }\r\n\r\n    startTour () {\r\n        window.startTour ();\r\n    }\r\n\r\n    render () {\r\n        let leftColumnElements, rightColumnElements\r\n\r\n        let stopDrawCover = (\r\n            <div>\r\n                {this.state.showStopDrawCover === true &&\r\n                    <div className=\"stop-drawing-cards\">\r\n                        {   ('blockerText' in this.state.stopperCard) &&\r\n                            this.state.stopperCard.blockerText.length > 0 &&\r\n                            <p>{this.state.stopperCard.blockerText}</p>\r\n                        }\r\n                        {   (!('blockerText' in this.state.stopperCard) ||\r\n                            this.state.stopperCard.blockerText.length === 0) &&\r\n                            <p>Event card must be played to continue</p>\r\n                        }\r\n                    </div>\r\n                }\r\n            </div>\r\n        )\r\n\r\n        let deck = (\r\n            <Deck\r\n            name=\"Draw\"\r\n            onClick={this.flipAndMoveCard} protectedSpeciesName={this.state.protectedSpeciesName}\r\n            >\r\n                { this.state.deck }\r\n            </Deck>\r\n        )\r\n\r\n        let discardDeck = (\r\n            <Deck\r\n                name=\"Play\"\r\n                onMouseDownOnCard={this.onMouseDownOnCard}\r\n                iceDestroyed={this.state.iceDestroyed}\r\n                protectedSpeciesName={this.state.protectedSpeciesName}\r\n                // onDoubleClick={this.onDoubleClick}\r\n            >\r\n                { this.state.discard }\r\n            </Deck>\r\n        )\r\n\r\n        let predatoryMammalSlots = (\r\n            <div className=\"apex-card-holder\">\r\n\r\n                <div className=\"header-bar\">\r\n                    <p>Hunters</p>\r\n                </div>\r\n\r\n                <div className=\"apex-card-row\">\r\n                    <ApexCardSlot\r\n                        id={APEX_PREDATOR_SLOT_ID_ZERO}\r\n                        // onDoubleclick={this.onDoubleclick}\r\n                        onMouseDownOnCard={this.onMouseDownOnCard}\r\n                        givenFoodChain={this.state.apexPredatorFoodChains.zero}\r\n                    >\r\n                        {this.state.drawnApexPredators [0]}\r\n                    </ApexCardSlot>\r\n                    <ApexCardSlot\r\n                        id={APEX_PREDATOR_SLOT_ID_ONE}\r\n                        // onDoubleclick={this.onDoubleclick}\r\n                        onMouseDownOnCard={this.onMouseDownOnCard}\r\n                        givenFoodChain={this.state.apexPredatorFoodChains.one}\r\n                    >\r\n                        {this.state.drawnApexPredators [1]}\r\n                    </ApexCardSlot>\r\n                </div>\r\n                <div className=\"apex-card-row\">\r\n                    <ApexCardSlot\r\n                        id={APEX_PREDATOR_SLOT_ID_TWO}\r\n                        // onDoubleclick={this.onDoubleclick}\r\n                        onMouseDownOnCard={this.onMouseDownOnCard}\r\n                        givenFoodChain={this.state.apexPredatorFoodChains.two}\r\n                    >\r\n                        {this.state.drawnApexPredators [2]}\r\n                    </ApexCardSlot>\r\n                    <ApexCardSlot\r\n                        id={APEX_PREDATOR_SLOT_ID_THREE}\r\n                        // onDoubleclick={this.onDoubleclick}\r\n                        onMouseDownOnCard={this.onMouseDownOnCard}\r\n                        givenFoodChain={this.state.apexPredatorFoodChains.three}\r\n                    >\r\n                        {this.state.drawnApexPredators [3]}\r\n                    </ApexCardSlot>\r\n                </div>\r\n            </div>\r\n        )\r\n\r\n        switch (Config.layout) {\r\n            case 1:\r\n                leftColumnElements = [stopDrawCover, deck, discardDeck]\r\n                rightColumnElements = [predatoryMammalSlots]\r\n                break;\r\n            case 2:\r\n                leftColumnElements = [predatoryMammalSlots]\r\n                rightColumnElements = [stopDrawCover, deck, discardDeck]\r\n                break;\r\n            default:\r\n                console.warn ('Unsupported config layout detected')\r\n        }\r\n\r\n        let totalScore = this.state.speciesScore + this.state.iceScore + this.state.bonusScore;\r\n\r\n        return (\r\n            <div className=\"eco-chains\">\r\n                <div className=\"ice-image-left\"></div>\r\n                <div className=\"ice-image-right\"></div>\r\n                <div className=\"top row\">\r\n                    <div className=\"left column\">\r\n                        <div className=\"header\">\r\n                            <div className=\"logo\"></div>\r\n                            <div className=\"divider\"></div>\r\n                            <div className=\"title\">Arctic Futures</div>\r\n                        </div>\r\n                    </div>\r\n                    <div className=\"middle column\">\r\n                        <div className=\"help\">\r\n                            <div className=\"quickstart-guide\" onClick={ () => { try { window.startTour (); } catch (error) { console.error (error) } } }>\r\n                                <img src=\"./play-circle.svg\" />\r\n                                <span>Quickstart Guide</span>\r\n                            </div>\r\n                            <a href=\"/ecochains/how-to-play/index.html\" target=\"_blank\">\r\n                                <div className=\"instructions\">\r\n                                    <img src=\"./doc.svg\" />\r\n                                    <span>Instructions</span>\r\n                                </div>\r\n                            </a>\r\n                        </div>\r\n                        <div className=\"scores\">\r\n                            <ScoreKeeper label=\"Species\" score={this.state.speciesScore}/>\r\n                            <ScoreKeeper label=\"Ice\" score={this.state.iceScore}/>\r\n                            <ScoreKeeper label=\"Action\" score={this.state.bonusScore}/>\r\n                        </div>\r\n                    </div>\r\n                    <div className=\"right column\">\r\n                        <ScoreKeeper type=\"total\" label=\"Total Score:\" score={ this.state.speciesScore + this.state.iceScore + this.state.bonusScore }/>\r\n                        {this.state.hideHelpButton === false &&\r\n                            <button class=\"help-button\" onClick={this.startTour}> Help </button>\r\n                        }\r\n\r\n                    </div>\r\n\r\n                </div>\r\n\r\n                <div className=\"middle row\">\r\n                    <div className=\"left column\">\r\n                        <div className=\"background\"></div>\r\n                        { leftColumnElements }\r\n                    </div>\r\n                    <div className=\"center column\">\r\n                        <div className=\"header-bar\"><p>Environment</p></div>\r\n                        { this.state.iceColumns.map ( this.createIceColumn ) }\r\n                    </div>\r\n                    <div className=\"right column\">\r\n                        { rightColumnElements }\r\n                    </div>\r\n                </div>\r\n\r\n                {this.state.deck.length === 0 &&\r\n                 this.state.showEndGameScreen === false &&\r\n                    <div\r\n                        className=\"end-game-button flash\"\r\n                        onClick={this.endGame}\r\n                    >\r\n                    <p>\r\n                        FINISH GAME\r\n                    </p>\r\n                    </div>\r\n                }\r\n\r\n                <div id=\"fade-out\" style={{position: 'absolute', top: 0, left: 0}}>\r\n                    {this.state.fadingOut.map (this.renderFadingOutCards)}\r\n                </div>\r\n\r\n                {this.state.showInspectionModal === true &&\r\n                    <CardModal\r\n                        card={this.state.cardToInspect}\r\n                        onClick={this.closeModal}\r\n                    />\r\n                }\r\n\r\n                {this.state.showEndGameScreen === true &&\r\n                    <div className=\"end-game-modal\">\r\n                        <div className=\"overlay\">\r\n                            <div className=\"end-game-modal-content\">\r\n                                <div className=\"modal-head\">\r\n                                    Final results\r\n                                </div>\r\n\r\n                                <div className=\"modal-body\">\r\n                                    <div className=\"ranks\">\r\n                                        <div class=\"title\">\r\n                                            <p>Points & Ranks</p>\r\n                                        </div>\r\n                                        <div class=\"results\">\r\n                                            <p>{'<'} 20 Keep trying!</p>\r\n                                            <p>20-29 Competent</p>\r\n                                            <p>30-39 Expert</p>\r\n                                            <p>40+ Steward</p>\r\n                                        </div>\r\n                                    </div>\r\n                                    <div className=\"player-rank\">\r\n                                        <p>Your rank...</p>\r\n                                    </div>\r\n                                    <div class=\"player-scores\">\r\n                                        <ScoreKeeper label=\"Species\" score={this.state.speciesScore}/>\r\n                                        <ScoreKeeper label=\"Ice\" score={this.state.iceScore}/>\r\n                                        <ScoreKeeper label=\"Action\" score={this.state.bonusScore}/>\r\n                                    </div>\r\n                                    <div className=\"final-score\">\r\n                                        <ScoreKeeper type=\"total\" label=\"Total Score\" score={ this.state.speciesScore + this.state.iceScore + this.state.bonusScore }/>\r\n                                    </div>\r\n                                    <div>\r\n\r\n                                        <div className=\"player-rank\">\r\n                                            {totalScore < 20 &&\r\n                                                <h1>Keep trying!</h1>\r\n                                            }\r\n                                            {totalScore < 30 &&\r\n                                            totalScore >= 20 &&\r\n                                                <h1>Competent</h1>\r\n                                            }\r\n                                            {totalScore < 40 &&\r\n                                            totalScore >= 30 &&\r\n                                                <h1>Expert</h1>\r\n                                            }\r\n                                            {totalScore >= 40 &&\r\n                                                <h1>Steward</h1>\r\n                                            }\r\n                                        </div>\r\n                                    </div>\r\n                                </div>\r\n\r\n                                <div className=\"modal-footer\">\r\n                                    <div\r\n                                        className=\"new-game-button\"\r\n                                        onClick={this.newGame}\r\n                                    >\r\n                                        <p>New Game</p>\r\n                                    </div>\r\n                                </div>\r\n                            </div>\r\n                        </div>\r\n                    </div>\r\n                }\r\n\r\n            </div>\r\n        )\r\n    }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport * as serviceWorker from './serviceWorker';\r\n\r\nimport EcoChains from './EcoChains';\r\n\r\nReactDOM.render(\r\n  <React.StrictMode>\r\n      <EcoChains />\r\n  </React.StrictMode>,\r\n  document.getElementById('root')\r\n);\r\n\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: https://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n"],"sourceRoot":""}