Files
grin-web-wallet/scripts/common.js
2024-12-20 18:08:44 -08:00

1952 lines
44 KiB
JavaScript
Executable File

// Use strict
"use strict";
// Classes
// Common class
class Common {
// Public
// From hex string
static fromHexString(hexString, useSharedArrayBuffer = false) {
// Initialize result
var result = new Uint8Array((useSharedArrayBuffer === true && crossOriginIsolated === true) ? new SharedArrayBuffer(Common.hexStringLength(hexString)) : Common.hexStringLength(hexString));
// Go through all bytes in the result
for(var i = 0; i < result["length"]; ++i) {
// Set character as a byte in the result
result[i] = (Common.HEX_CHARACTER_TO_VALUE[hexString[i * Common.HEX_NUMBER_LENGTH]] << (Common.BITS_IN_A_BYTE / 2)) | Common.HEX_CHARACTER_TO_VALUE[hexString[i * Common.HEX_NUMBER_LENGTH + 1]];
}
// Return result
return result;
}
// To hex string
static toHexString(byteArray) {
// Initialize result
var result = "";
// Go through all bytes in the byte array
for(var i = 0; i < byteArray["length"]; ++i) {
// Get byte
var byte = byteArray[i];
// Append byte as characters to the result
result = result.concat(Common.VALUE_TO_HEX_CHARACTER[byte >>> (Common.BITS_IN_A_BYTE / 2)], Common.VALUE_TO_HEX_CHARACTER[byte & 0x0F]);
}
// Return result
return result;
}
// Is hex string
static isHexString(string) {
// Check if string isn't a string
if(typeof string !== "string")
// Return false
return false;
// Check if string's length is invalid
if(string["length"] % Common.HEX_NUMBER_LENGTH !== 0) {
// Return false
return false;
}
// Return if string is a hex string
return Common.HEX_STRING_PATTERN.test(string) === true;
}
// Hex string length
static hexStringLength(string) {
// Return hex string length
return string["length"] / Common.HEX_NUMBER_LENGTH;
}
// Is number string
static isNumberString(string) {
// Check if string isn't a string
if(typeof string !== "string")
// Return false
return false;
// Return if string is a number string
return Common.NUMBER_STRING_PATTERN.test(string) === true;
}
// Is RFC 3339 string
static isRfc3339String(string) {
// Check if string isn't a string
if(typeof string !== "string")
// Return false
return false;
// Check if string isn't an RFC 3339 string
if(Common.RFC_3339_STRING_PATTERN.test(string) === false)
// Return false
return false;
// Return if string could be converted from a RFC 3339 string to a timestamp
return Number.isNaN(Common.rfc3339StringToTimestamp(string)) === false;
}
// Is lowercase string
static isLowercaseString(string) {
// Check if string isn't a string
if(typeof string !== "string")
// Return false
return false;
// Return if string is a a lowercase string
return Common.LOWERCASE_STRING_PATTERN.test(string) === true;
}
// RFC 3339 string to timestamp
static rfc3339StringToTimestamp(string) {
// Return timestamp from string
return Date.parse(string);
}
// Merge arrays
static mergeArrays(arrays) {
// Initialize result
var result = new Uint8Array([]);
// Go through all arrays
for(var i = 0; i < arrays["length"]; ++i) {
// Get array
var array = arrays[i];
// Set updated result to be the length of the current result and the array
var updatedResult = new Uint8Array(result["length"] + array["length"]);
// Set arrays in the updated result
updatedResult.set(result);
updatedResult.set(array, result["length"]);
// Set result to the updated result
result = updatedResult;
}
// Return result
return result;
}
// Arrays are equal
static arraysAreEqual(arrayOne, arrayTwo) {
// Check if arrays have different lengths
if(arrayOne["length"] !== arrayTwo["length"])
// Return false
return false;
// Go through all values each array
for(var i = 0; i < arrayOne["length"]; ++i)
// Check if array values differ
if(arrayOne[i] !== arrayTwo[i])
// Return false
return false;
// Return true
return true;
}
// Arrays are equal timing safe
static arraysAreEqualTimingSafe(arrayOne, arrayTwo) {
// Initialize results
var result = (arrayOne["length"] === arrayTwo["length"]) ? 0 : 1;
// Go through all values in the first array
for(var i = 0; i < arrayOne["length"]; ++i) {
// Get current value from each array
var arrayOneValue = arrayOne[i];
var arrayTwoValue = (i < arrayTwo["length"]) ? arrayTwo[i] : 0;
// Update result to if current values are equal
result |= (arrayOneValue === arrayTwoValue) ? 0 : 1;
}
// Return if arrays are equal
return result === 0;
}
// Get current timestamp
static getCurrentTimestamp() {
// Return current timestamp
return Math.floor(Date.now() / Common.MILLISECONDS_IN_A_SECOND);
}
// Is extension
static isExtension() {
// Return if extension
return typeof location !== "undefined" && location["protocol"]["length"] > "-extension:"["length"] && location["protocol"].substring(location["protocol"]["length"] - "-extension:"["length"]) === "-extension:";
}
// Is popup
static isPopup() {
// Get URL parameters
var urlParameters = Common.getUrlParameters();
// Return if popup
return Common.isExtension() === true && "Is Popup" in urlParameters === true && urlParameters["Is Popup"] === "True";
}
// Is app
static isApp() {
// Return if app
return Common.isExtension() === false && ((typeof navigator === "object" && navigator !== null && "standalone" in navigator === true && navigator["standalone"] === true) || (typeof matchMedia === "function" && matchMedia("(display-mode: standalone)")["matches"] === true));
}
// HTML encode
static htmlEncode(string) {
// Return string with HTML entities encoded
return $("<div>").text(string).html().replace(Common.DOUBLE_QUOTE_PATTERN, Common.DOUBLE_QUOTE_HTML_ENTITY).replace(Common.SINGLE_QUOTE_PATTERN, Common.SINGLE_QUOTE_HTML_ENTITY).replace(Common.GRAVE_ACCENT_PATTERN, Common.GRAVE_ACCENT_HTML_ENTITY);
}
// HTML decode
static htmlDecode(htmlString) {
// Return html string with HTML entities decoded
return $("<div>").html(htmlString).text();
}
// Random number
static randomNumber(minValue, maxValue) {
// Return random number between values inclusively
return Math.floor(Math.random() * (maxValue - minValue + 1)) + minValue;
}
// Escape regular expression
static escapeRegularExpression(string) {
// Return string with regular expression meta characters escaped
return string.replace(/[.*+?^${}()|[\]\\]/ug, "\\$&");
}
// Map
static map(value, inMin, inMax, outMin, outMax) {
// Return value mapped to different range
return (new BigNumber(outMax)).minus(outMin).multipliedBy((new BigNumber(value)).minus(inMin)).dividedBy((new BigNumber(inMax)).minus(inMin)).plus(outMin);
}
// Is valid URL
static isValidUrl(url) {
// Check if URL doesn't have a protocol
if(Common.urlContainsProtocol(url) === false) {
// Add protocol to URL
url = Common.HTTP_PROTOCOL + "//" + url;
}
// Try
try {
// Parse URL as a URL
new URL(url);
}
// Catch errors
catch(error) {
// Return false
return false;
}
// Return true
return true;
}
// Is iframe
static isIframe() {
// Try
try {
// Return if self isn't the top window
return window["self"] !== window["top"];
}
// Catch errors
catch(error) {
// Return true
return true;
}
}
// On reduced data connection
static onReducedDataConnection() {
// Return if save data is enabled
return typeof navigator === "object" && navigator !== null && "connection" in navigator === true && typeof navigator["connection"] === "object" && navigator["connection"] !== null && "saveData" in navigator["connection"] === true && navigator["connection"]["saveData"] === true;
}
// Is low memory device
static isLowMemoryDevice() {
// Return if device has low memory
return typeof navigator === "object" && navigator !== null && "deviceMemory" in navigator === true && navigator["deviceMemory"] <= Common.LOW_MEMORY_THRESHOLD_GIGABYTES;
}
// Is high memory device
static isHighMemoryDevice() {
// Return if device has high memory
return typeof navigator === "object" && navigator !== null && "deviceMemory" in navigator === true && navigator["deviceMemory"] >= Common.HIGH_MEMORY_THRESHOLD_GIGABYTES;
}
// Is mobile device
static isMobileDevice() {
// Return if device is a mobile device
return typeof navigator === "object" && navigator !== null && "userAgentData" in navigator === true && "mobile" in navigator["userAgentData"] === true && navigator["userAgentData"]["mobile"] === true;
}
// Is using cellular network
static isUsingCellularNetwork() {
// Return if using cellular network
return typeof navigator === "object" && navigator !== null && "connection" in navigator === true && "type" in navigator["connection"] === true && navigator["connection"]["type"] === "cellular";
}
// Upgrade applicable insecure URL
static upgradeApplicableInsecureUrl(url) {
// Try
try {
// Parse HTTPS server address as a URL
var parsedHttpsServerUrl = new URL(HTTPS_SERVER_ADDRESS);
// Parse Tor server address as a URL
var parsedTorServerUrl = new URL(TOR_SERVER_ADDRESS);
// Parse URL as a URL
var parsedUrl = new URL(url);
}
// Catch errors
catch(error) {
// Return url
return url;
}
// Check if URL's protocol is HTTP, the HTTPS server address's protocol is HTTPS, and the URL is the same site as the HTTPS server address
if(parsedUrl["protocol"] === Common.HTTP_PROTOCOL && parsedHttpsServerUrl["protocol"] === Common.HTTPS_PROTOCOL && parsedUrl["hostname"] === parsedHttpsServerUrl["hostname"]) {
// Create an HTTPS URL from the URL
var httpsUrl = Common.HTTPS_PROTOCOL + Common.ltrim(url).substring(Common.HTTP_PROTOCOL["length"]);
// Return HTTPS URL
return httpsUrl;
}
// Otherwise check if URL's protocol is WebSocket, the HTTPS server address's protocol is HTTPS, and the URL is the same site as the HTTPS server address
else if(parsedUrl["protocol"] === Common.WEBSOCKET_PROTOCOL && parsedHttpsServerUrl["protocol"] === Common.HTTPS_PROTOCOL && parsedUrl["hostname"] === parsedHttpsServerUrl["hostname"]) {
// Create an WebSocket secure URL from the URL
var wssUrl = Common.WEBSOCKET_SECURE_PROTOCOL + Common.ltrim(url).substring(Common.WEBSOCKET_PROTOCOL["length"]);
// Return WebSocket secure URL
return wssUrl;
}
// Otherwise check if URL's protocol is HTTPS, the Tor server address's protocol is HTTP, and the URL is the same site as the Tor server address
else if(parsedUrl["protocol"] === Common.HTTPS_PROTOCOL && parsedTorServerUrl["protocol"] === Common.HTTP_PROTOCOL && parsedUrl["hostname"] === parsedTorServerUrl["hostname"]) {
// Create an HTTP URL from the URL
var httpUrl = Common.HTTP_PROTOCOL + Common.ltrim(url).substring(Common.HTTPS_PROTOCOL["length"]);
// Return HTTP URL
return httpUrl;
}
// Otherwise check if URL's protocol is WebSocket secure, the Tor server address's protocol is HTTP, and the URL is the same site as the Tor server address
else if(parsedUrl["protocol"] === Common.WEBSOCKET_SECURE_PROTOCOL && parsedTorServerUrl["protocol"] === Common.HTTP_PROTOCOL && parsedUrl["hostname"] === parsedTorServerUrl["hostname"]) {
// Create an WebSocket URL from the URL
var wsUrl = Common.WEBSOCKET_PROTOCOL + Common.ltrim(url).substring(Common.WEBSOCKET_SECURE_PROTOCOL["length"]);
// Return WebSocket URL
return wsUrl;
}
// Otherwise
else {
// Return URL
return url;
}
}
// Get URL parmaters
static getUrlParameters() {
// Initialize result
var result = {};
// Check if URL query string exists
if(typeof URL_QUERY_STRING !== "undefined") {
// Get URL parameters from URL query string
var urlParameters = URL_QUERY_STRING.substring(Common.URL_QUERY_STRING_SEPARATOR["length"]).split(Common.URL_QUERY_STRING_PARAMETER_SEPARATOR);
// Go through all URL parameters
for(var i = 0; i < urlParameters["length"]; ++i) {
// Get URL parameter
var urlParameter = urlParameters[i].split(Common.URL_QUERY_STRING_PARAMETER_VALUE_SEPARATOR);
// Check if URL parameter is valid
if(urlParameter["length"] === 2) {
// Get URL parameter's key
var key = decodeURIComponent(urlParameter[0].replace(/\+/ug, "%20"));
// Check if key isn't already in the rersult
if(key in result === false) {
// Set URL parameter in the result
result[key] = decodeURIComponent(urlParameter[1].replace(/\+/ug, "%20"));
}
}
}
}
// Return result
return result;
}
// URL contains protocol
static urlContainsProtocol(url) {
// Return if the URL contains protocol
return Common.URL_PROTOCOL_PATTERN.test(url) === true;
}
// URL contains top-level domain
static urlContainsTopLevelDomain(url) {
// Return if the URL contains a top-level domain
return Common.URL_TOP_LEVEL_DOMAIN_PATTERN.test(url) === true;
}
// Remove subdomain
static removeSubdomain(url) {
// Return URL's without its subdomain
return url.match(Common.URL_DOMAIN_NAME_PATTERN)[0];
}
// Remove top-level domain
static removeTopLevelDomain(url) {
// Return URL without its top-level domain
return url.match(Common.URL_WITHOUT_TOP_LEVEL_DOMAIN_PATTERN)[1];
}
// Remove trailing slashes
static removeTrailingSlashes(text) {
// Return text with its trailing slashes removed
return Common.rtrim(text).replace(Common.TRAILING_SLASHES_PATTERN, "");
}
// Remove duplicate slashes
static removeDuplicateSlashes(text) {
// Return text with its duplicate slashes removed
return text.replace(Common.DUPLICATE_SLASHES_PATTERN, "/");
}
// Split remaining
static splitRemaining(text, separator, limit) {
// Initialzie result
var result = [];
// Go through limit
for(var i = 0; i < limit; ++i) {
// Get last separator end
var lastSeparatorEnd = separator["lastIndex"];
// Get current separator start
var currentSeparatorStart = separator.exec(text);
// Check if separator start exists
if(currentSeparatorStart !== Common.NO_MATCH_FOUND) {
// Append part to result
result.push(text.slice(lastSeparatorEnd, currentSeparatorStart["index"]));
}
// Otherwise
else {
// Get last part
var lastPart = text.slice(lastSeparatorEnd);
// Check if last part exists and isn't a separator
if(lastPart["length"] !== 0 && separator.test(lastPart) === false) {
// Append last part to result
result.push(lastPart);
}
// Return result
return result;
}
}
// Get last part
var lastPart = text.slice(separator["lastIndex"]);
// Check if last part exists and isn't a separator
if(lastPart["length"] !== 0 && separator.test(lastPart) === false) {
// Append last part to result
result.push(lastPart);
}
// Return result
return result;
}
// Remove duplicate newlines
static removeDuplicateNewlines(text) {
// Return text with duplicate newlines and trailing newlines removed from it
return text.replace(Common.DUPLICATE_NEWLINE_PATTERN, "\n").replace(Common.TRAILING_NEWLINE_PATTERN, "");
}
// Remove trailing zeros
static removeTrailingZeros(text) {
// Remove trailing zeros and ending decimal point from text
text = text.replace(Common.TRAILING_ZEROS_PATTERN, "$1").replace(Common.ENDING_DECIMAL_POINT_PATTERN, "");
// Check if text is invalid
if(Number.isNaN(parseFloat(text)) === true) {
// Return zero
return "0";
}
// Otherwise
else {
// Return text
return text;
}
}
// Get number string precision
static getNumberStringPrecision(text) {
// Remove trailing zeros from text
text = Common.removeTrailingZeros(text);
// Check if text doesn't contains a fractional component
var fractionIndex = text.indexOf(".");
if(fractionIndex === Common.INDEX_NOT_FOUND) {
// Return zero
return 0;
}
// Otherwise
else {
// Return number of fractional digits
return text["length"] - (fractionIndex + "."["length"]);
}
}
// Serialize object
static serializeObject(object) {
// Check if object is an array
if(Array.isArray(object) === true) {
// Return serialized object
return {
// Value
"Value": object.map(function(value) {
// Return serialized value
return Common.serializeObject(value);
})
};
}
// Otherwise check if object is an object
else if(typeof object === "object" && object !== null) {
// Check if object is a typed array
if("buffer" in object === true && object["buffer"] instanceof ArrayBuffer === true) {
// Get object's type
var type = Object["prototype"]["toString"].call(object).match(Common.OBJECT_TYPE_PATTERN);
// Return serialized object
return {
// Constructor
"Constructor": (type !== Common.NO_MATCH_FOUND) ? type[1] : object["constructor"]["name"],
// Value
"Value": Array.from(object)
};
}
// Otherwise
else {
// Return serialized object
return {
// Constructor
"Constructor": (object instanceof BigNumber === true) ? "BigNumber" : object["constructor"]["name"],
// Properties
"Properties": Object.entries(object).map(function(property) {
// Return serialized property
return {
// Name
"Name": property[0],
// Value
"Value": Common.serializeObject(property[1])
};
})
};
}
}
// Otherwise
else {
// Return serialized object
return {
// Value
"Value": object
};
}
}
// Unserialize object
static unserializeObject(serializedObject) {
// Check if serialized object contains a constructor
if("Constructor" in serializedObject === true) {
// Check if serialized object can be created
if(serializedObject["Constructor"] in globalThis === true) {
// Check if serialzed object is a typed array
if("Value" in serializedObject === true) {
// Create object
var object = new globalThis[serializedObject["Constructor"]](serializedObject["Value"]);
// Return object
return object;
}
// Otherwise
else {
// Create object
var object = Object.create(globalThis[serializedObject["Constructor"]]["prototype"]);
// Go through all of the serialized object's properties
for(var i = 0; i < serializedObject["Properties"]["length"]; ++i) {
// Get property
var property = serializedObject["Properties"][i];
// Set property in the object
object[property["Name"]] = Common.unserializeObject(property["Value"]);
}
// Return object
return object;
}
}
// Otherwise
else {
// Return undefined
return undefined;
}
}
// Otherwise check if serialzied object is an array
else if(Array.isArray(serializedObject["Value"]) === true) {
// Return serialized object's value
return serializedObject["Value"].map(function(serializedValue) {
// Return unserializing the serialized value
return Common.unserializeObject(serializedValue);
});
}
// Otherwise
else {
// Return serialized object's value
return serializedObject["Value"];
}
}
// Request animation frame or timeout
static requestAnimationFrameOrTimeout(callback) {
// Initialize animation frame
var animationFrame;
// Set timeout
var timeout = setTimeout(function() {
// Cancel animation frame
cancelAnimationFrame(animationFrame);
// Run callback
callback(event);
}, Common.REQUEST_ANIMATION_FRAME_TIMEOUT_MILLISECONDS);
// Set animation frame
animationFrame = requestAnimationFrame(function(event) {
// Clear timeout
clearTimeout(timeout);
// Run callback
callback(event);
});
}
// Ltrim
static ltrim(text) {
// Return text with leading whitespace removed
return text.replace(Common.LEADING_WHITESPACE_PATTERN, "");
}
// Rtrim
static rtrim(text) {
// Return text with trailing whitespace removed
return text.replace(Common.TRAILING_WHITESPACE_PATTERN, "");
}
// Get preserved URL parameters
static getPreservedUrlParameters() {
// Check if is popup
if(Common.isPopup() === true) {
// Return preserved URL parameters
return Common.URL_QUERY_STRING_PARAMETER_SEPARATOR + encodeURIComponent("Is Popup").replace(/%20/ug, "+") + Common.URL_QUERY_STRING_PARAMETER_VALUE_SEPARATOR + encodeURIComponent("True").replace(/%20/ug, "+");
}
// Otherwise
else {
// Return nothing
return "";
}
}
// Save file
static saveFile(name, contents) {
// Create anchor
var anchor = $("<a></a>");
// Create URL from contents
var url = URL.createObjectURL(new Blob([
// Contents
contents
], {
// Type
"type": "application/octet-stream"
}));
// Set anchor's href to URL
anchor.attr("href", url);
// Set anchor's download to name
anchor.attr("download", name);
// Click on anchor
anchor.get(0).click();
// Set timeout
setTimeout(function() {
// Revoke URL
URL.revokeObjectURL(url);
}, 0);
}
// Has whitespace
static hasWhitespace(text) {
// Return if text has whitespace
return Common.HAS_WHITESPACE_PATTERN.test(text) === true;
}
// Remove whitespace
static removeWhitespace(text) {
// Return text with whitespace removed
return text.replace(Common.HAS_WHITESPACE_PATTERN, "");
}
// Milliseconds in a second
static get MILLISECONDS_IN_A_SECOND() {
// Return milliseconds in a second
return 1000;
}
// Seconds in a minute
static get SECONDS_IN_A_MINUTE() {
// Return minutes in a second
return 60;
}
// Minutes in an hour
static get MINUTES_IN_AN_HOUR() {
// Return minutes in an hour
return 60;
}
// Hours in a day
static get HOURS_IN_A_DAY() {
// Return hours in a day
return 24;
}
// Days in a week
static get DAYS_IN_A_WEEK() {
// Return days in a week
return 7;
}
// Weeks in a year
static get WEEKS_IN_A_YEAR() {
// Return weeks in a year
return 52;
}
// Byte max value
static get BYTE_MAX_VALUE() {
// Return byte max value
return Math.pow(2, Common.BITS_IN_A_BYTE) - 1;
}
// Uint16 max value
static get UINT16_MAX_VALUE() {
// Return uint16 max value
return Math.pow(2, Common.BITS_IN_A_BYTE * Uint16Array["BYTES_PER_ELEMENT"]) - 1;
}
// Uint32 max value
static get UINT32_MAX_VALUE() {
// Return uint32 max value
return Math.pow(2, Common.BITS_IN_A_BYTE * Uint32Array["BYTES_PER_ELEMENT"]) - 1;
}
// Int32 max value
static get INT32_MAX_VALUE() {
// Return int32 max value
return Math.pow(2, Common.BITS_IN_A_BYTE * Int32Array["BYTES_PER_ELEMENT"] - 1) - 1;
}
// Bytes in a uint8
static get BYTES_IN_A_UINT8() {
// Return bytes in a uint8
return 8 / Common.BITS_IN_A_BYTE;
}
// Bytes in a uint16
static get BYTES_IN_A_UINT16() {
// Return bytes in a uint16
return 16 / Common.BITS_IN_A_BYTE;
}
// Bytes in a uint32
static get BYTES_IN_A_UINT32() {
// Return bytes in a uint32
return 32 / Common.BITS_IN_A_BYTE;
}
// Bytes in a uint64
static get BYTES_IN_A_UINT64() {
// Return bytes in a uint64
return 64 / Common.BITS_IN_A_BYTE;
}
// Invalid local storage item
static get INVALID_LOCAL_STORAGE_ITEM() {
// Return invalid local storage item
return null;
}
// Index not found
static get INDEX_NOT_FOUND() {
// Return index not found
return -1;
}
// No match found
static get NO_MATCH_FOUND() {
// Return no match found
return null;
}
// No tab index
static get NO_TAB_INDEX() {
// Return no tab index
return "-1";
}
// Decimal number base
static get DECIMAL_NUMBER_BASE() {
// Return decimal number base
return 10;
}
// Hex number base
static get HEX_NUMBER_BASE() {
// Return hex number base
return 16;
}
// Hex number length
static get HEX_NUMBER_LENGTH() {
// Return hex number length
return "FF"["length"];
}
// Hex color length
static get HEX_COLOR_LENGTH() {
// Return hex color length
return "FFFFFF"["length"];
}
// Hex number padding
static get HEX_NUMBER_PADDING() {
// Return hex number padding
return "0";
}
// Focus change event
static get FOCUS_CHANGE_EVENT() {
// Return focus change event
return "FocusChangeEvent";
}
// No attribute
static get NO_ATTRIBUTE() {
// Return no attribute
return undefined;
}
// No argument
static get NO_ARGUMENT() {
// Return no argument
return undefined;
}
// URL query string separator
static get URL_QUERY_STRING_SEPARATOR() {
// Return URL query string separator
return "?";
}
// URL query string parameter separator
static get URL_QUERY_STRING_PARAMETER_SEPARATOR() {
// Return URL query string parameter separator
return "&";
}
// URL query string parameter value separator
static get URL_QUERY_STRING_PARAMETER_VALUE_SEPARATOR() {
// Return URL query string parameter value separator
return "=";
}
// Data attribute prefix
static get DATA_ATTRIBUTE_PREFIX() {
// Return data attribute prefix
return "data-";
}
// First match result index
static get FIRST_MATCH_RESULT_INDEX() {
// Return first match result index
return 1;
}
// JSON NULL value
static get JSON_NULL_VALUE() {
// Return JSON NULL value
return null;
}
// HTTP protocol
static get HTTP_PROTOCOL() {
// Return HTTP protocol
return "http:";
}
// HTTPS protocol
static get HTTPS_PROTOCOL() {
// Return HTTPS protocol
return "https:";
}
// WebSocket protocol
static get WEBSOCKET_PROTOCOL() {
// Return WebSocket protocol
return "ws:";
}
// WebSocket secure protocol
static get WEBSOCKET_SECURE_PROTOCOL() {
// Return WebSocket secure protocol
return "wss:";
}
// File protocol
static get FILE_PROTOCOL() {
// Return file protocol
return "file:";
}
// HTTP no response status
static get HTTP_NO_RESPONSE_STATUS() {
// Return HTTP no response status
return 0;
}
// HTTP ok status
static get HTTP_OK_STATUS() {
// Return HTTP ok status
return 200;
}
// HTTP bad request status
static get HTTP_BAD_REQUEST_STATUS() {
// Return HTTP bad request status
return 400;
}
// HTTP unauthorized status
static get HTTP_UNAUTHORIZED_STATUS() {
// Return HTTP unauthorized status
return 401;
}
// HTTP forbidden status
static get HTTP_FORBIDDEN_STATUS() {
// Return HTTP forbidden status
return 403;
}
// HTTP not found status
static get HTTP_NOT_FOUND_STATUS() {
// Return HTTP not found status
return 404;
}
// HTTP payload too large status
static get HTTP_PAYLOAD_TOO_LARGE_STATUS() {
// Return HTTP payload too large status
return 413;
}
// HTTP unsupported media type status
static get HTTP_UNSUPPORTED_MEDIA_TYPE_STATUS() {
// Return HTTP unsupported media type status
return 415;
}
// HTTP bad gateway status
static get HTTP_BAD_GATEWAY_STATUS() {
// Return HTTP bad gateway status
return 502;
}
// HTTP gateway timeout status
static get HTTP_GATEWAY_TIMEOUT_STATUS() {
// Return HTTP gateway timeout status
return 504;
}
// Double quote pattern
static get DOUBLE_QUOTE_PATTERN() {
// Return double quote pattern
return /"/ug;
}
// Enable event
static get ENABLE_EVENT() {
// Return enable event
return "CommonEnableEvent";
}
// Primary pointer button bitmask
static get PRIMARY_POINTER_BUTTON_BITMASK() {
// Return primary pointer button bitmask
return 1;
}
// January month index
static get JANUARY_MONTH_INDEX() {
// Return january month index
return 0;
}
// Sort equal to
static get SORT_EQUAL() {
// Return sort equal
return 0;
}
// Sort greater than
static get SORT_GREATER_THAN() {
// Return sort greater than
return Common.SORT_EQUAL + 1;
}
// Sort less than
static get SORT_LESS_THAN() {
// Return sort less than
return Common.SORT_EQUAL - 1;
}
// Visibility state visible
static get VISIBILITY_STATE_VISIBLE() {
// Return visibility state visible
return "visible";
}
// Visibility state hidden
static get VISIBILITY_STATE_HIDDEN() {
// Return visibility state hidden
return "hidden";
}
// Canceled error
static get CANCELED_ERROR() {
// Return canceled error
return "CommonCancelError";
}
// No cancel occurred
static get NO_CANCEL_OCCURRED() {
// Return no cancel occurred
return null;
}
// Hex prefix
static get HEX_PREFIX() {
// Return hex prefix
return "0x";
}
// Default HTTP port
static get DEFAULT_HTTP_PORT() {
// Return default HTTP port
return 80;
}
// Default HTTPS port
static get DEFAULT_HTTPS_PORT() {
// Return default HTTPS port
return 443;
}
// Private
// Bits in a byte
static get BITS_IN_A_BYTE() {
// Return bits in a byte
return 8;
}
// Number string pattern
static get NUMBER_STRING_PATTERN() {
// Return number string pattern
return /^[+-]?(?:0(?:\.\d+)?|[1-9]\d*(?:\.\d+)?|\.\d+)$/u;
}
// Hex string pattern
static get HEX_STRING_PATTERN() {
// Return hex string pattern
return /^(?:[0-9A-F])+$/iu;
}
// Hex character to value
static get HEX_CHARACTER_TO_VALUE() {
// Return hex character to value
return {
// Zero
"0": 0x00,
// One
"1": 0x01,
// Two
"2": 0x02,
// Three
"3": 0x03,
// Four
"4": 0x04,
// Five
"5": 0x05,
// Six
"6": 0x06,
// Seven
"7": 0x07,
// Eight
"8": 0x08,
// Nine
"9": 0x09,
// Uppercase a
"A": 0x0A,
// Uppercase b
"B": 0x0B,
// Uppercase c
"C": 0x0C,
// Uppercase d
"D": 0x0D,
// Uppercase e
"E": 0x0E,
// Uppercase f
"F": 0x0F,
// Lowercase a
"a": 0x0A,
// Lowercase b
"b": 0x0B,
// Lowercase c
"c": 0x0C,
// Lowercase d
"d": 0x0D,
// Lowercase e
"e": 0x0E,
// Lowercase f
"f": 0x0F
};
}
// Value to hex character
static get VALUE_TO_HEX_CHARACTER() {
// Return value to hex character
return [
// Zero
"0",
// One
"1",
// Two
"2",
// Three
"3",
// Four
"4",
// Five
"5",
// Six
"6",
// Seven
"7",
// Eight
"8",
// Nine
"9",
// A
"a",
// B
"b",
// C
"c",
// D
"d",
// E
"e",
// F
"f"
];
}
// RFC 3339 string pattern
static get RFC_3339_STRING_PATTERN() {
// Return RFC 3339 string pattern
return /^(?:\d+)-(?:0[1-9]|1[012])-(?:0[1-9]|[12]\d|3[01])[Tt](?:[01]\d|2[0-3]):(?:[0-5]\d):(?:[0-5]\d|60)(?:\.\d+)?(?:(?:[Zz])|(?:[\+|\-](?:[01]\d|2[0-3]):[0-5]\d))$/u;
}
// Lowercase string pattern
static get LOWERCASE_STRING_PATTERN() {
// Return lowercase string pattern
return /^[a-z0-9]+$/u;
}
// Single quote HTML entity
static get SINGLE_QUOTE_HTML_ENTITY() {
// Return single quote HTML entity
return "&#39;";
}
// Double quote HTML entity
static get DOUBLE_QUOTE_HTML_ENTITY() {
// Return double quote HTML entity
return "&quot;";
}
// Grave accent HTML entity
static get GRAVE_ACCENT_HTML_ENTITY() {
// Return grave accent HTML entity
return "&#96;";
}
// Single quote pattern
static get SINGLE_QUOTE_PATTERN() {
// Return single quote pattern
return /'/ug;
}
// Grave accent pattern
static get GRAVE_ACCENT_PATTERN() {
// Return grave accent pattern
return /`/ug;
}
// Return low memory threshold gigabytes
static get LOW_MEMORY_THRESHOLD_GIGABYTES() {
// Return low memory threshold gigabytes
return 2;
}
// Return high memory threshold gigabytes
static get HIGH_MEMORY_THRESHOLD_GIGABYTES() {
// Return high memory threshold gigabytes
return 8;
}
// URL protocol pattern
static get URL_PROTOCOL_PATTERN() {
// Return URL protocol pattern
return /^[^:]+:\/\/.+/u;
}
// URL top-level domain pattern
static get URL_TOP_LEVEL_DOMAIN_PATTERN() {
// Return URL top-level domain pattern
return /[^\.]+\.[^\/?:#\s]+(?:[\/?:#\s]|$)/u;
}
// URL domain name pattern
static get URL_DOMAIN_NAME_PATTERN() {
// Return URL domain name pattern
return /[^\.]+\.[^\.]+$/u;
}
// URL without top-level domain pattern
static get URL_WITHOUT_TOP_LEVEL_DOMAIN_PATTERN() {
// Return URL without top-level domain pattern
return /([^\.]+)\.[^\.]+$/u;
}
// Trailing slashes pattern
static get TRAILING_SLASHES_PATTERN() {
// Return trailing slashes pattern
return /\/+$/u;
}
// Duplicate slashes pattern
static get DUPLICATE_SLASHES_PATTERN() {
// Return duplicate slashes pattern
return /\/+/ug;
}
// Duplicate newline pattern
static get DUPLICATE_NEWLINE_PATTERN() {
// Return duplicate newline pattern
return /\n+/ug;
}
// Trailing zeros pattern
static get TRAILING_ZEROS_PATTERN() {
// Return trailing zeros pattern
return /(\.\d*?)0+$/u;
}
// Ending decimal point pattern
static get ENDING_DECIMAL_POINT_PATTERN() {
// Return ending decimal point pattern
return /\.$/u;
}
// Trailing newline pattern
static get TRAILING_NEWLINE_PATTERN() {
// Return trailing newline pattern
return /\n$/u;
}
// Object type pattern
static get OBJECT_TYPE_PATTERN() {
// Return object type pattern
return /^\[object\s*(.*)\]$/u;
}
// Request animation frame timeout milliseconds
static get REQUEST_ANIMATION_FRAME_TIMEOUT_MILLISECONDS() {
// Return request animation frame timeout milliseconds
return 100;
}
// Leading whitespace pattern
static get LEADING_WHITESPACE_PATTERN() {
// Return leading whitespace pattern
return /^\s+/u;
}
// Trailing whitespace pattern
static get TRAILING_WHITESPACE_PATTERN() {
// Return leading whitespace pattern
return /\s+$/u;
}
// Has whitespace pattern
static get HAS_WHITESPACE_PATTERN() {
// Return has whitespace pattern
return /\s/ug;
}
}
// Main function
// Set global object's common
globalThis["Common"] = Common;
// Check if jQuery exists
if(typeof jQuery === "function") {
// Disable tab
$["prototype"].disableTab = function() {
// Go through each element
this.each(function() {
// Add no tab index to element
$(this).attr("tabindex", Common.NO_TAB_INDEX);
});
// Return elements
return this;
};
// Enable tab
$["prototype"].enableTab = function() {
// Go through each element
this.each(function() {
// Remove tab index from element
$(this).removeAttr("tabindex");
});
// Return elements
return this;
};
// Disable
$["prototype"].disable = function() {
// Go through each element
this.each(function() {
// Disable the element
$(this).prop("disabled", true);
});
// Return elements
return this;
};
// Enable
$["prototype"].enable = function() {
// Go through each element
this.each(function() {
// Enable the element and trigger an enable event on the element
$(this).prop("disabled", false).trigger(Common.ENABLE_EVENT);
});
// Return elements
return this;
};
// Outer Html
$["prototype"].outerHtml = function() {
// Return element's outer HTML
return this.wrap("<div>").parent().html();
};
// Scroll idle duration milliseconds
var SCROLL_IDLE_DURATION_MILLISECONDS = 250;
// Scroll stopped
$["fn"].scrollStopped = function(callback) {
// Go through each element
this.each(function() {
// Set self
var self = $(this);
// Get index
var index = (typeof self.data("scrollStoppedIndex") === "undefined") ? 0 : self.data("scrollStoppedIndex");
// Self scroll scroll stopped index event
self.on("scroll.scrollStopped" + index.toFixed(), function(event) {
// Check if scroll stopped timeout index exists
if(typeof self.data("scrollStoppedTimeout" + index.toFixed()) !== "undefined") {
// Clear scroll stopped timeout index
clearTimeout(self.data("scrollStoppedTimeout" + index.toFixed()));
}
// Set scroll stopped timeout index
self.data("scrollStoppedTimeout" + index.toFixed(), setTimeout(function() {
// Remove scroll stopped timeout index
self.removeData("scrollStoppedTimeout" + index.toFixed());
// Run callback
callback.bind(self)(event);
}, SCROLL_IDLE_DURATION_MILLISECONDS));
});
// Increment index
self.data("scrollStoppedIndex", (index === Number.MAX_SAFE_INTEGER) ? 0 : index + 1);
});
// Return elements
return this;
};
// Transition end timeout milliseconds
var TRANSITION_END_TIMEOUT_MILLISECONDS = 100;
// Transition end or timeout
$["fn"].transitionEndOrTimeout = function(callback, property) {
// Go through each element
this.each(function() {
// Set self
var self = $(this);
// Set timeout
var timeout = TRANSITION_END_TIMEOUT_MILLISECONDS;
// Go through all of the element's transition properties
var properties = self.css("transition-property").split(",");
for(var i = 0; i < properties["length"]; ++i) {
// Check if property was found
if(properties[i].trim() === property) {
// Get transition's duration
var duration = self.css("transition-duration").split(",")[i].trim();
// Get transition's delay
var delay = self.css("transition-delay").split(",")[i].trim();
// Set timeout to the duration
timeout = parseFloat(duration) * ((duration.indexOf("ms") !== Common.INDEX_NOT_FOUND) ? 1 : Common.MILLISECONDS_IN_A_SECOND) + parseFloat(delay) * ((delay.indexOf("ms") !== Common.INDEX_NOT_FOUND) ? 1 : Common.MILLISECONDS_IN_A_SECOND) + TRANSITION_END_TIMEOUT_MILLISECONDS;
// Break
break;
}
}
// Get index
var index = (typeof self.data("transitionEndOrTimeoutIndex") === "undefined") ? 0 : self.data("transitionEndOrTimeoutIndex");
// Set transition end or timeout timeout index
self.data("transitionEndOrTimeoutTimeout" + index.toFixed(), setTimeout(function() {
// Turn off transition end transition end or timeout index event
self.off("transitionend.transitionEndOrTimeout" + index.toFixed());
// Remove transition end or timeout timeout index
self.removeData("transitionEndOrTimeoutTimeout" + index.toFixed());
// Run callback
callback.bind(self)();
}, timeout));
// Self transition end transition end or timeout index event
self.one("transitionend.transitionEndOrTimeout" + index.toFixed(), function(event) {
// Clear transition end or timeout timeout index
clearTimeout(self.data("transitionEndOrTimeoutTimeout" + index.toFixed()));
// Remove transition end or timeout timeout index
self.removeData("transitionEndOrTimeoutTimeout" + index.toFixed());
// Run callback
callback.bind(self)(event);
});
// Increment index
self.data("transitionEndOrTimeoutIndex", (index === Number.MAX_SAFE_INTEGER) ? 0 : index + 1);
});
// Return elements
return this;
};
// Off transition end or timeout
$["fn"].offTransitionEndOrTimeout = function() {
// Go through each element
this.each(function() {
// Set self
var self = $(this);
// Turn off transition end event
self.off("transitionend");
// Get data
var data = self.data();
// Go through all data
for(var key in data) {
if(data.hasOwnProperty(key) === true) {
// Check if data is a transition end or timeout timeout index
if(key.indexOf("transitionEndOrTimeoutTimeout") === 0) {
// Clear transition end or timeout timeout index
clearTimeout(self.data(key));
// Remove transition end or timeout timeout index
self.removeData(key);
}
}
}
});
// Return elements
return this;
};
}
// Check if BigNumber exists
if(typeof BigNumber === "function") {
// Big endian
BigNumber.BIG_ENDIAN = 0;
// Little endian
BigNumber.LITTLE_ENDIAN = 1;
// Any length
BigNumber.ANY_LENGTH = -1;
// To bytes
BigNumber.prototype.toBytes = function(endianness = BigNumber.LITTLE_ENDIAN, length = BigNumber.ANY_LENGTH) {
// Check if is number isn't supported
if(this.isFinite() === false || this.isNaN() === true || this.isNegative() === true || this.isInteger() === false) {
// Throw error
throw "Unsupported number.";
}
// Otherwise
else {
// Create bytes
var bytes = new Array((length === BigNumber.ANY_LENGTH) ? 1 : length).fill(0);
// Make number a whole number
var temp = this.dividedToIntegerBy(1);
// Go through all bytes in the whole number
for(var i = 0; temp.isGreaterThan(0); ++i) {
// Get byte from the whole number
var byte = temp.modulo(Common.BYTE_MAX_VALUE + 1).toNumber();
// Remove byte from the whole number
temp = temp.dividedToIntegerBy(Common.BYTE_MAX_VALUE + 1);
// Check if space exists in bytes for the byte
if(i < bytes["length"]) {
// Set byte in bytes
bytes[i] = byte;
}
// Otherwise check if length is Constrained
else if(length !== BigNumber.ANY_LENGTH) {
// Throw error
throw "Insufficient length.";
}
// Otherwise
else {
// Append byte to bytes
bytes.push(byte);
}
}
// Check if endianness is big endian
if(endianness === BigNumber.BIG_ENDIAN) {
// Reverse bytes order
bytes = bytes.reverse();
}
// Return bytes
return new Uint8Array(bytes);
}
};
}
// Check if object exists
if(typeof Object === "function") {
// Is object
Object.isObject = function(variable) {
// Try
try {
// Return if variable is an object
return Object.getPrototypeOf(variable)["constructor"]["name"] === "Object";
}
// Catch errors
catch(error) {
// Return false
return false;
}
};
}
// Check if Uint8Array exist
if(typeof Uint8Array === "function") {
// Read uint32 little endian
Uint8Array["prototype"].readUInt32LE = function(index) {
// Return value at index as a uint32 in little endian
return this[index] | (this[index + 1] << Common.BITS_IN_A_BYTE) | (this[index + 2] << (Common.BITS_IN_A_BYTE * 2)) | (this[index + 3] << (Common.BITS_IN_A_BYTE * 3));
};
// Read uint16 little endian
Uint8Array["prototype"].readUInt16LE = function(index) {
// Return value at index as a uint16 in little endian
return this[index] | (this[index + 1] << Common.BITS_IN_A_BYTE);
};
}
// Check if cross-origin isolated doesn't exist
if(typeof crossOriginIsolated === "undefined") {
// Set cross-origin isolated to false
var crossOriginIsolated = false;
}