{"version":3,"sources":["ACTWebsocket.js","Action.js","Rotation.js","serviceWorker.js","index.js","App.js"],"names":["handleCodes","Set","gcdOverrides","ogcdOverrides","Action","_ref","actionId","additionalClasses","_React$useState","React","useState","_React$useState2","Object","slicedToArray","apiData","setApiData","useEffect","current","asyncToGenerator","regenerator_default","a","mark","_callee","data","wrap","_context","prev","next","fetch","concat","mode","sent","json","stop","undefined","Icon","react_default","createElement","className","has","ActionCategory","ID","src","alt","Name","RotationContainer","encounterId","name","actionList","open","setOpen","Fragment","onClick","RotationContents","expanded","_ref2","map","action","i","Action_Action","key","Boolean","window","location","hostname","match","ReactDOM","render","setActionList","_React$useState3","_React$useState4","encounterList","setEncounterList","selfId","lastTimestamp","lastAction","currentZone","lastKey","ws","listenActWebSocket","callback","url","URLSearchParams","search","wsUri","get","WebSocket","onerror","close","onclose","setTimeout","onmessage","e","m","send","obj","JSON","parse","msgtype","msg","code","substring","openNewEncounter","timestamp","rotation","length","shift","unshift","slice","charID","_data$split","split","_data$split2","refCode","message","_data$split3","zoneName","_data$split5","logCharIdHex","parseInt","_data$split7","controlCode","_data$split9","_data$split10","logTimestamp","logActionIdHex","Date","now","unstable_batchedUpdates","push","encounter","document","getElementById","navigator","serviceWorker","ready","then","registration","unregister"],"mappings":"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","file":"static/js/main.66db225b.chunk.js","sourcesContent":["const handleCodes = new Set([\r\n\t'00',\r\n\t'01',\r\n\t'02',\r\n\t'21',\r\n\t'22',\r\n\t'33'\r\n])\r\n\r\nexport default function listenActWebSocket( callback ) {\r\n const url = new URLSearchParams(window.location.search)\r\n const wsUri = `${url.get(\"HOST_PORT\")}BeforeLogLineRead` || undefined\r\n const ws = new WebSocket(wsUri)\r\n ws.onerror = () => ws.close()\r\n ws.onclose = () => setTimeout(() => { listenActWebSocket( callback ) }, 1000)\r\n ws.onmessage = function(e, m) {\r\n if (e.data === \".\") return ws.send(\".\") //PING\r\n\r\n const obj = JSON.parse(e.data);\r\n if (obj.msgtype === \"SendCharName\") {\r\n return callback(obj.msg, null)\r\n } else if (obj.msgtype === \"Chat\") {\r\n const code = obj.msg.substring(0, 2) //first 2 numbers POG\r\n\r\n if (handleCodes.has(code)) return callback(obj.msg, code) //NetworkAbility or NetworkAoeAbility\r\n }\r\n }\r\n\r\n return ws\r\n}\r\n","import React from 'react'\r\nimport './css/Action.css'\r\n\r\nconst gcdOverrides = new Set([\r\n\t15997, //standard step\r\n\t15998, //technical step\r\n\t15999, \r\n\t16000,\r\n\t16001,\r\n\t16002, //step actions\r\n\t16003, //standard finish\r\n\t16004, //technical finish\r\n\t16191, //single standard finish\r\n\t16192, //double standard finish (WHY IS IT LIKE THIS)\r\n\t16193, //single technical finish\r\n\t16194, //double technical finish\r\n\t16195, //triple technical finish\r\n\t16196, //quadruple technical finish\r\n\t7418, //flamethrower\r\n\t16483 //tsubame-gaeshi\r\n])\r\n\r\nconst ogcdOverrides = new Set([\r\n\t3559, //bard WM\r\n\t116, //bard AP\r\n\t114 //bard MB\r\n])\r\n\r\nexport default function Action({ actionId, additionalClasses }) {\r\n\tconst [apiData, setApiData] = React.useState()\r\n\t\r\n\tReact.useEffect(() => {\r\n\t\tlet current = true\r\n\t\tvoid (async () => {\r\n\t\t\tconst data = await (\r\n\t\t\t\tawait fetch(`https://xivapi.com/Action/${actionId}`, { mode: 'cors' })\r\n\t\t\t).json()\r\n\t\t\tif (current) {\r\n\t\t\t\tsetApiData(data)\r\n\t\t\t}\r\n\t\t})()\r\n\r\n\t\treturn () => {\r\n\t\t\tcurrent = false\r\n\t\t}\r\n\t}, [actionId])\r\n\t\r\n\tif (apiData === undefined || !apiData.Icon) {\r\n\t\treturn null\r\n\t}\r\n\t\r\n\treturn (\r\n\t\t\r\n\t)\r\n}\r\n","import React from 'react'\r\nimport './css/Rotation.css'\r\nimport Action from './Action'\r\n\r\nexport default function RotationContainer({encounterId, name, actionList}) {\r\n\tconst [open, setOpen] = React.useState(false)\r\n\t\r\n\treturn (\r\n\t\t<>\r\n\t\t\t\r\n\t\t\t\r\n\t\t\r\n\t)\r\n}\r\n\r\nfunction RotationContents({ expanded, actionList }) {\r\n\tif(!expanded) return null\r\n\t\t\r\n\treturn (\r\n\t\t
\r\n\t\t\t{actionList.map((action, i) => (\r\n\t\t\t\t\r\n\t\t\t))}\r\n\t\t
\r\n\t)\r\n}","// 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.1/8 is 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 .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.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport './css/index.css';\r\nimport App from './App';\r\nimport * as serviceWorker from './serviceWorker';\r\n\r\nReactDOM.render(, document.getElementById('root'));\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","import React from 'react'\r\nimport listenActWebSocket from './ACTWebsocket'\r\nimport './css/App.css'\r\nimport Action from './Action'\r\nimport RotationContainer from './Rotation'\r\nimport ReactDOM from 'react-dom'\r\n\r\nexport default function App() {\r\n\t// NOTE: unlike class state, useState doesn't do object merging; instead, it directly holds values\r\n\tconst [actionList, setActionList] = React.useState([])\r\n\tconst [encounterList, setEncounterList] = React.useState([])\r\n\r\n\tReact.useEffect(() => {\r\n\t\t\r\n\t\t// These values are only used internally by the handler,\r\n\t\t// we don't need to notify React that they were updated,\r\n\t\t// or keep their updates synchronized with actionList updates.\r\n\t\t//\r\n\t\t// This means we don't have to keep them in State (or Reducer)!\r\n\t\tlet selfId\r\n\t\tlet lastTimestamp = ''\r\n\t\tlet lastAction = -1\r\n\t\tlet currentZone = 'Unknown'\r\n\r\n\t\t// we need keys to persist for each push, even if we shorten the array later,\r\n\t\t// so we store the key with the action; can't just use array index due to CSS\r\n\t\tlet lastKey = 1\r\n\r\n\t\t// listenActWebSocket should be changed to return the websocket,\r\n\t\t// and this effect should return a function that disconnects the websocket\r\n\t\t//\r\n\t\t// like \"return () => { ws.close() }\"\r\n\t\tlet ws = listenActWebSocket((data, code) => {\r\n\t\t\tconst openNewEncounter = (timestamp) => {\r\n\t\t\t\tsetEncounterList(encounterList => {\r\n\t\t\t\t\tif(encounterList[0] && encounterList[0].rotation && encounterList[0].rotation.length <= 0) {\r\n\t\t\t\t\t\tencounterList.shift()\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tencounterList.unshift({\r\n\t\t\t\t\t\tname: currentZone,\r\n\t\t\t\t\t\trotation: []\r\n\t\t\t\t\t})\r\n\t\t\t\t\t\r\n\t\t\t\t\treturn encounterList.slice(0,3)\r\n\t\t\t\t})\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif (data.charID) {\r\n\t\t\t\tselfId = data.charID\r\n\t\t\t\topenNewEncounter()\r\n\t\t\t\treturn\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tswitch(code) {\r\n\t\t\t\tcase '00':\r\n\t\t\t\t\tconst [, , refCode, , message] = data.split('|')\r\n\t\t\t\t\tif(refCode === '0038' && message === 'end') openNewEncounter()\r\n\t\t\t\t\treturn\r\n\t\t\t\tcase '01':\r\n\t\t\t\t\tconst [, , , zoneName] = data.split('|')\r\n\t\t\t\t\tcurrentZone = zoneName\r\n\t\t\t\t\treturn\r\n\t\t\t\tcase '02':\r\n\t\t\t\t\tconst [, , logCharIdHex] = data.split('|')\r\n\t\t\t\t\tselfId = parseInt(logCharIdHex, 16)\r\n\t\t\t\t\topenNewEncounter()\r\n\t\t\t\t\treturn\r\n\t\t\t\tcase '33':\r\n\t\t\t\t\tconst [, , , controlCode] = data.split('|')\r\n\t\t\t\t\tif(controlCode === '40000012' || controlCode === '40000010') openNewEncounter()\r\n\t\t\t\t\treturn\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tbreak\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t//if it's not any of these it must be Network(AOE)Ability, the bulk of what we want to handle\r\n\r\n\t\t\tif (selfId === undefined) return\r\n\r\n\t\t\tconst [, logTimestamp, logCharIdHex, , logActionIdHex] = data.split('|')\r\n\r\n\t\t\t// microoptimization: since selfId updates way less often,\r\n\t\t\t// save selfId as data.charID.toString(16), that way you don't need to\r\n\t\t\t// parse logCharIdHex every time\r\n\t\t\tif (parseInt(logCharIdHex, 16) !== selfId) return\r\n\r\n\t\t\t// we do a mathematical comparison with action though so can't optimize this away\r\n\t\t\tconst action = parseInt(logActionIdHex, 16)\r\n\r\n\t\t\tif (\r\n\t\t\t\taction <= 8 ||\r\n\t\t\t\t(logTimestamp === lastTimestamp && action === lastAction)\r\n\t\t\t)\r\n\t\t\t\treturn\r\n\t\t\t\t\r\n\t\t\tif((Date.now() - Date.parse(lastTimestamp)) > 120000) openNewEncounter()//last action > 120s ago\r\n\r\n\t\t\tlastTimestamp = logTimestamp\r\n\t\t\tlastAction = action\r\n\r\n\t\t\tconst key = (lastKey % 256) + 1\r\n\t\t\tlastKey = key\r\n\r\n\t\t\tReactDOM.unstable_batchedUpdates(() => {\r\n\t\t\t\tsetActionList(actionList => actionList.concat({ action, key }))\r\n\t\t\t\tsetEncounterList(encounterList => {\r\n\t\t\t\t\tif(!encounterList[0]) {\r\n\t\t\t\t\t\tencounterList[0] = {\r\n\t\t\t\t\t\t\tname: currentZone,\r\n\t\t\t\t\t\t\trotation: []\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t\tencounterList[0].rotation.push( action )\r\n\t\t\t\t\r\n\t\t\t\t\treturn encounterList\r\n\t\t\t\t})\r\n\t\t\t})\r\n\r\n\t\t\t// This _probably_ should be done as a separate React.useEffect instead,\r\n\t\t\t// which runs as an effect whenever the value of actionList changes.\r\n\t\t\t// The problem there is, it would have to detect whether the list grew\r\n\t\t\t// since the last time it was called, otherwise it'd react (heh) to its own\r\n\t\t\t// updates.\r\n\t\t\t//\r\n\t\t\t// Easier to pair it with the previous set.\r\n\t\t\tsetTimeout(() => {\r\n\t\t\t\tsetActionList(actionList => actionList.slice(1))\r\n\t\t\t}, 10000)\r\n\t\t})\r\n\t\t\r\n\t\treturn () => { ws.close() }\r\n\t}, [])\r\n\r\n\treturn (\r\n\t\t
\r\n\t\t\t
\r\n\t\t\t\t{actionList.map(({ action, key }) => (\r\n\t\t\t\t\t\r\n\t\t\t\t))}\r\n\t\t\t
\r\n\t\t\t{encounterList.map((encounter, i) => (\r\n\t\t\t\t\r\n\t\t\t))}\r\n\t\t
\r\n\t)\r\n}\r\n\r\n"],"sourceRoot":""}