From 3bdbf03658deb38271323f046898fdeaff63a097 Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Wed, 23 Oct 2019 13:30:07 +1100 Subject: [PATCH 1/6] Enforce display name --- background.html | 7 +++--- js/views/nickname_dialog_view.js | 20 +++++++--------- js/views/standalone_registration_view.js | 29 +++++++++++++++--------- stylesheets/_global.scss | 9 ++++++++ 4 files changed, 38 insertions(+), 27 deletions(-) diff --git a/background.html b/background.html index a2c80e74b..d489a7b4e 100644 --- a/background.html +++ b/background.html @@ -196,7 +196,6 @@
{{ message }}
{{ /message }}
-
@@ -646,7 +645,7 @@
Enter your public display name (alphanumeric characters and underscores only)
- +
Type an optional password for added security
@@ -655,8 +654,8 @@
- Back - Save + +
diff --git a/js/views/nickname_dialog_view.js b/js/views/nickname_dialog_view.js index ba65ff4de..9d33a730e 100644 --- a/js/views/nickname_dialog_view.js +++ b/js/views/nickname_dialog_view.js @@ -19,9 +19,6 @@ this.reject = options.reject; this.cancelText = options.cancelText || i18n('cancel'); - this.clear = options.clear; - this.clearText = options.clearText || i18n('clear'); - this.title = options.title; this.render(); @@ -52,16 +49,17 @@ keyup: 'onKeyup', 'click .ok': 'ok', 'click .cancel': 'cancel', - 'click .clear': 'clear', change: 'validateNickname', }, validateNickname() { const nickname = this.$input.val(); if (_.isEmpty(nickname)) { - this.$('.clear').hide(); + this.$('.ok').attr('disabled', 'disabled'); + return false; } else { - this.$('.clear').show(); + this.$('.ok').removeAttr('disabled'); + return true; } }, render_attributes() { @@ -70,7 +68,6 @@ showCancel: !this.hideCancel, cancel: this.cancelText, ok: this.okText, - clear: this.clearText, title: this.title, }; }, @@ -88,14 +85,13 @@ this.reject(); } }, - clear() { - this.$input.val('').trigger('change'); - }, onKeyup(event) { - this.validateNickname(); + const valid = this.validateNickname(); switch (event.key) { case 'Enter': - this.ok(); + if (valid) { + this.ok(); + } break; case 'Escape': case 'Esc': diff --git a/js/views/standalone_registration_view.js b/js/views/standalone_registration_view.js index 46036eac4..7d863ac18 100644 --- a/js/views/standalone_registration_view.js +++ b/js/views/standalone_registration_view.js @@ -57,21 +57,13 @@ this.onValidatePassword(); - const sanitiseNameInput = () => { - const oldVal = this.$('#display-name').val(); - this.$('#display-name').val(oldVal.replace(/[^a-zA-Z0-9_]/g, '')); - }; - - this.$('#display-name').get(0).oninput = () => { - sanitiseNameInput(); - }; - this.$('#display-name').get(0).onpaste = () => { // Sanitise data immediately after paste because it's easier setTimeout(() => { - sanitiseNameInput(); + this.sanitiseNameInput(); }); }; + this.sanitiseNameInput(); }, events: { keyup: 'onKeyup', @@ -91,6 +83,18 @@ 'keyup #password': 'onValidatePassword', 'keyup #password-confirmation': 'onValidatePassword', }, + sanitiseNameInput() { + const oldVal = this.$('#display-name').val(); + const newVal = oldVal.replace(/[^a-zA-Z0-9_]/g, ''); + this.$('#display-name').val(newVal); + if (_.isEmpty(newVal)) { + this.$('#save-button').attr('disabled', 'disabled'); + return false; + } else { + this.$('#save-button').removeAttr('disabled'); + return true; + } + }, async showPage(pageIndex) { // eslint-disable-next-line func-names this.$pages.each(function(index) { @@ -123,9 +127,12 @@ return; } + const validName = this.sanitiseNameInput(); switch (event.key) { case 'Enter': - this.onSaveProfile(); + if (validName) { + this.onSaveProfile(); + } break; case 'Escape': case 'Esc': diff --git a/stylesheets/_global.scss b/stylesheets/_global.scss index da7f21736..f3fc177ce 100644 --- a/stylesheets/_global.scss +++ b/stylesheets/_global.scss @@ -69,6 +69,15 @@ audio { button { cursor: pointer; font-size: inherit; + + &[disabled='disabled'] { + &, + &:hover { + opacity: 0.5; + box-shadow: none; + cursor: default; + } + } } button.grey { border-radius: $border-radius; From 22df66c08fb3c23337de84dfb0b8a0e4e4cc412b Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Wed, 23 Oct 2019 13:30:25 +1100 Subject: [PATCH 2/6] Fix missing await, fix undefined bug --- background.html | 2 ++ js/models/conversations.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/background.html b/background.html index d489a7b4e..8bb34969d 100644 --- a/background.html +++ b/background.html @@ -654,6 +654,8 @@
+ +
diff --git a/js/models/conversations.js b/js/models/conversations.js index 35ecae10c..4da731a20 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -2015,7 +2015,7 @@ ); const ourNumber = textsecure.storage.user.getNumber(); return !stillUnread.some( - m => m.propsForMessage.text.indexOf(`@${ourNumber}`) !== -1 + m => m.propsForMessage.text && m.propsForMessage.text.indexOf(`@${ourNumber}`) !== -1 ); })(); @@ -2419,7 +2419,7 @@ }, async deletePublicMessage(message) { - const channelAPI = this.getPublicSendData(); + const channelAPI = await this.getPublicSendData(); if (!channelAPI) { return false; } From 49fcb50d483af8bb716a0b676569daf3e3ca31d6 Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Wed, 23 Oct 2019 13:41:07 +1100 Subject: [PATCH 3/6] Update link preview settings to be cleaner --- _locales/en/messages.json | 9 ++------- js/views/settings_view.js | 1 - settings.html | 12 ++++-------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 81a15ee2c..ebfe68fab 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1227,14 +1227,9 @@ "description": "Option to control creation and send of link previews in setting screen" }, - "linkPreviewsDescription": { - "message": - "Previews are supported for Imgur, Instagram, Reddit, and YouTube links.", - "description": - "Additional detail provided for Link Previews option in settings screen" - }, "linkPreviewsSettingDescription": { - "message": "Enable local link previews", + "message": + "Enable link previews", "description": "Description shown for the Link Preview option " }, "spellCheckDescription": { diff --git a/js/views/settings_view.js b/js/views/settings_view.js index e30e14d3c..f1d254196 100644 --- a/js/views/settings_view.js +++ b/js/views/settings_view.js @@ -250,7 +250,6 @@ spellCheckDescription: i18n('spellCheckDescription'), blockedHeader: 'Blocked Users', linkPreviews: i18n('linkPreviews'), - linkPreviewsDescription: i18n('linkPreviewsDescription'), linkPreviewsSettingDescription: i18n('linkPreviewsSettingDescription'), }; }, diff --git a/settings.html b/settings.html index 0d573e162..bd10df867 100644 --- a/settings.html +++ b/settings.html @@ -100,15 +100,11 @@ + -
-

{{ linkPreviews }}

-
{{ linkPreviewsDescription }}
-
-

{{ permissions }}

From a3635216db123c9d94c59940eb0a3e1e051d23d1 Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Wed, 23 Oct 2019 14:00:55 +1100 Subject: [PATCH 4/6] Enable sending audio recordings --- _locales/en/messages.json | 3 +-- background.html | 6 ++---- js/models/conversations.js | 4 +++- js/modules/loki_app_dot_net_api.js | 11 ++++++++++- js/views/conversation_view.js | 5 ----- js/views/nickname_dialog_view.js | 5 ++--- js/views/standalone_registration_view.js | 5 ++--- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index ebfe68fab..1355e2f87 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1228,8 +1228,7 @@ "Option to control creation and send of link previews in setting screen" }, "linkPreviewsSettingDescription": { - "message": - "Enable link previews", + "message": "Enable link previews", "description": "Description shown for the Link Preview option " }, "spellCheckDescription": { diff --git a/background.html b/background.html index 8bb34969d..91db71824 100644 --- a/background.html +++ b/background.html @@ -133,12 +133,12 @@
-
+
- +
@@ -654,8 +654,6 @@
- -
diff --git a/js/models/conversations.js b/js/models/conversations.js index 4da731a20..12b67d756 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -2015,7 +2015,9 @@ ); const ourNumber = textsecure.storage.user.getNumber(); return !stillUnread.some( - m => m.propsForMessage.text && m.propsForMessage.text.indexOf(`@${ourNumber}`) !== -1 + m => + m.propsForMessage.text && + m.propsForMessage.text.indexOf(`@${ourNumber}`) !== -1 ); })(); diff --git a/js/modules/loki_app_dot_net_api.js b/js/modules/loki_app_dot_net_api.js index c0670aedd..cd4352e59 100644 --- a/js/modules/loki_app_dot_net_api.js +++ b/js/modules/loki_app_dot_net_api.js @@ -942,7 +942,16 @@ class LokiPublicChannelAPI { } static getAnnotationFromAttachment(attachment) { - const type = attachment.contentType.match(/^image/) ? 'photo' : 'video'; + let type; + if (attachment.contentType.match(/^image/)) { + type = 'photo'; + } else if (attachment.contentType.match(/^video/)) { + type = 'video'; + } else if (attachment.contentType.match(/^audio/)) { + type = 'audio'; + } else { + type = 'other'; + } const annotation = { type: ATTACHMENT_TYPE, value: { diff --git a/js/views/conversation_view.js b/js/views/conversation_view.js index b643b4a43..cd7d14cf7 100644 --- a/js/views/conversation_view.js +++ b/js/views/conversation_view.js @@ -636,10 +636,6 @@ }, toggleMicrophone() { - // ALWAYS HIDE until we support audio - this.$('.capture-audio').hide(); - - /* if ( this.$('.send-message').val().length > 0 || this.fileInput.hasFiles() @@ -648,7 +644,6 @@ } else { this.$('.capture-audio').show(); } - */ }, captureAudio(e) { e.preventDefault(); diff --git a/js/views/nickname_dialog_view.js b/js/views/nickname_dialog_view.js index 9d33a730e..3890c342f 100644 --- a/js/views/nickname_dialog_view.js +++ b/js/views/nickname_dialog_view.js @@ -57,10 +57,9 @@ if (_.isEmpty(nickname)) { this.$('.ok').attr('disabled', 'disabled'); return false; - } else { - this.$('.ok').removeAttr('disabled'); - return true; } + this.$('.ok').removeAttr('disabled'); + return true; }, render_attributes() { return { diff --git a/js/views/standalone_registration_view.js b/js/views/standalone_registration_view.js index 7d863ac18..b621c204d 100644 --- a/js/views/standalone_registration_view.js +++ b/js/views/standalone_registration_view.js @@ -90,10 +90,9 @@ if (_.isEmpty(newVal)) { this.$('#save-button').attr('disabled', 'disabled'); return false; - } else { - this.$('#save-button').removeAttr('disabled'); - return true; } + this.$('#save-button').removeAttr('disabled'); + return true; }, async showPage(pageIndex) { // eslint-disable-next-line func-names From 2f52995e18ed643130d7cfb01120e6d8d213a769 Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Fri, 25 Oct 2019 12:06:39 +1100 Subject: [PATCH 5/6] Fix the delete messages button to not break the conversation --- _locales/en/messages.json | 2 +- js/models/conversations.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 1355e2f87..a6a98762f 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1053,7 +1053,7 @@ "Confirmation dialog text that asks the user if they really wish to delete the public channel messages locally. Answer buttons use the strings 'ok' and 'cancel'. The deletion is permanent, i.e. it cannot be undone." }, "deleteConversationConfirmation": { - "message": "Permanently delete this conversation?", + "message": "Permanently delete the messages in this conversation?", "description": "Confirmation dialog text that asks the user if they really wish to delete the conversation. Answer buttons use the strings 'ok' and 'cancel'. The deletion is permanent, i.e. it cannot be undone." }, diff --git a/js/models/conversations.js b/js/models/conversations.js index 12b67d756..8e471760b 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -2450,8 +2450,8 @@ }); } else { Whisper.events.trigger('showConfirmationDialog', { - message: i18n('deleteContactConfirmation'), - onOk: () => ConversationController.deleteContact(this.id), + message: i18n('deleteConversationConfirmation'), + onOk: () => this.destroyMessages(), }); } }, From 6a512503f04d5fe29fa5e510d914a13dfcf4581b Mon Sep 17 00:00:00 2001 From: Beaudan Brown Date: Mon, 28 Oct 2019 12:45:13 +1100 Subject: [PATCH 6/6] Update display name sanitisation to allow a bunch of languages and spaces --- .eslintrc.js | 1 + js/views/nickname_dialog_view.js | 4 ++-- js/views/standalone_registration_view.js | 7 ++++--- preload.js | 3 +++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 6451fae05..e5dd5e85d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -65,6 +65,7 @@ module.exports = { // We still want to limit comments as before: comments: 90, ignoreUrls: true, + ignoreRegExpLiterals: true, }, ], }, diff --git a/js/views/nickname_dialog_view.js b/js/views/nickname_dialog_view.js index 3890c342f..398ec3c41 100644 --- a/js/views/nickname_dialog_view.js +++ b/js/views/nickname_dialog_view.js @@ -1,4 +1,4 @@ -/* global Whisper, i18n, _ */ +/* global Whisper, i18n, _, displayNameRegex */ // eslint-disable-next-line func-names (function() { @@ -31,7 +31,7 @@ const sanitiseNameInput = () => { const oldVal = this.$input.val(); - this.$input.val(oldVal.replace(/[^a-zA-Z0-9_]/g, '')); + this.$input.val(oldVal.replace(displayNameRegex, '')); }; this.$input[0].oninput = () => { diff --git a/js/views/standalone_registration_view.js b/js/views/standalone_registration_view.js index b621c204d..d757f0677 100644 --- a/js/views/standalone_registration_view.js +++ b/js/views/standalone_registration_view.js @@ -1,4 +1,5 @@ -/* global Whisper, $, getAccountManager, textsecure, i18n, passwordUtil, _, setTimeout */ +/* global Whisper, $, getAccountManager, textsecure, + i18n, passwordUtil, _, setTimeout, displayNameRegex */ /* eslint-disable more/no-then */ @@ -85,7 +86,7 @@ }, sanitiseNameInput() { const oldVal = this.$('#display-name').val(); - const newVal = oldVal.replace(/[^a-zA-Z0-9_]/g, ''); + const newVal = oldVal.replace(displayNameRegex, ''); this.$('#display-name').val(newVal); if (_.isEmpty(newVal)) { this.$('#save-button').attr('disabled', 'disabled'); @@ -154,7 +155,7 @@ await this.accountManager.registerSingleDevice( mnemonic, language, - this.$('#display-name').val() + this.trim(this.$('#display-name').val()) ); this.$el.trigger('openInbox'); } catch (e) { diff --git a/preload.js b/preload.js index 9df58dadd..d0d167143 100644 --- a/preload.js +++ b/preload.js @@ -24,6 +24,9 @@ if (config.appInstance) { window.Lodash = require('lodash'); +// Regex to match all characters which are *not* supported in display names +window.displayNameRegex = /[^\u0041-\u005A\u0061-\u007A\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC _0-9]*/g; + window.platform = process.platform; window.getDefaultPoWDifficulty = () => config.defaultPoWDifficulty; window.getTitle = () => title;