1var VAWLT_MAX_COOKIE_AGE = (15 * 365 * 24 * 60 * 60); // 15 years in the future, not accounting for leap years 2 3function getMMDDYYYY() { 4 var today = new Date(); 5 var dd = today.getDate(); 6 var mm = today.getMonth() + 1; 7 8 var yyyy = today.getFullYear(); 9 if (dd < 10) { 10 dd = '0' + dd; 11 } 12 if (mm < 10) { 13 mm = '0' + mm; 14 } 15 return mm + '/' + dd + '/' + yyyy; 16} 17 18function setCookieValue (key, value, persist=true) { 19 var cookieStr ="" + key + "=" + value + ";"; 20 if (persist) { cookieStr += " max-age=" + VAWLT_MAX_COOKIE_AGE +";"; } 21 cookieStr +=" domain=" + rootDomain() +"; path=/;"; 22 console.log("CookieStr:" + cookieStr); 23 document.cookie = cookieStr; 24} 25 26function getCookieValue (key) { 27 var d=[], 28 e=document.cookie.split(";"); 29 a=RegExp("^\\s*"+key+"=\\s*(.*?)\\s*$"); 30 for(var b=0;b<e.length;b++){ 31 var f=e[b].match(a); 32 f&&d.push(f[1]) 33 } 34 return (d ? d[0] : undefined); 35} 36 37function clearCookieValue (key) { 38 var cookieStr ="" + key + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT"; // Valid Epoch usage. WITNESS! 39 document.cookie = cookieStr; 40} 41 42function canUseLocalStorage() { 43 try { 44 if (localStorage === undefined || localStorage === null) { return false; } 45 const key = createGUID(); 46 localStorage.setItem(key, key); 47 localStorage.removeItem(key); 48 return true; 49 } catch (e) { 50 return false; 51 } 52} 53 54function rootDomain() { 55 if (location.hostname === "localhost") { return location.hostname; } 56 var rootDomain = location.hostname.split('.').reverse()[1] + "." + 57 location.hostname.split('.').reverse()[0]; 58 console.log("RootDomain:" + rootDomain); 59 return rootDomain; 60} 61 62function setPersistedValue(key, val) { 63 console.log("Setting Persistent Value", val); 64 setCookieValue(key, val, true); 65 if (canUseLocalStorage()) { 66 localStorage.setItem(key, val); 67 } 68} 69 70function getPersistedValue(key, defaultVal=undefined) { 71 var val = undefined; 72 var cookieVal = getCookieValue(key) 73 val = cookieVal; 74 75 if (canUseLocalStorage()) { 76 localVal = localStorage.getItem(key); 77 if (localVal) { 78 val = localVal; 79 setCookieValue(key, localVal); 80 } else if (cookieVal) { 81 localStorage.setItem(key, cookieVal); 82 } 83 } 84 85 return (val ? val : defaultVal); 86} 87 88var vURLParams = new URLSearchParams(window.location.search); 89 90if (vURLParams.has('g') || vURLParams.has('G')) { 91 92 var g = parseInt(vURLParams.get('g') || vURLParams.get('G'), 10); 93 if (!isNaN(g) && g >= 1 && g <= 2) { 94 setPersistedValue("g", g); 95 } 96} 97 98if (vURLParams.has('a') || vURLParams.has('A')) { 99 var av = vURLParams.get('a') || vURLParams.get('A'); 100 if (av.indexOf("-") > 0) { 101 var ab = -1; 102 var ae = -1; 103 var aparts = av.split("-"); 104 if (aparts.length >= 2) { 105 ab = parseInt(aparts[0]); 106 ae = parseInt(aparts[1]); 107 } else if (aparts.length === 1) { 108 ab = parseInt(aparts[0]); 109 ae = 99; 110 } 111 if (!isNaN(ab) && !isNaN(ae) && ab > 13 && ae >= ab) { 112 setPersistedValue("a", ab + "-" + ae); 113 } 114 } else { 115 var a = parseInt(vURLParams.get('a') ||vURLParams.get('A'), 10); 116 if (!isNaN(a) && a >= 13) { 117 setPersistedValue("a", a); 118 } 119 } 120} 121 122if (vURLParams.has('i') || vURLParams.has('I')) { 123 var i = vURLParams.get('i') || vURLParams.get('I'); 124 var ei = getPersistedValue('i'); 125 if (ei) { 126 var eiparts = ei.split("|"); 127 var has = false; 128 for (var ii=0; ii < eiparts.length; ii++) { 129 if (eiparts[ii] === i) { console.log("Already has", i); has = true; break; } 130 } 131 if (!has) { setPersistedValue("i", ei + "|" + i); } 132 } else { 133 setPersistedValue("i", i); 134 } 135} 136 137 138/// Our Vawlt Anonymous Unique User Id. 139var _VAUUID 140function getVAUUID() { 141 if (!_VAUUID) { _VAUUID = getPersistedValue("va_uuid"); } 142 return _VAUUID; 143} 144 145function getStartDate() { 146 return getPersistedValue("va_start_date"); 147} 148 149/// 150// Just for getting started purposees. Maybe not use this guid function in real life due to Math.random 151// TODO: Validate this is ok solution, but we are static site generation at the moment with no backend. 152/// 153function S4() { 154 return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 155} 156function createGUID() { 157 console.log("CREATE GUID TEMPORARY. REPLACE WITH MORE ROBUST SOLUTION"); 158 // then to call it, plus stitch in '4' in the third group 159 guid = (S4() + S4() + "-" + S4() + "-4" + S4().substr(0,3) + "-" + S4() + "-" + S4() + S4() + S4()).toLowerCase(); 160 return guid; 161} 162 163 164/// 165// Can we use local storage? 166/// 167function canUseLocalStorage() { 168 169 try { 170 if (localStorage === undefined || localStorage === null) { return false; }
171 const key = createGUID(); 172 localStorage.setItem(key, key); 173 localStorage.removeItem(key); 174 return true; 175 } catch (e) { 176 return false; 177 } 178} 179 180/// 181// Do we think we are on iOS? 182/// 183function isIOS() { 184 return /iPhone|iPod|iPad/.test(navigator.platform); 185} 186 187function isAndroid() { 188 console.log("User Agent is:", navigator.userAgent); 189 return /(android)/i.test(navigator.userAgent); 190} 191 192function isSafari () { 193 return navigator.userAgent.toLowerCase().indexOf('safari') > -1; 194} 195 196function isMobile() { 197 return isIOS() || isAndroid(); 198} 199 200function isDesktop() { 201 return !isMobile(); 202} 203 204function isSamsung() { 205 //return navigator.userAgent.match(/SAMSUNG|Samsung|SGH-[I|N|T]|GT-[I|N]|SM-[A|N|P|T|Z]|SHV-E|SCH-[I|J|R|S]|SPH-L/i); 206 return /SamsungBrowser/.test(navigator.userAgent); 207} 208 209function isChrome() { 210 return !!window.chrome; 211} 212 213/// 214// What is our root domain? E.g subdomain.domain.com will return domain.com. localhost is localhost 215/// 216function rootDomain() { 217 if (location.hostname === "localhost") { return location.hostname; } 218 var rootDomain = location.hostname.split('.').reverse()[1] + "." + 219 location.hostname.split('.').reverse()[0]; 220 console.log("RootDomain:" + rootDomain); 221 return rootDomain; 222} 223 224/// 225// Set a cookie value by key. Set persisted to true to make "permanent" 226/// 227function setCookieValue (key, value, persist=true) { 228 var cookieStr ="" + key + "=" + value + ";"; 229 if (persist) { cookieStr += " max-age=" + VAWLT_MAX_COOKIE_AGE +";"; } 230 cookieStr +=" domain=" + rootDomain() +"; path=/;"; 231 console.log("CookieStr:" + cookieStr); 232 document.cookie = cookieStr; 233} 234 235/// 236// Get a cookie value by key 237/// 238function getCookieValue (key) { 239 var d=[], 240 e=document.cookie.split(";"); 241 a=RegExp("^\\s*"+key+"=\\s*(.*?)\\s*$"); 242 for(var b=0;b<e.length;b++){ 243 var f=e[b].match(a); 244 f&&d.push(f[1]) 245 } 246 return (d ? d[0] : undefined); 247} 248 249/// 250// Clear out a cookie value 251/// 252function clearCookieValue (key) { 253 var cookieStr ="" + key + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT"; // Valid Epoch usage. WITNESS! 254 document.cookie = cookieStr; 255} 256 257/// 258// Persisted Values try to set values in both cookie and localstorage 259// Localstorage has priority over cookies and should be sync'd. reading a value will result 260// in the cookie being set as well. 261/// 262function getPersistedValue(key, defaultVal=undefined) { 263 var val = undefined; 264 265 // We check the cookie value first, as it is second priority 266 var cookieVal = getCookieValue(key) 267 val = cookieVal; // Initially set the value to be the cookie value (including undefined) 268 269 // Can we use local storage? If so, grab the value 270 if (canUseLocalStorage()) { 271 localVal = localStorage.getItem(key); 272 // We have a local value 273 if (localVal) { 274 val = localVal; // return local 275 setCookieValue(key, localVal); // Set the cookie value to sync 276 277 // We don't have a local, but we have a cookievalue, so use that and set local 278 } else if (cookieVal) { localStorage.setItem(key, cookieVal); } 279 } 280 281 // return the value if we have one, otherwise return default value. 282 return (val ? val : defaultVal); 283 284} 285 286/// 287// Set a value in the most persistent way we can. Set in a cookie and localStorage if possible 288/// 289function setPersistedValue(key, val) { 290 console.log("Setting Persistent Value", val); 291 setCookieValue(key, val, true); 292 if (canUseLocalStorage()) { 293 localStorage.setItem(key, val); 294 } 295} 296 297/// 298// Do we think we are in a PWA instance? 299/// 300function isPWA() { 301 var displayModes = ["fullscreen", "standalone", "minimal-ui"]; 302 303 for (var ii=0; ii < displayModes.length; ii++) { 304 var displayMode = displayModes[ii]; 305 if (window.matchMedia('(display-mode: ' + displayMode + ')').matches) { 306 console.log("is PWA true with displaymode:" + displayMode); 307 return true; 308 } 309 } 310 console.log("is PwA no match"); 311 return false; 312} 313// gaReportEvent will use this to queue up pending events if ga() is not defined 314// This can happen if a game is using defer.js to push all 3rd party libs/etc to load after the page is fully loaded 315// call flushPendingGAEvents() to clear. gaReportEvent will also call 316var _pendingGAEvents = []; 317 318/// 319// Send this event to google analytics 320/// 321function gaReportEvent(name, action, label, value = 1) { 322 if (typeof ga != "function") { 323 console.log("GA not ready yet"); 324 _pendingGAEvents.push({name: name, action: action, label: label, value: value}); 325 return; // We don't have ga loaded yet 326 } 327 328 // If there are any things pending, let's get them out of here before we do our call. 329 // Note: We don't use the queue unnecessarily as ga will handle queueing itself. We have our own queue in just a defer load case 330 flushPendingGAEvents(); 331 332 console.log("GA Report Event: Name:" + name + " Action:" + action + " Label:" + label + " Value:" + value); 333 ga('send', { 334 hitType: 'event', 335 eventName: name, 336 eventAction: action, 337 eventLabel: label, 338 eventValue: value, 339 hitCallback: function() { 340 console.log("gaReportEvent callback"); 341 } 342 }); 343} 344 345function flushPendingGAEvents() { 346 347 if (_pendingGAEvents.length > 0) { 348 console.log("Flushing pending GA events*********"); 349 for (var ii=0; ii < _pendingGAEvents.length; ii++ ) { 350 var pending = _pendingGAEvents.pop(); 351 ga('send', { 352 hitType: 'event', 353 eventName: pending.name, 354 eventAction: pending.action, 355 eventLabel: pending.label, 356 eventValue: pending.value, 357 hitCallback: function() { 358 console.log("gaReportEvent callback"); 359 } 360 }); 361 } 362 } 363} 364 365// Is WebView Code
366//var isIosWebview =/(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent) 367// if (typeof Android != "undefined") { means you are in a webview 368 369var vGameConfig = {}; 370// 371// Parse out the game configuration from the gc paramater and/or persistent storage. 372// For now the full string is stored, not distinct values. 373// The gc parameter is encoded with | as the separator. 374function initGameConfig(gameName="default") { 375 var configString = ""; 376 if (vURLParams.has('gc') || vURLParams.has('GC')) { 377 configString = vURLParams.get('gc') || vURLParams.get('GC'); 378 } else { 379 configString = getPersistedValue(gameName + "_gc"); 380 } 381 382 // Do we have a config string to parse? 383 if (!configString) { 384 return; // If not, let's bail 385 } else { 386 setPersistedValue(gameName + "_gc", configString); // Store the config string for future use. 387 } 388 389 console.log("ConfigString", configString); 390 var configParts = configString.split("|"); 391 console.log("ConfigParts", configParts); 392 for (var ii=0; ii < configParts.length; ii++) { 393 console.log("Checking Parts", configParts[ii]); 394 switch(configParts[ii]) { 395 396 case "cf0": // Card Faces 397 console.log("Setting card faces to false"); 398 vGameConfig["card_faces"] = "false"; 399 break; 400 401 case "cf1": 402 vGameConfig["card_faces"] = "true"; 403 break; 404 } 405 } 406 console.log("vGameConfig", vGameConfig); 407}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.