{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./app/javascript/packs/CandyManiaUnityBridge.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","keys","hasDontEnumBug","toString","propertyIsEnumerable","dontEnums","dontEnumsLength","length","obj","TypeError","prop","result","push","window","CandyManiaUnityBridge","this","version","_unityConnected","_messageQueue","_draining","_unityHandshakeCallback","undefined","_leaderboardRankCallback","_printDebugMessages","_dryRunEnabled","_gameName","_sfxVolume","_musicVolume","PostMessage","message","params","Error","uri","encodeURIComponent","join","Log","DrainQueue","JSON","stringify","shift","indexOf","close","location","href","encodeURI","setTimeout","console","log","error","Warn","warn","Handshake","Math","min","max","sfxVolume","musicVolume","SetOnHandshakeCallback","callback","UnityConnected","SetGameName","gameName","GetSfxVolume","SetSfxVolume","GetMusicVolume","SetMusicVolume","PostGameStarted","game","PostGameComplete","level","score","finalLevelComplete","PostGameOver","gameOver","PostLevelStarted","PostLevelComplete","PostPowerupUsed","powerup","PostCustomEvent","SubmitScore","GetLeaderboardRank","resultCallback","self","rank","random","floor","OnGetLeaderboardRankComplete","Exit","SetDebugMessagesEnabled","enabled","EnableDryRun"],"mappings":"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","file":"js/CandyManiaUnityBridge-09492c1c1bc6305009f5.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/packs/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 173);\n","/**\n * Summary:\n * - The Handshake() function is called by Unity when connecting to the javascript. It should connect as soon as the page content has loaded but may be delayed slightly.\n * If you are attempting to call functions very early in the page lifecycle and are getting warnings about Unity not being connected yet, use CandyManiaUnityBridge.SetOnHandshakeCallback(callback) to wait for the connection event.\n *\n * - The game should have an 'Exit' button somewhere in the main menu that will be used to close the game window and exit back to the Unity wrapper. Tapping it should call the CandyManiaUnityBridge.Exit() function.\n * Check if CandyManiaUnityBridge.UnityConnected() returns true to tell whether you should show/hide this UI element.\n *\n * - Call CandyManiaUnityBridge.SetGameName(gameName) to set the game name to something unique before posting any messages. This is used to group all messages posted by the same game.\n *\n * - The getter/setter functions for SFX and music volumes are only valid once Unity has connected and shouldn't be used if CandyManiaUnityBridge.UnityConnected() returns false.\n * SFX/Music volumes should be multiplied by these values if Unity is connected and the values returned range from 0 to 1.\n *\n * - The following functions should be called at the appropriate times similar to using analytics calls. They will simply be ignored if Unity has not connected so there is no need to check UnityConnected() before calling them.\n * PostGameStarted(): Call this at the beginning of every play session. I.e: Starting from the main menu or resetting to level 1 from a game over. This should be paired with a call to PostGameComplete() or PostGameOver().\n * PostGameComplete(level, score, finalLevelComplete): Call this whenever the player leaves a play session either by completing the game or exiting via the pause menu or some other way.\n *\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t Make sure to set the 'finalLevelComplete' parameter to true if the player beat the game.\n *\t\t PostGameOver(level, score): Call this when the player has lost and gotten a game over or otherwise failed the play session.\n *\t\t PostLevelStarted(level): Call this every time the player starts a new level.\n *\t\t PostLevelComplete(level, score): Call this every time the player completes a level.\n *\t\t SubmitScore(score): Call this to submit the final score to the Leaderboard. This will open a new window in the Unity wrapper that will handle name entry and validation\n *\t\t Exit(): Call this to close the WebView window and return to the Unity wrappers main menu.\n */\n\n\n// Object.keys() polyfill\n// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys\nif (!Object.keys) {\n Object.keys = (function() {\n 'use strict';\n var hasOwnProperty = Object.prototype.hasOwnProperty,\n hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),\n dontEnums = [\n 'toString',\n 'toLocaleString',\n 'valueOf',\n 'hasOwnProperty',\n 'isPrototypeOf',\n 'propertyIsEnumerable',\n 'constructor'\n ],\n dontEnumsLength = dontEnums.length;\n\n return function(obj) {\n if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {\n throw new TypeError('Object.keys called on non-object');\n }\n\n var result = [], prop, i;\n\n for (prop in obj) {\n if (hasOwnProperty.call(obj, prop)) {\n result.push(prop);\n }\n }\n\n if (hasDontEnumBug) {\n for (i = 0; i < dontEnumsLength; i++) {\n if (hasOwnProperty.call(obj, dontEnums[i])) {\n result.push(dontEnums[i]);\n }\n }\n }\n return result;\n };\n }());\n}\n\n// Note: Since the Unity web view plugin intercepts the location.href value to parse messages, you can not send multiple messages on the same frame.\n// Multiple messages posted on the same frame are queued and sent at a rate of about 30 messages per second.\nwindow.CandyManiaUnityBridge = new function() {\n\tthis.version = \"1.3\";\n\tvar that = this;\t\t// Not sure why this is here but the internet told me to put it here to avoid some kind of nebulous issue with 'this' inside private functions.\n\tvar _unityConnected = false;\n\tvar _messageQueue = [];\n\tvar _draining = false;\n\tvar _unityHandshakeCallback = undefined;\n\tvar _leaderboardRankCallback = undefined;\n\tvar _printDebugMessages = false;\n\tvar _dryRunEnabled = false;\n\n\tvar _gameName = \"__undefined__\";\n\tvar _sfxVolume = 1;\n\tvar _musicVolume = 1;\n\n\t/**\n\t * Called by Unity when the WebView initializes to tell us that it's safe to send candymania:// messages. Do not call this manually from the javascript source.\n\t *\n\t * @param {object} params - Any additional parameters sent in by the Unity system.\n\t */\n\tthis.Handshake = function(params) {\n\t\tif(!_unityConnected) {\n\t\t\t_unityConnected = true;\n\n\t\t\tif(params !== undefined) {\n\t\t\t\tif(params.hasOwnProperty(\"sfxVolume\")) _sfxVolume = Math.min(Math.max(params.sfxVolume, 0), 1);\n\t\t\t\tif(params.hasOwnProperty(\"musicVolume\")) _musicVolume = Math.min(Math.max(params.musicVolume, 0), 1);\n\t\t\t}\n\n\t\t\tLog(\"Unity Handshake received with parameters: \" + JSON.stringify(params, null, 1));\n\t\t\tif(_unityHandshakeCallback !== undefined) _unityHandshakeCallback();\n\t\t}\n\t};\n\n\t/**\n\t * Sets a callback that is fired when Unity successfully sends its handshake message.\n\t * Unity will typically handshake within the first 0.3 seconds but it may be possible your page has loaded from cache before that happens.\n\t * If you're attempting to use this API inside the initial startup of the page you may want to hook into this to wait for Unity to connect before calling things like GetSfxVolume().\n\t *\n\t * @param {function} callback - The callback function to fire when Unity connects.\n\t */\n\tthis.SetOnHandshakeCallback = function(callback) {\n\t\tif(typeof callback === \"function\" || typeof callback === \"undefined\") _unityHandshakeCallback = callback;\n\t};\n\n\t/**\n\t * Check if Unity has been initialized and connected to the javascript.\n\t *\n\t * @return {boolean} True if Unity is connected and ready to receive messages. False otherwise.\n\t */\n\tthis.UnityConnected = function() {\n\t\treturn _unityConnected;\n\n\t};\n\n\t/**\n\t * Sets the name of the game to use as a key for all future calls to the Unity system. Should be called once before all other calls to this API.\n\t *\n\t * @param {string} gameName - The game name to use.\n\t */\n\tthis.SetGameName = function(gameName) {\n\t\tif(typeof _gameName === \"string\") {\n\t\t\t_gameName = gameName;\n\t\t\tLog(\"GameName set to: \" + _gameName);\n\t\t} else {\n\t\t\tError(\"Attempted to call SetGameName with an invalid type of '\" + (typeof gameName) + \"'. gameName must be a string.\");\n\t\t}\n\t};\n\n\t/**\n\t * Gets the global SFX volume synched with the Unity wrapper. Multiply your sound effect volume by this value if UnityConnected() returns true.\n\t */\n\tthis.GetSfxVolume = function() {\n\t\tif(!_unityConnected) {\n\t\t\tWarn(\"Attempted to retrieve the global SFX volume before Unity has connected to the javascript. This value should only be used if UnityConnected() returns true.\");\n\t\t}\n\n\t\tLog(\"Get sfx volume = \" + _sfxVolume);\n\t\treturn _sfxVolume;\n\t}\n\n\t/**\n\t * Sets the global SFX volume and synchs it with the Unity wrapper. Only valid if UnityConnected() returns true.\n\t *\n\t * @param {number} value - The sfx volume to use. Clamped from 0 to 1.\n\t */\n\tthis.SetSfxVolume = function(value) {\n\t\tif(typeof value === \"number\") {\n\t\t\t_sfxVolume = Math.min(Math.max(value, 0), 1);\n\t\t\tLog(\"Current sfx volume set to: \" + _sfxVolume);\n\t\t} else {\n\t\t\tError(\"Attempted to call SetSfxVolume with an invalid value. Value must be a number.\");\n\t\t}\n\n\t\tif(!_unityConnected) {\n\t\t\tWarn(\"SetSfxVolume called before Unity has connected to the javascript. SFX volume will not be saved or synched with Unity.\");\n\t\t}\n\n\t\tPostMessage(\"setsfxvolume\", { value: _sfxVolume });\n\t}\n\n\t/**\n\t * Gets the global music volume synched with the Unity wrapper. Multiply your game music volume by this value if UnityConnected() returns true.\n\t */\n\tthis.GetMusicVolume = function() {\n\t\tif(!_unityConnected) {\n\t\t\tWarn(\"Attempted to retrieve the global music volume before Unity has connected to the javascript. This value should only be used if UnityConnected() returns true.\");\n\t\t}\n\n\t\tLog(\"Get music volume = \" + _musicVolume);\n\t\treturn _musicVolume;\n\t}\n\n\t/**\n\t * Sets the global music volume and synchs it with the Unity wrapper. Only valid if UnityConnected() returns true.\n\t *\n\t * @param {number} value - The music volume to use. Clamped from 0 to 1.\n\t */\n\tthis.SetMusicVolume = function(value) {\n\t\tif(typeof value === \"number\") {\n\t\t\t_musicVolume = Math.min(Math.max(value, 0), 1);\n\t\t\tLog(\"Current music volume set to: \" + _musicVolume);\n\t\t} else {\n\t\t\tError(\"Attempted to call SetMusicVolume with an invalid value. Value must be a number.\");\n\t\t}\n\n\t\tif(!_unityConnected) {\n\t\t\tWarn(\"SetMusicVolume called before Unity has connected to the javascript. Music volume will not be saved or synched with Unity.\");\n\t\t}\n\n\t\tPostMessage(\"setmusicvolume\", { value: _musicVolume });\n\t}\n\n\t/**\n\t * Queue a message to Unity to indicate that a new gameplay session has started. I.e: Restarting from level 1 after a Game Over.\n\t */\n\tthis.PostGameStarted = function() {\n\t\tPostMessage(\"gamestart\", { game: _gameName });\n\t};\n\n\t/**\n\t * Queue a message to Unity to indicate that a gameplay session has ended. Call either this or PostGameOver to end a play session.\n\t *\n\t * @param {string} level - The final level that was reached during the gameplay session. This can be a numerical level, level id, or an empty string/undefined if level progression is not tracked.\n\t * @param {number} score - The final total score the player achieved in the gameplay session.\n\t * @param {boolean} finalLevelComplete - A boolean to indicate if the player completed the final level or exited the session before that point. Defaults to false if not provided.\n\t */\n\tthis.PostGameComplete = function(level, score, finalLevelComplete) {\n\t\tif(typeof level !== \"number\" && typeof level !== \"string\") level = \"\";\n\t\tif(typeof score !== \"number\") score = 0;\n\t\tif(typeof finalLevelComplete !== \"boolean\") finalLevelComplete = false;\n\t\tPostMessage(\"gamecomplete\", { game: _gameName, level: level, score: score, finalLevelComplete: finalLevelComplete });\n\t};\n\n\t/**\n\t * Queue a message to Unity to indicate when a player has gotten a Game Over. Call either this or PostGameComplete to end a play session.\n\t *\n\t * @param {string} level - The final level that was reached during the gameplay session. This can be a numerical level, level id, or an empty string/undefined if level progression is not tracked.\n\t * @param {number} score - The final total score the player achieved in the gameplay session.\n\t */\n\tthis.PostGameOver = function(level, score) {\n\t\tif(typeof level !== \"number\" && typeof level !== \"string\") level = \"\";\n\t\tif(typeof score !== \"number\") score = 0;\n\t\tPostMessage(\"gamecomplete\", { game: _gameName, level: level, score: score, gameOver: true });\n\t};\n\n\t/**\n\t * Queue a message to Unity to indicate that the player has started a level in the game.\n\t *\n\t * @param {string} level - The level that was started. This can be a numerical level, level id, or an empty string/undefined if level progression is not tracked.\n\t */\n\tthis.PostLevelStarted = function(level) {\n\t\tif(typeof level !== \"number\" && typeof level !== \"string\") level = \"\";\n\t\tPostMessage(\"levelstart\", { game: _gameName, level: level });\n\t};\n\n\t/**\n\t * Queue a message to Unity to indicate that the player has completed a level in the game.\n\t *\n\t * @param {string} level - The level that was completed. This can be a numerical level, level id, or an empty string/undefined if level progression is not tracked.\n\t * @param {number} score - The score the player achieved in the level.\n\t */\n\tthis.PostLevelComplete = function(level, score) {\n\t\tif(typeof level !== \"number\" && typeof level !== \"string\") level = \"\";\n\t\tif(typeof score !== \"number\") score = 0;\n\t\tPostMessage(\"levelcomplete\", { game: _gameName, level: level, score: score });\n\t};\n\n\t/**\n\t * Queue a message to Unity to indicate the player has used a powerup. Used for achievement tracking.\n\t *\n\t * @param {string} name - The name or type of powerup that was used.\n\t */\n\tthis.PostPowerupUsed = function(name) {\n\t\tif(typeof name !== \"string\") name = \"unknown\";\n\t\tPostMessage(\"powerupused\", { game: _gameName, powerup: name });\n\n\n\t}\n\n\t/**\n\t * Queue a generic custom event to send to Unity. Custom events and their parameters should be confirmed with the Unity app developer to ensure it is accounted for and handled correctly.\n\t * This is used for tracking unique actions for a game that can apply to more specialized achievements.\n\t *\n\t * @param {string} name - The name of the event to send.\n\t * @param {object} params - (Optional) A dictionary of custom parameters to attach to the event. Parameters must be basic data types that are castable to a string: string, number, boolean\n\t */\n\tthis.PostCustomEvent = function(name, params) {\n\t\tif(typeof name !== \"string\") {\n\t\t\tWarn(\"Invalid name sent to PostEvent. Event name must be a string but function recieved type: \" + typeof name);\n\t\t} else {\n\t\t\tif(typeof params === \"object\" && params !== null) {\n\t\t\t\tif(params.hasOwnProperty(\"game\")) {\n\t\t\t\t\tWarn(\"PostCustomEvent parameters found a parameter named 'game'. 'game' is a reserved parameter and will be overwitten.\")\n\t\t\t\t}\n\n\t\t\t\tparams.game = _gameName;\n\t\t\t}\n\n\t\t\tPostMessage(name, params);\n\t\t}\n\n\t};\n\n\t/**\n\t * Opens the leaderboard submission screen in the Unity wrapper app which handles name entry and validation. This will exit out of the game and close the WebView so make sure data is saved before calling this.\n\t *\n\t * @param {number} score - The score the player achieved.\n\t */\n\tthis.SubmitScore = function(score) {\n\t\tif(typeof score !== \"number\") score = 0;\n\t\tPostMessage(\"submitscore\", { game: _gameName, score: score });\n\t};\n\n\t/**\n\t * Submits a score value and returns what rank that score would be assigned if it was submitted via the SubmitScore function. The call is asyncronous so the result will be sent to the resultCallback function. Usually returns within one or two frames.\n\t *\n\t * @param {number} score - The score to retrieve a projected rank for.\n\t * @param {function} resultCallback - A callback function which receives the resulting rank value from Unity. If this function receives a value of 0 it means the score is too low to place on the leaderboard.\n\t *\n\t */\n\tthis.GetLeaderboardRank = function(score, resultCallback) {\n\t\tif(typeof score !== \"number\") score = 0;\n\t\tif(typeof resultCallback === \"function\" || typeof resultCallback === \"undefined\") _leaderboardRankCallback = resultCallback;\n\t\tPostMessage(\"getleaderboardrank\", { game: _gameName, score: score });\n\n\t\tif(_dryRunEnabled) {\n\t\t\t// Dry Run mode. Add a delay to simulate the wait for Unity to return and send back a random rank between 0 and 25.\n\t\t\tvar self = this;\n\t\t\tsetTimeout(function() {\n\t\t\t\t// Weight the random rank so that it returns zero more often than other ranks. Helps to test showing/hiding UI elements based on whether they rank on the scoreboard or not.\n\t\t\t\tvar rank = Math.random() < 0.5 ? 0 : Math.floor(Math.random() * 26);\n\t\t\t\tself.OnGetLeaderboardRankComplete(rank);\n\t\t\t}, 66);\n\t\t}\n\t};\n\n\t/**\n\t * Called by Unity after it receives a GetLeaderboardRank message. Fires the saved callback method and sends it the rank returned from Unity. This function should not be called manually.\n\t *\n\t * @param {number} rank - The projected rank that the score sent to GetLeaderboardRank would receive if it is submitted to the leaderboard. Return 0 if the score is too low to rank on the leaderboard.\n\t */\n\tthis.OnGetLeaderboardRankComplete = function(rank) {\n\t\tLog(\"Received GetLeaderboardRank callback with rank = \" + rank);\n\t\tif(_leaderboardRankCallback !== undefined) _leaderboardRankCallback(rank);\n\t\t_leaderboardRankCallback = undefined;\n\t};\n\n\t/**\n\t * Queues a message to Unity that will exit and unload the game from the WebView.\n\t */\n\tthis.Exit = function() {\n\t\tPostMessage(\"exit\");\n\t};\n\n\t/**\n\t* Sets whether or not to print debug messages to the console\n\t*\n\t* @param {boolean} enabled - Whether to print debug messages or not.\n\t*/\n\tthis.SetDebugMessagesEnabled = function(enabled) {\n\t\tif(typeof enabled === \"boolean\") _printDebugMessages = enabled;\n\t};\n\n\t/**\n\t* !!! DEBUG ONLY. DO NOT CALL IN RELEASE CODE. !!!\n\t* Sets the API to run in 'Dry Run' mode. The script will act as if Unity has properly called the Handshake function and forces printing debug messages regardless of the SetDebugMessagesEnabled function.\n\t* Allows setting the default values for sfxVolume and musicVolume as if they were sent by Unity.\n\t* Can only be called once and will not function properly if Unity has already connected.\n\t*\n\t* @param {boolean} enabled - Whether to enable or disable Dry Run mode.\n\t* @param {number} sfxVolume - (Optional) The default sfxVolume to set when imitating the Unity Handshake. Defaults to 1 if not provided.\n\t* @param {number} musicVolume - (Optional) The default musicVolume to set when imitating the Unity Handshake. Defaults to 1 if not provided.\n\t*/\n\tthis.EnableDryRun = function(sfxVolume, musicVolume) {\n\t\t_dryRunEnabled = true;\n\n\t\tvar params = {};\n\t\tif(typeof sfxVolume === \"number\") params.sfxVolume = sfxVolume;\n\t\tif(typeof musicVolume === \"number\") params.musicVolume = musicVolume;\n\n\t\tthis.Handshake(params);\n\t};\n\n\t/**\n\t * Private function that constructs the proper URI for the message to Unity and adds it to the message queue. Does nothing if Unity has not sent the Handshake message.\n\t *\n\t * @param {string} message - The message to send to Unity\n\t * @param {object} params - A dictionary of parameters to append to the message URI.\n\t */\n\tfunction PostMessage(message, params) {\n\t\tif(_unityConnected) {\n\t\t\tif(_gameName === \"__undefined__\") {\n\t\t\t\tError(\"Attempted to send a Unity message without setting the game name. Please call SetGameName before posting any messages.\");\n\t\t\t} else {\n\t\t\t\tvar uri = \"candymania://\" + message;\n\t\t\t\tif(params !== undefined) {\n\t\t\t\t\tvar keys = Object.keys(params);\n\t\t\t\t\tvar p = [];\n\t\t\t\t\tfor(var i = 0; i < keys.length; i++) {\n\t\t\t\t\t\tp.push(keys[i] + \"=\" + encodeURIComponent(params[keys[i]]));\n\t\t\t\t\t}\n\t\t\t\t\turi += \"?\" + p.join(\"&\");\n\t\t\t\t}\n\n\t\t\t\tLog(\"Queued message: \" + uri);\n\t\t\t\t_messageQueue.push(uri);\n\n\t\t\t\tif(!_draining) {\n\t\t\t\t\t_draining = true;\n\t\t\t\t\tDrainQueue();\n\t\t\t\t}\n\t\t\t}\n\t\t} else if(_printDebugMessages) {\n\t\t\tvar paramString = (params !== undefined) ? \", \" + JSON.stringify(params, null, 1) : \"\";\n\t\t\tLog(\"Unity not connected. Ignoring message: \" + message + paramString);\n\t\t}\n\t}\n\n\t/**\n\t * Sends messages from the queue to Unity at a rate of about 30 per second.\n\t */\n\tfunction DrainQueue() {\n\t\tif(_messageQueue.length > 0) {\n\t\t\tvar uri = _messageQueue.shift();\n\t\t\tLog(\"Sending message: \" + uri);\n\n\t\t\tif(_dryRunEnabled) {\n\t\t\t\tif(uri.indexOf(\"exit\") != -1 || uri.indexOf(\"submitscore\") != -1) {\n\t\t\t\t\t// Simulate Unity exiting the game for the exit and submitscore events.\n\t\t\t\t\t// Doesn't actually close the window since Javascript prevents closing windows you didn't open, but generates a warning to indicate what's happening.\n\t\t\t\t\twindow.close();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twindow.location.href = encodeURI(uri);\n\t\t\t}\n\n\t\t\tsetTimeout(DrainQueue, 33);\n\t\t} else {\n\t\t\t_draining = false;\n\t\t}\n\t}\n\n\t/**\n\t * Log info messages if enabled\n\t */\n\tfunction Log(message) {\n\t\tif(_printDebugMessages || _dryRunEnabled) console.log(\"CandyManiaUnityBridge: \" + message);\n\t}\n\n\tfunction Error(message) {\n\t\tconsole.error(\"CandyManiaUnityBridge: \" + message);\n\t}\n\n\tfunction Warn(message) {\n\t\tconsole.warn(\"CandyManiaUnityBridge: \" + message)\n\t}\n};\n"],"sourceRoot":""}