function getLocalStorage(key) { try { return localStorage.getItem(key); } catch (e) { } return null; } function setLocalStorage(key, value) { try { if (value !== "" && value !== null) { localStorage.setItem(key, value); } else { localStorage.removeItem(key); } return true; } catch (e) {} return false; } function clearLocalStorage(key) { localStorage.removeItem(key); } // jump down to the max height of a div, with a slight delay function jumpToBottom(element) { if (!element) return; setTimeout(() => { element.scrollTo({ top: element.scrollHeight, left: 0, behavior: 'smooth' }); }, 50, element); } function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); } // convert newlines to
s function addNewlines(str) { return str.replace(/(?:\r\n|\r|\n)/g, '
'); } // Trying to determine if browser is mobile/tablet. // Source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent function hasTouchScreen() { var hasTouchScreen = false; if ("maxTouchPoints" in navigator) { hasTouchScreen = navigator.maxTouchPoints > 0; } else if ("msMaxTouchPoints" in navigator) { hasTouchScreen = navigator.msMaxTouchPoints > 0; } else { var mQ = window.matchMedia && matchMedia("(pointer:coarse)"); if (mQ && mQ.media === "(pointer:coarse)") { hasTouchScreen = !!mQ.matches; } else if ('orientation' in window) { hasTouchScreen = true; // deprecated, but good fallback } else { // Only as a last resort, fall back to user agent sniffing var UA = navigator.userAgent; hasTouchScreen = ( /\b(BlackBerry|webOS|iPhone|IEMobile)\b/i.test(UA) || /\b(Android|Windows Phone|iPad|iPod)\b/i.test(UA) ); } } return hasTouchScreen; }