From 40b742c3ef1e44adbe9880e68431da9ebe5e6370 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sat, 23 Jun 2018 14:46:06 +1200 Subject: [PATCH 001/104] Increased version number to 10.4.0. --- manifest.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/manifest.json b/manifest.json index baec36a1a..ab6e42263 100755 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "minimum_chrome_version": "38", - "version": "10.3.0", + "version": "10.4.0", "author": "Betaflight Squad", "name": "Betaflight - Configurator", "short_name": "Betaflight", diff --git a/package.json b/package.json index 6c86c7093..418328de7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "betaflight-configurator", "description": "Crossplatform configuration tool for Betaflight flight control system.", - "version": "10.3.0", + "version": "10.4.0", "main": "main_nwjs.html", "bg-script": "js/eventPage.js", "default_locale": "en", From c93f2f13e4f1cf7f28a6941c19abd6eb779bbf32 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 24 Jun 2018 17:44:48 +1200 Subject: [PATCH 002/104] Added setting of RTC when connecting. --- src/js/msp/MSPCodes.js | 5 +++++ src/js/msp/MSPHelper.js | 13 +++++++++++++ src/js/serial_backend.js | 12 ++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/js/msp/MSPCodes.js b/src/js/msp/MSPCodes.js index 794cf0d98..8ea36f20a 100644 --- a/src/js/msp/MSPCodes.js +++ b/src/js/msp/MSPCodes.js @@ -150,6 +150,11 @@ var MSPCodes = { MSP_ACC_TRIM: 240, MSP_SERVO_MIX_RULES: 241, MSP_SET_SERVO_MIX_RULE: 242, // Not used + MSP_SET_4WAY_IF: 245, // Not used + MSP_SET_RTC: 246, + MSP_RTC: 247, // Not used + MSP_SET_BOARD_INFO: 248, // Not used + MSP_SET_SIGNATURE: 249, // Not used MSP_EEPROM_WRITE: 250, MSP_DEBUGMSG: 253, // Not used diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 6a7cd6922..5ffc75e21 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -1178,6 +1178,9 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_ARMING_DISABLE: console.log('Arming disable'); break; + case MSPCodes.MSP_SET_RTC: + console.log('Real time clock set'); + break; default: console.log('Unknown code detected: ' + code); } else { @@ -1577,6 +1580,16 @@ MspHelper.prototype.crunch = function(code) { // This will be ignored if `armingDisabled` is true buffer.push8(value); + break; + case MSPCodes.MSP_SET_RTC: + var now = new Date(); + buffer.push16(now.getUTCFullYear()); + buffer.push8(now.getUTCMonth() + 1); + buffer.push8(now.getUTCDate()); + buffer.push8(now.getUTCHours()); + buffer.push8(now.getUTCMinutes()); + buffer.push8(now.getUTCSeconds()); + break; default: return false; diff --git a/src/js/serial_backend.js b/src/js/serial_backend.js index 37e27375b..e811c7ee4 100755 --- a/src/js/serial_backend.js +++ b/src/js/serial_backend.js @@ -228,10 +228,10 @@ function onOpen(openInfo) { GUI.log(i18n.getMessage('craftNameReceived', [CONFIG.name])); CONFIG.armingDisabled = false; - mspHelper.setArmingEnabled(false, false, finishOpen); + mspHelper.setArmingEnabled(false, false, setRtc); }); } else { - finishOpen(); + setRtc(); } }); }); @@ -280,6 +280,14 @@ function onOpen(openInfo) { } } +function setRtc() { + if (semver.gte(CONFIG.apiVersion, "1.37.0")) { + MSP.send_message(MSPCodes.MSP_SET_RTC, mspHelper.crunch(MSPCodes.MSP_SET_RTC), false, finishOpen); + } else { + finishOpen(); + } +} + function finishOpen() { CONFIGURATOR.connectionValid = true; GUI.allowedTabs = GUI.defaultAllowedFCTabsWhenConnected.slice(); From bf117875eca175f0c093f1feddff08e1958d731b Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Tue, 26 Jun 2018 08:50:03 +0200 Subject: [PATCH 003/104] Remove unused and conflictive logo strings --- locales/ca/messages.json | 6 ------ locales/de/messages.json | 6 ------ locales/en/messages.json | 6 ------ locales/es/messages.json | 6 ------ locales/fr/messages.json | 6 ------ locales/it/messages.json | 6 ------ locales/ja/messages.json | 6 ------ locales/ko/messages.json | 6 ------ locales/lv/messages.json | 6 ------ locales/pt/messages.json | 6 ------ locales/zh_CN/messages.json | 6 ------ 11 files changed, 66 deletions(-) diff --git a/locales/ca/messages.json b/locales/ca/messages.json index 2d6f85279..247b0f4f2 100644 --- a/locales/ca/messages.json +++ b/locales/ca/messages.json @@ -2932,12 +2932,6 @@ "osdSetupCustomLogoInfoUploadHint": { "message": "Prem $t(osdSetupUploadFont.message)<\/b> per a desar la imatge personalitzada" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Mida de la imatge invàlida; s'esperava $1×$2 en comptes de $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "La imatge conté una paleta de colors invàlida (només verd, negre i blanc són permesos)" - }, "osdSetupUploadFont": { "message": "Pujar Font" }, diff --git a/locales/de/messages.json b/locales/de/messages.json index aca12f8a0..b909cf951 100644 --- a/locales/de/messages.json +++ b/locales/de/messages.json @@ -3022,12 +3022,6 @@ "osdSetupCustomLogoColorMapError": { "message": "Das Bild verwendet eine ungültige Farbpalette (nur grün, schwarz und weiß sind erlaubt)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Ungültige Bildgröße; Es wird $1 x $2 statt $3 x $4 erwartet" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "Das Bild verwendet eine Ungültige Farbpalette (nur grün, schwarz und weiß sind erlaubt)" - }, "osdSetupUploadFont": { "message": "Schriftart hochladen" }, diff --git a/locales/en/messages.json b/locales/en/messages.json index baa9c4069..d1a0d2e8f 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3119,12 +3119,6 @@ "osdSetupCustomLogoColorMapError": { "message": "The image contains an invalid color palette (only green, black and white are allowed)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Invalid image size; expected $1×$2 instead of $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "The image contains an invalid color palette (only green, black and white are allowed)" - }, "osdSetupUploadFont": { "message": "Upload Font" }, diff --git a/locales/es/messages.json b/locales/es/messages.json index 29492f031..894f175dd 100644 --- a/locales/es/messages.json +++ b/locales/es/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "La imagen contiene una paleta de colores no válida (sólo se permite verde, blanco y negro)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Tamaño de imagen no válido; se esperaba $1×$2 en vez de $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "La imagen contiene una paleta de colores no válida (sólo se permite verde, blanco y negro)" - }, "osdSetupUploadFont": { "message": "Cargar Fuente" }, diff --git a/locales/fr/messages.json b/locales/fr/messages.json index e935147ab..4fb84bfac 100644 --- a/locales/fr/messages.json +++ b/locales/fr/messages.json @@ -3025,12 +3025,6 @@ "osdSetupCustomLogoColorMapError": { "message": "La palette couleurs de l'image n'est pas valide (seuls le vert, le noir et le blanc sont autorisés)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Taille de l'image invalide; requise $1×$2 au lieu de $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "La palette couleurs de l'image n'est pas valide (seuls le vert, le noir et le blanc sont autorisés)" - }, "osdSetupUploadFont": { "message": "Charger le fichier de police" }, diff --git a/locales/it/messages.json b/locales/it/messages.json index 745daba18..b1cb62a9b 100644 --- a/locales/it/messages.json +++ b/locales/it/messages.json @@ -2908,12 +2908,6 @@ "osdSetupCustomLogoColorMapError": { "message": "L'immagine contiene una tavolozza colori non valida (sono ammessi solo verde, nero e bianco)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Dimensione immagine non valida; previsto $1×$2 invece di $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "L'immagine contiene una palette colori non valida (sono ammessi solo verde, nero e bianco)" - }, "osdSetupUploadFont": { "message": "Carica carattere" }, diff --git a/locales/ja/messages.json b/locales/ja/messages.json index 0edc1250b..cb2f9389c 100644 --- a/locales/ja/messages.json +++ b/locales/ja/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "画像に無効なカラーが含まれています\n (緑・黒・白のみ有効)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "画像サイズが無効; 既定サイズ $1×$2 無効サイズ $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "画像に無効なカラーパレットが含まれています \n(緑、黒、白のみが許可)" - }, "osdSetupUploadFont": { "message": "フォントアップロード" }, diff --git a/locales/ko/messages.json b/locales/ko/messages.json index 013b49009..6de6ff4a2 100644 --- a/locales/ko/messages.json +++ b/locales/ko/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "이미지가 유효하지 않은 색상표를 포함하고 있습니다 (오직 녹색, 검정 및 흰색만 허용됨)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "유효하지 않은 이미지 크기; $3×$4 대신 $1×$2 예상" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "이미지가 유효하지 않은 색상표를 포함하고 있습니다 (오직 녹색, 검정 및 흰색만 허용됨)" - }, "osdSetupUploadFont": { "message": "글꼴 업로드" }, diff --git a/locales/lv/messages.json b/locales/lv/messages.json index d6b258a28..166d37ba4 100644 --- a/locales/lv/messages.json +++ b/locales/lv/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "Šis attēls satur nederīgu krāsu paleti (tikai zaļa, melna un balta krāsa atļauta)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Nederīgs attēla izmērs; sagaidu $1×$2 šī vietā $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "Šis attēls satur nederīgu krāsu paleti (tikai zaļa, melna un balta krāsa atļauta)" - }, "osdSetupUploadFont": { "message": "Augšupielādēt fontu" }, diff --git a/locales/pt/messages.json b/locales/pt/messages.json index 0db9f31bc..817531c13 100644 --- a/locales/pt/messages.json +++ b/locales/pt/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "A imagem contém uma paleta de cores inválida (somente verde, preto e branco são permitidos)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "Tamanho da imagem inválida; era esperado $1x$2 ao invés de $3x$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "A imagem contém uma palheta de cores inválida (somente é permitido verde, preto e branco)" - }, "osdSetupUploadFont": { "message": "Carregar Fonte" }, diff --git a/locales/zh_CN/messages.json b/locales/zh_CN/messages.json index b2ded5c72..7286d298f 100644 --- a/locales/zh_CN/messages.json +++ b/locales/zh_CN/messages.json @@ -3028,12 +3028,6 @@ "osdSetupCustomLogoColorMapError": { "message": "图像包含无效的颜色 (仅允许绿色、黑色和白色)" }, - "osdSetupReplaceLogoImageSizeError": { - "message": "图像大小无效:应该是 $1×$2 而不是 $3×$4" - }, - "osdSetupReplaceLogoImageColorsError": { - "message": "图像包含无效调色板 (仅允许绿色、黑色和白色)" - }, "osdSetupUploadFont": { "message": "更新字体" }, From 26442d0a7818e84c624473da31abc870c328f257 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Tue, 26 Jun 2018 09:09:53 +0200 Subject: [PATCH 004/104] Fix lpf zero --- src/js/msp/MSPHelper.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 6a7cd6922..65ba1407f 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -843,7 +843,7 @@ MspHelper.prototype.process_data = function(dataHandler) { if (semver.gte(CONFIG.apiVersion, "1.39.0")) { FILTER_CONFIG.gyro_hardware_lpf = data.readU8(); FILTER_CONFIG.gyro_32khz_hardware_lpf = data.readU8(); - FILTER_CONFIG.gyro_soft_lpf_hz = data.readU16(); + FILTER_CONFIG.gyro_lowpass_hz = data.readU16(); FILTER_CONFIG.gyro_lowpass2_hz = data.readU16(); FILTER_CONFIG.gyro_lowpass_type = data.readU8(); FILTER_CONFIG.gyro_lowpass2_type = data.readU8(); @@ -1472,7 +1472,7 @@ MspHelper.prototype.crunch = function(code) { } break; case MSPCodes.MSP_SET_FILTER_CONFIG: - buffer.push8(FILTER_CONFIG.gyro_soft_lpf_hz) + buffer.push8(FILTER_CONFIG.gyro_lowpass_hz) .push16(FILTER_CONFIG.dterm_lowpass_hz) .push16(FILTER_CONFIG.yaw_lowpass_hz); if (semver.gte(CONFIG.apiVersion, "1.20.0")) { From 9bdedd0c2c9a746c018837ad0f62cb97afb43aef Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Thu, 28 Jun 2018 08:50:23 +0200 Subject: [PATCH 005/104] Fix OSD non positionable elements --- src/js/tabs/osd.js | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 24b29619f..e8805f735 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -381,7 +381,13 @@ OSD.constants = { CROSSHAIRS: { name: 'CROSSHAIRS', desc: 'osdDescElementCrosshairs', - default_position: 193, + default_position: function() { + var position = 193; + if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] != 'NTSC') { + position += FONT.constants.SIZES.LINE; + } + return position; + }, draw_order: 40, positionable: function() { return semver.gte(CONFIG.apiVersion, "1.39.0") ? true : false; @@ -391,7 +397,13 @@ OSD.constants = { ARTIFICIAL_HORIZON: { name: 'ARTIFICIAL_HORIZON', desc: 'osdDescElementArtificialHorizon', - default_position: 194, + default_position: function() { + var position = 74; + if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] != 'NTSC') { + position += FONT.constants.SIZES.LINE; + } + return position; + }, draw_order: 10, positionable: function() { return semver.gte(CONFIG.apiVersion, "1.39.0") ? true : false; @@ -422,7 +434,13 @@ OSD.constants = { HORIZON_SIDEBARS: { name: 'HORIZON_SIDEBARS', desc: 'osdDescElementHorizonSidebars', - default_position: 194, + default_position: function() { + var position = 194; + if (OSD.constants.VIDEO_TYPES[OSD.data.video_system] != 'NTSC') { + position += FONT.constants.SIZES.LINE; + } + return position; + }, draw_order: 50, positionable: function() { return semver.gte(CONFIG.apiVersion, "1.39.0") ? true : false; @@ -1119,14 +1137,20 @@ OSD.msp = { unpack: { position: function(bits, c) { var display_item = {}; + + var positionable = typeof(c.positionable) === 'function'? c.positionable() : c.positionable; + var default_position = typeof(c.default_position) === 'function'? c.default_position() : c.default_position; + + display_item.positionable = positionable; if (semver.gte(CONFIG.apiVersion, "1.21.0")) { // size * y + x - display_item.position = FONT.constants.SIZES.LINE * ((bits >> 5) & 0x001F) + (bits & 0x001F); + display_item.position = positionable ? FONT.constants.SIZES.LINE * ((bits >> 5) & 0x001F) + (bits & 0x001F) : default_position; display_item.isVisible = (bits & OSD.constants.VISIBLE) != 0; } else { - display_item.position = (bits === -1) ? c.default_position : bits; + display_item.position = (bits === -1) ? default_position : bits; display_item.isVisible = bits !== -1; } + return display_item; }, timer: function(bits, c) { @@ -1264,7 +1288,6 @@ OSD.msp = { desc: c.desc, index: j, draw_order: c.draw_order, - positionable: c.positionable, preview: suffix ? c.preview + suffix : c.preview }, this.helpers.unpack.position(v, c))); } @@ -1323,9 +1346,6 @@ OSD.msp = { if (typeof(item.preview) === 'function') { item.preview = item.preview(d); } - if (typeof(item.positionable) === 'function') { - item.positionable = item.positionable(d); - } } OSD.updateDisplaySize(); From 684c118f23ab70936b0b8b8ca4757bf00c62a817 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Thu, 28 Jun 2018 11:54:57 +0200 Subject: [PATCH 006/104] Add OSD anti gravity element --- locales/en/messages.json | 3 +++ src/js/tabs/osd.js | 35 ++++++++++++++++++++++++----------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index d1a0d2e8f..558871dfb 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3292,6 +3292,9 @@ "osdDescElementCoreTemperature": { "message": "Temperature of the STM32 MCU core" }, + "osdDescAntiGravity": { + "message": "Enables an indicator when the anti gravity is active" + }, "osdDescStatMaxSpeed": { "message": "Maximum recorded speed" diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 24b29619f..ed98a66ee 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -517,7 +517,7 @@ OSD.constants = { name: 'GPS_SPEED', desc: 'osdDescElementGPSSpeed', default_position: -1, - draw_order: 330, + draw_order: 430, positionable: true, preview: function(osd_data) { return ' 40' + (osd_data.unit_mode === 0 ? 'M' : 'K'); @@ -527,7 +527,7 @@ OSD.constants = { name: 'GPS_SATS', desc: 'osdDescElementGPSSats', default_position: -1, - draw_order: 320, + draw_order: 420, positionable: true, preview: FONT.symbol(SYM.GPS_SAT_L) + FONT.symbol(SYM.GPS_SAT_R) + '14' }, @@ -535,7 +535,7 @@ OSD.constants = { name: 'GPS_LON', desc: 'osdDescElementGPSLon', default_position: -1, - draw_order: 350, + draw_order: 450, positionable: true, preview: FONT.symbol(SYM.ARROW_EAST) + '-000.0000000' }, @@ -543,7 +543,7 @@ OSD.constants = { name: 'GPS_LAT', desc: 'osdDescElementGPSLat', default_position: -1, - draw_order: 340, + draw_order: 440, positionable: true, preview: FONT.symbol(SYM.ARROW_NORTH) + '-00.0000000 ' }, @@ -647,7 +647,7 @@ OSD.constants = { name: 'HOME_DIRECTION', desc: 'osdDescElementHomeDirection', default_position: -1, - draw_order: 370, + draw_order: 470, positionable: true, preview: FONT.symbol(SYM.ARROW_SOUTH + 2) }, @@ -655,7 +655,7 @@ OSD.constants = { name: 'HOME_DISTANCE', desc: 'osdDescElementHomeDistance', default_position: -1, - draw_order: 360, + draw_order: 460, positionable: true, preview: function(osd_data) { return '43' + FONT.symbol(osd_data.unit_mode === 0 ? SYM.FEET : SYM.METRE) + (semver.gte(CONFIG.apiVersion, "1.37.0")?' ':''); @@ -701,7 +701,7 @@ OSD.constants = { name: 'ESC_TEMPERATURE', desc: 'osdDescElementEscTemperature', default_position: -1, - draw_order: 380, + draw_order: 480, positionable: true, preview: FONT.symbol(SYM.TEMP_C) + '45' }, @@ -709,7 +709,7 @@ OSD.constants = { name: 'ESC_RPM', desc: 'osdDescElementEscRpm', default_position: -1, - draw_order: 390, + draw_order: 490, positionable: true, preview: '226000' }, @@ -725,7 +725,7 @@ OSD.constants = { name: 'RTC_DATE_TIME', desc: 'osdDescElementRtcDateTime', default_position: -1, - draw_order: 400, + draw_order: 500, positionable: true, preview: '2017-11-11 16:20:00' }, @@ -733,7 +733,7 @@ OSD.constants = { name: 'ADJUSTMENT_RANGE', desc: 'osdDescElementAdjustmentRange', default_position: -1, - draw_order: 410, + draw_order: 510, positionable: true, preview: 'PITCH/ROLL P: 42' }, @@ -761,11 +761,19 @@ OSD.constants = { name: 'CORE_TEMPERATURE', desc: 'osdDescElementCoreTemperature', default_position: -1, - draw_order: 420, + draw_order: 520, positionable: true, preview: function(osd_data) { return OSD.generateTemperaturePreview(osd_data, 33); } + }, + ANTI_GRAVITY: { + name: 'ANTI_GRAVITY', + desc: 'osdDescAntiGravity', + default_position: -1, + draw_order: 320, + positionable: true, + preview: 'AG' } }, UNKNOWN_DISPLAY_FIELD: { @@ -976,6 +984,11 @@ OSD.chooseFields = function () { F.ADJUSTMENT_RANGE, F.CORE_TEMPERATURE ]); + if (semver.gte(CONFIG.apiVersion, "1.39.0")) { + OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ + F.ANTI_GRAVITY + ]); + } } } } From 263ea5d3648baadfddf886b2e0ad2debac695657 Mon Sep 17 00:00:00 2001 From: mikeller Date: Fri, 29 Jun 2018 00:58:29 +1200 Subject: [PATCH 007/104] Fixed display of GPS altitude. --- src/js/tabs/gps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/tabs/gps.js b/src/js/tabs/gps.js index 7fa3d97ac..6566c95cd 100644 --- a/src/js/tabs/gps.js +++ b/src/js/tabs/gps.js @@ -48,7 +48,7 @@ TABS.gps.initialize = function (callback) { var url = 'https://maps.google.com/?q=' + lat + ',' + lon; $('.GPS_info td.fix').html((GPS_DATA.fix) ? i18n.getMessage('gpsFixTrue') : i18n.getMessage('gpsFixFalse')); - $('.GPS_info td.alt').text((GPS_DATA.alt / 10) + ' m'); + $('.GPS_info td.alt').text(GPS_DATA.alt + ' m'); $('.GPS_info td.lat a').prop('href', url).text(lat.toFixed(4) + ' deg'); $('.GPS_info td.lon a').prop('href', url).text(lon.toFixed(4) + ' deg'); $('.GPS_info td.speed').text(GPS_DATA.speed + ' cm/s'); From ec75c22669428f539a60c95a72ddc719f34fd857 Mon Sep 17 00:00:00 2001 From: mikeller Date: Fri, 29 Jun 2018 01:18:27 +1200 Subject: [PATCH 008/104] Fix from review. --- src/js/tabs/gps.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/js/tabs/gps.js b/src/js/tabs/gps.js index 6566c95cd..1dc095e75 100644 --- a/src/js/tabs/gps.js +++ b/src/js/tabs/gps.js @@ -46,9 +46,13 @@ TABS.gps.initialize = function (callback) { var lat = GPS_DATA.lat / 10000000; var lon = GPS_DATA.lon / 10000000; var url = 'https://maps.google.com/?q=' + lat + ',' + lon; + var alt = GPS_DATA.alt; + if (semver.lt(CONFIG.apiVersion, "1.39.0")) { + alt = alt / 10; + } $('.GPS_info td.fix').html((GPS_DATA.fix) ? i18n.getMessage('gpsFixTrue') : i18n.getMessage('gpsFixFalse')); - $('.GPS_info td.alt').text(GPS_DATA.alt + ' m'); + $('.GPS_info td.alt').text(alt + ' m'); $('.GPS_info td.lat a').prop('href', url).text(lat.toFixed(4) + ' deg'); $('.GPS_info td.lon a').prop('href', url).text(lon.toFixed(4) + ' deg'); $('.GPS_info td.speed').text(GPS_DATA.speed + ' cm/s'); From f7b8d60812a381b9ba00dcc8f95e9d29551a5169 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 1 Jul 2018 23:10:43 +1200 Subject: [PATCH 009/104] Added Facebook link, cleaned up landing page. --- locales/en/messages.json | 5 ++++- src/css/tabs/landing.css | 23 ++++++++++++++++++++--- src/images/flogo_RGB_HEX-1024.svg | 1 + src/tabs/landing.html | 6 ++++++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/images/flogo_RGB_HEX-1024.svg diff --git a/locales/en/messages.json b/locales/en/messages.json index 558871dfb..a70711bf5 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -496,7 +496,7 @@ "message": "Hardware" }, "defaultWelcomeText": { - "message": "The application supports all hardware that can run Betaflight. Check flash tab for full list of hardware.

Download Betaflight Blackbox

The firmware source code can be downloaded from here
The newest binary firmware image is available here

Latest CP210x Drivers can be downloaded from here
Latest STM USB VCP Drivers can be downloaded from here
Latest Zadig for Windows USB driver installation can be downloaded from here
" + "message": "The application supports all hardware that can run Betaflight. Check flash tab for full list of hardware.

Download Betaflight Blackbox Log Viewer

The firmware source code can be downloaded from here

Latest CP210x Drivers can be downloaded from here
Latest STM USB VCP Drivers can be downloaded from here
Latest Zadig for Windows USB driver installation can be downloaded from here
" }, "defaultContributingHead": { "message": "Contributing" @@ -504,6 +504,9 @@ "defaultContributingText": { "message": "If you would like to help make Betaflight even better you can help in many ways, including:
" }, + "defaultFacebookText": { + "message": "We also have a Facebook Group.
Join us to get a place to talk about Betaflight, ask configuration questions, or just hang out with fellow pilots." + }, "defaultChangelogAction": { "message": "Changelog" }, diff --git a/src/css/tabs/landing.css b/src/css/tabs/landing.css index 59cd8c19f..2fcef348b 100755 --- a/src/css/tabs/landing.css +++ b/src/css/tabs/landing.css @@ -91,7 +91,7 @@ color: #fff; } -.text1, .text2, .text3 { +.text1, .text2, .text3, .text4 { margin-top: 15px; margin-bottom: 15px; font-weight: normal; @@ -141,7 +141,6 @@ .tab-landing .content_mid .text2 li { padding: 5px 0; - border-top: 1px dotted silver; } .tab-landing .content_mid .text3 { @@ -164,6 +163,24 @@ text-align: center; } +.tab-landing .content_mid_bottom { + padding: 15px; + padding-top: 0px; + padding-bottom: 0px; +} + +.tab-landing .content_mid_bottom .logo { + float: left; + width: 40px; +} + +.tab-landing .content_mid_bottom .text4 { + margin-top: 0px; + margin-left: 5px; + display: block; + float: left; +} + /* changelog block */ #changelog { width: 250px; @@ -237,4 +254,4 @@ #changelog .log p { margin-bottom: 20px; -} \ No newline at end of file +} diff --git a/src/images/flogo_RGB_HEX-1024.svg b/src/images/flogo_RGB_HEX-1024.svg new file mode 100644 index 000000000..24643f3ae --- /dev/null +++ b/src/images/flogo_RGB_HEX-1024.svg @@ -0,0 +1 @@ +flogo_RGB_HEX-1024 \ No newline at end of file diff --git a/src/tabs/landing.html b/src/tabs/landing.html index 13ceaa8a7..1531f45fa 100644 --- a/src/tabs/landing.html +++ b/src/tabs/landing.html @@ -31,6 +31,12 @@

+
+ +
+
From 920eafffcdb5e7e45bd651ad2587835d4499bb97 Mon Sep 17 00:00:00 2001 From: leocb Date: Mon, 2 Jul 2018 15:11:12 -0300 Subject: [PATCH 010/104] Added G-force element to OSD Config --- locales/en/messages.json | 4 +++- src/js/tabs/osd.js | 29 +++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 558871dfb..9cb2dc937 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3295,7 +3295,9 @@ "osdDescAntiGravity": { "message": "Enables an indicator when the anti gravity is active" }, - + "osdDescGForce": { + "message": "Shows how much G-Force the craft is experiencing" + }, "osdDescStatMaxSpeed": { "message": "Maximum recorded speed" }, diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index ed98a66ee..d9bbaa130 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -774,6 +774,14 @@ OSD.constants = { draw_order: 320, positionable: true, preview: 'AG' + }, + G_FORCE: { + name: 'G_FORCE', + desc: 'osdDescGForce', + default_position: -1, + draw_order: 11, + positionable: true, + preview: '1.0G' } }, UNKNOWN_DISPLAY_FIELD: { @@ -978,17 +986,22 @@ OSD.chooseFields = function () { F.ESC_RPM ]); if (semver.gte(CONFIG.apiVersion, "1.37.0")) { + OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ + F.REMAINING_TIME_ESTIMATE, + F.RTC_DATE_TIME, + F.ADJUSTMENT_RANGE, + F.CORE_TEMPERATURE + ]); + if (semver.gte(CONFIG.apiVersion, "1.39.0")) { OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ - F.REMAINING_TIME_ESTIMATE, - F.RTC_DATE_TIME, - F.ADJUSTMENT_RANGE, - F.CORE_TEMPERATURE + F.ANTI_GRAVITY ]); - if (semver.gte(CONFIG.apiVersion, "1.39.0")) { - OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ - F.ANTI_GRAVITY - ]); + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ + F.G_FORCE + ]); } + } } } } From 7590c47636658a466cd3d4714ac02d5d6979b1d3 Mon Sep 17 00:00:00 2001 From: leocb Date: Mon, 2 Jul 2018 15:26:45 -0300 Subject: [PATCH 011/104] Changed g_force draw_order to 15 --- src/js/tabs/osd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index d9bbaa130..d7c2f7550 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -779,7 +779,7 @@ OSD.constants = { name: 'G_FORCE', desc: 'osdDescGForce', default_position: -1, - draw_order: 11, + draw_order: 15, positionable: true, preview: '1.0G' } From 8322e86b578715497b528205349b2a63593b484b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Tue, 3 Jul 2018 00:38:56 +0200 Subject: [PATCH 012/104] improve the way boot logo source image errors are handled to address issue #1077 --- locales/en/messages.json | 2 +- src/css/tabs/osd.css | 3 ++- src/js/LogoManager.js | 10 ++++++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 57797a4eb..ef0fa0521 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3120,7 +3120,7 @@ "message": "Invalid image size: {{width}}×{{height}} (expected $t(logoWidthPx)×$t(logoHeightPx))" }, "osdSetupCustomLogoColorMapError": { - "message": "The image contains an invalid color palette (only green, black and white are allowed)" + "message": "The image contains an invalid pixel: rgb({{valueR}}, {{valueG}}, {{valueB}}) at coordinates {{posX}}×{{posY}}" }, "osdSetupUploadFont": { "message": "Upload Font" diff --git a/src/css/tabs/osd.css b/src/css/tabs/osd.css index 0ee07632e..d45af866e 100644 --- a/src/css/tabs/osd.css +++ b/src/css/tabs/osd.css @@ -336,7 +336,7 @@ #font-logo-preview-container { background:rgba(0, 255, 0, 0.4); margin-bottom: 10px; - width: 50%; + width: 45%; float: left; } @@ -347,6 +347,7 @@ } #font-logo-info { + width: 45%; margin-left: 18px; font-size: 125%; line-height: 150%; diff --git a/src/js/LogoManager.js b/src/js/LogoManager.js index a77b4ce92..d80ecb640 100644 --- a/src/js/LogoManager.js +++ b/src/js/LogoManager.js @@ -80,7 +80,13 @@ LogoManager.init = function (font, logoStartIndex) { var rgbPixel = ctx.getImageData(x, y, 1, 1).data.slice(0, 3), colorKey = rgbPixel.join("-"); if (!this.constants.MCM_COLORMAP[colorKey]) { - GUI.log(i18n.getMessage("osdSetupCustomLogoColorMapError")); + GUI.log(i18n.getMessage("osdSetupCustomLogoColorMapError", { + valueR: rgbPixel[0], + valueG: rgbPixel[1], + valueB: rgbPixel[2], + posX: x, + posY: y, + })); return false; } } @@ -162,7 +168,7 @@ LogoManager.openImage = function () { this.showConstraintSatisfied(constraint); } else { this.showConstraintNotSatisfied(constraint); - reject(); + reject("Boot logo image constraint violation"); return; } } From 1a6410c153bf5f99e62ba062766fd9b5978ca4fa Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 8 Jul 2018 16:38:31 +1200 Subject: [PATCH 013/104] Updated readme to remove outdated information. --- README.md | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/README.md b/README.md index b8568d0bf..d1b28eb6e 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Please note - the application will automatically update itself when new versions ### Alternative way, Chrome app: 1. Clone the repo to any local directory or download it as zip. -2. Extract to a folder and not the folder. +2. If downloaded as a zip, extract it into a new directory. 3. Start Google Chrome. 4. Click the 3-dots on the far right of the URL bar. 5. Select "More Tools" @@ -44,14 +44,8 @@ Please note - the application will automatically update itself when new versions 8. Click on load unpacked extension. 9. Point it to the folder you extracted the zip to. -## How to use - -You can find the Betaflight Configurator icon in your application tab "Apps" - ## Native app build via NW.js -Linux build is disabled currently because of unmet dependecies with some distros, it can be enabled in the `gulpfile.js`. - ### Development 1. Install node.js From ef00402976efa95f9f375472e0cc39072d372ee9 Mon Sep 17 00:00:00 2001 From: Sean M Date: Mon, 25 Jun 2018 21:37:03 -0400 Subject: [PATCH 014/104] Fix configuration load/save for board and sensor alignment, craft name, DShot Beacon, ESC/Motor features, beeper, mixer, accelerometer, barometer and magnetometer --- src/js/backup_restore.js | 35 ++++++++++++++++++++++++++++------- src/js/msp/MSPHelper.js | 5 +++-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/js/backup_restore.js b/src/js/backup_restore.js index bffcf65e2..59d2f56e5 100644 --- a/src/js/backup_restore.js +++ b/src/js/backup_restore.js @@ -141,6 +141,11 @@ function configuration_backup(callback) { configuration.SERIAL_CONFIG = jQuery.extend(true, {}, SERIAL_CONFIG); configuration.LED_STRIP = jQuery.extend(true, [], LED_STRIP); configuration.LED_COLORS = jQuery.extend(true, [], LED_COLORS); + configuration.BOARD_ALIGNMENT_CONFIG = jQuery.extend(true, {}, BOARD_ALIGNMENT_CONFIG); + configuration.CRAFT_NAME = CONFIG.name; + configuration.MIXER_CONFIG = jQuery.extend(true, {}, MIXER_CONFIG); + configuration.SENSOR_CONFIG = jQuery.extend(true, {}, SENSOR_CONFIG); + configuration.PID_ADVANCED_CONFIG = jQuery.extend(true, {}, PID_ADVANCED_CONFIG); if (semver.gte(CONFIG.apiVersion, "1.19.0")) { configuration.LED_MODE_COLORS = jQuery.extend(true, [], LED_MODE_COLORS); @@ -165,6 +170,9 @@ function configuration_backup(callback) { configuration.GPS_CONFIG = jQuery.extend(true, {}, GPS_CONFIG); configuration.COMPASS_CONFIG = jQuery.extend(true, {}, COMPASS_CONFIG); } + if (semver.gte(CONFIG.apiVersion, "1.36.0")) { + configuration.BEEPER_CONFIG = jQuery.extend(true, {}, BEEPER_CONFIG); + } save(); } @@ -303,26 +311,21 @@ function configuration_restore(callback) { // validate - if (typeof configuration.generatedBy !== 'undefined' && compareVersions(configuration.generatedBy, CONFIGURATOR.backupFileMinVersionAccepted)) { - + if (typeof configuration.generatedBy !== 'undefined' && compareVersions(configuration.generatedBy, CONFIGURATOR.backupFileMinVersionAccepted)) { if (!compareVersions(configuration.generatedBy, "1.14.0") && !migrate(configuration)) { GUI.log(i18n.getMessage('backupFileUnmigratable')); return; } - - if (configuration.FEATURE_CONFIG.features._featureMask) { + if (typeof configuration.FEATURE_CONFIG != 'undefined' && configuration.FEATURE_CONFIG.features._featureMask) { var features = new Features(CONFIG); features.setMask(configuration.FEATURE_CONFIG.features._featureMask); configuration.FEATURE_CONFIG.features = features; } configuration_upload(configuration, callback); - } else { GUI.log(i18n.getMessage('backupFileIncompatible')); } - - } }; @@ -763,6 +766,13 @@ function configuration_restore(callback) { ]; function update_unique_data_list() { + uniqueData.push(MSPCodes.MSP_SET_NAME); + uniqueData.push(MSPCodes.MSP_SET_SENSOR_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_MIXER_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_BEEPER_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_BOARD_ALIGNMENT_CONFIG); + uniqueData.push(MSPCodes.MSP_SET_ADVANCED_CONFIG); + if (semver.gte(CONFIG.apiVersion, "1.8.0")) { uniqueData.push(MSPCodes.MSP_SET_LOOP_TIME); uniqueData.push(MSPCodes.MSP_SET_ARMING_CONFIG); @@ -803,6 +813,17 @@ function configuration_restore(callback) { GPS_CONFIG = configuration.GPS_CONFIG; COMPASS_CONFIG = configuration.COMPASS_CONFIG; RSSI_CONFIG = configuration.RSSI_CONFIG; + BOARD_ALIGNMENT_CONFIG = configuration.BOARD_ALIGNMENT_CONFIG; + CONFIG.name = configuration.CRAFT_NAME; + MIXER_CONFIG = configuration.MIXER_CONFIG; + SENSOR_CONFIG = configuration.SENSOR_CONFIG; + PID_ADVANCED_CONFIG = configuration.PID_ADVANCED_CONFIG; + + BEEPER_CONFIG.beepers = new Beepers(CONFIG); + BEEPER_CONFIG.beepers.setMask(configuration.BEEPER_CONFIG.beepers._beeperMask); + BEEPER_CONFIG.dshotBeaconTone = configuration.BEEPER_CONFIG.dshotBeaconTone; + BEEPER_CONFIG.dshotBeaconConditions = new Beepers(CONFIG, [ "RX_LOST", "RX_SET" ]); + BEEPER_CONFIG.dshotBeaconConditions.setMask(configuration.BEEPER_CONFIG.dshotBeaconConditions._beeperMask); } function send_unique_data_item() { diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index b82c5c76a..4ebe8498f 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -1109,7 +1109,9 @@ MspHelper.prototype.process_data = function(dataHandler) { case MSPCodes.MSP_SET_ADJUSTMENT_RANGE: console.log('Adjustment range saved'); break; - + case MSPCodes.MSP_SET_BOARD_ALIGNMENT_CONFIG: + console.log('Board alignment saved'); + break; case MSPCodes.MSP_PID_CONTROLLER: PID.controller = data.readU8(); break; @@ -1875,7 +1877,6 @@ MspHelper.prototype.sendCurrentConfig = function(onCompleteCallback) { } - MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) { var nextFunction = send_next_led_strip_config; From 70c839eb3a3f869672af15992e883774d5497a00 Mon Sep 17 00:00:00 2001 From: Sean Moriarty Date: Thu, 28 Jun 2018 13:36:54 -0700 Subject: [PATCH 015/104] Check for valid PID_ADVANCED values --- src/js/backup_restore.js | 62 ++++++++++++++++++++++++++++++++++-- src/js/serial_backend.js | 2 ++ src/js/tabs/configuration.js | 1 + 3 files changed, 62 insertions(+), 3 deletions(-) diff --git a/src/js/backup_restore.js b/src/js/backup_restore.js index 59d2f56e5..b76ed9555 100644 --- a/src/js/backup_restore.js +++ b/src/js/backup_restore.js @@ -177,9 +177,65 @@ function configuration_backup(callback) { save(); } } + + if (GUI.configuration_loaded === true) { + return fetch_unique_data_item(); + } + var promises = [ getAdvancedConfig(), getSensorConfig(), getCraftName(), getBoardAlignmentConfig(), getMixerConfig(), getBeeperConfig() ]; + Promise.all(promises). + then(function () { + fetch_unique_data_item(); + }); + - // start fetching - fetch_unique_data_item(); + } + + function getAdvancedConfig() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, function() { + resolve(); + }); + }); + } + + function getSensorConfig() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_SENSOR_CONFIG, false, false, function() { + resolve(); + }); + }); + } + + function getCraftName() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_NAME, false, false, function() { + resolve(); + }); + }); + } + + function getBoardAlignmentConfig() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG, false, false, function() { + resolve(); + }); + }); + } + + function getMixerConfig() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, function() { + resolve(); + }); + }); + } + + function getBeeperConfig() { + return new Promise(function (resolve, reject) { + MSP.send_message(MSPCodes.MSP_BEEPER_CONFIG, false, false, function() { + resolve(); + }); + }); } function save() { @@ -316,7 +372,7 @@ function configuration_restore(callback) { GUI.log(i18n.getMessage('backupFileUnmigratable')); return; } - if (typeof configuration.FEATURE_CONFIG != 'undefined' && configuration.FEATURE_CONFIG.features._featureMask) { + if (configuration.FEATURE_CONFIG.features._featureMask) { var features = new Features(CONFIG); features.setMask(configuration.FEATURE_CONFIG.features._featureMask); configuration.FEATURE_CONFIG.features = features; diff --git a/src/js/serial_backend.js b/src/js/serial_backend.js index e811c7ee4..30128eb92 100755 --- a/src/js/serial_backend.js +++ b/src/js/serial_backend.js @@ -43,6 +43,8 @@ function initializeSerialBackend() { thisElement.data("clicks", !clicks); }; + GUI.configuration_loaded = false; + var selected_baud = parseInt($('div#port-picker #baud').val()); var selected_port = $('div#port-picker #port option:selected').data().isManual ? $('#port-override').val() : diff --git a/src/js/tabs/configuration.js b/src/js/tabs/configuration.js index 6ca6cc231..7cc86354f 100644 --- a/src/js/tabs/configuration.js +++ b/src/js/tabs/configuration.js @@ -10,6 +10,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) { if (GUI.active_tab != 'configuration') { GUI.active_tab = 'configuration'; + GUI.configuration_loaded = true; } if (semver.lt(CONFIG.apiVersion, "1.36.0")) { From 6443401e32c7125248835420263686f5fd71b61c Mon Sep 17 00:00:00 2001 From: Sean M Date: Mon, 9 Jul 2018 10:56:00 -0400 Subject: [PATCH 016/104] Remove async on promises --- src/js/backup_restore.js | 65 ++++++++-------------------------------- 1 file changed, 12 insertions(+), 53 deletions(-) diff --git a/src/js/backup_restore.js b/src/js/backup_restore.js index b76ed9555..32b973ca2 100644 --- a/src/js/backup_restore.js +++ b/src/js/backup_restore.js @@ -181,60 +181,19 @@ function configuration_backup(callback) { if (GUI.configuration_loaded === true) { return fetch_unique_data_item(); } - var promises = [ getAdvancedConfig(), getSensorConfig(), getCraftName(), getBoardAlignmentConfig(), getMixerConfig(), getBeeperConfig() ]; - Promise.all(promises). - then(function () { - fetch_unique_data_item(); - }); - - - } - - function getAdvancedConfig() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_ADVANCED_CONFIG, false, false, function() { - resolve(); - }); - }); - } - - function getSensorConfig() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_SENSOR_CONFIG, false, false, function() { - resolve(); - }); - }); - } - - function getCraftName() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_NAME, false, false, function() { - resolve(); - }); - }); - } - - function getBoardAlignmentConfig() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG, false, false, function() { - resolve(); - }); - }); - } - function getMixerConfig() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, function() { - resolve(); - }); - }); - } - - function getBeeperConfig() { - return new Promise(function (resolve, reject) { - MSP.send_message(MSPCodes.MSP_BEEPER_CONFIG, false, false, function() { - resolve(); - }); + MSP.promise(MSPCodes.MSP_ADVANCED_CONFIG).then(function() { + return MSP.promise(MSPCodes.MSP_SENSOR_CONFIG); + }).then(function() { + return MSP.promise(MSPCodes.MSP_NAME); + }).then(function() { + return MSP.promise(MSPCodes.MSP_BOARD_ALIGNMENT_CONFIG); + }).then(function() { + return MSP.promise(MSPCodes.MSP_MIXER_CONFIG); + }).then(function() { + return MSP.promise(MSPCodes.MSP_BEEPER_CONFIG); + }).then(function() { + return fetch_unique_data_item(); }); } From b9358083d95b31bf7ef57dce91875e3c76607749 Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 15 Jul 2018 23:39:18 +1200 Subject: [PATCH 017/104] Added buttons for reboot into boot loader and MSC modes. --- locales/en/messages.json | 23 ++++++++++++++++++++++- src/js/main.js | 14 +++++++++++++- src/js/msp/MSPHelper.js | 23 ++++++++++++++++++++++- src/js/tabs/setup.js | 24 +++++++++++++++++++++++- src/main.html | 10 ++++++++++ src/tabs/setup.html | 12 ++++++++++++ 6 files changed, 102 insertions(+), 4 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index ef0fa0521..acf7a1a83 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -9,12 +9,21 @@ "error": { "message": "Error: {{errorMessage}}" }, + "errorTitle": { + "message": "Error" + }, "warningTitle": { "message": "Warning" }, "noticeTitle": { "message": "Notice" }, + "operationNotSupported": { + "message": "This operation is not supported by your hardware." + }, + "storageDeviceNotReady": { + "message": "The storage device is not ready. In the case of a microSD card, make sure it is properly recognised by your flight controller." + }, "options_title": { "message": "Application Options" }, @@ -598,8 +607,20 @@ "initialSetupButtonRestore": { "message": "Restore" }, + "initialSetupButtonRebootBootloader": { + "message": "Activate Boot Loader / DFU" + }, + "initialSetupButtonRebootMsc": { + "message": "Activate Mass Storage Device Mode" + }, "initialSetupBackupRestoreText": { - "message": "Backup your configuration in case of an accident, CLI settings are not included - See 'dump' cli command" + "message": "Backup your configuration in case of an accident, CLI settings are not included - use the command 'diff all' in CLI for this." + }, + "initialSetupRebootBootloaderText": { + "message": "Reboot into boot loader / DFU mode." + }, + "initialSetupRebootMscText": { + "message": "Reboot into mass storage device (MSC) mode. Once activated, the onboard flash or SD card on your flight controller will be recognised as a storage device by your computer, and allow you to download your log files. Eject and power cycel your flight controller to leave mass storage device mode." }, "initialSetupBackupSuccess": { "message": "Backup saved successfully" diff --git a/src/js/main.js b/src/js/main.js index 326921c2d..9ebe303af 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -642,4 +642,16 @@ function openNewWindowsInExternalBrowser() { } catch (ex) { console.log("require does not exist, maybe inside chrome"); } -} \ No newline at end of file +} + +function showErrorDialog(message) { + var dialog = $('.dialogError')[0]; + + $('.dialogError-content').html(message); + + $('.dialogError-closebtn').click(function() { + dialog.close(); + }); + + dialog.showModal(); +} diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index b82c5c76a..ba13a314f 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -27,6 +27,12 @@ function MspHelper () { 'RUNCAM_DEVICE_CONTROL': 14, // support communitate with RunCam Device 'LIDAR_TF': 15 }; + + self.REBOOT_TYPES = { + FIRMWARE: 0, + BOOTLOADER: 1, + MSC: 2 + }; } MspHelper.prototype.reorderPwmProtocols = function (protocol) { @@ -617,6 +623,17 @@ MspHelper.prototype.process_data = function(dataHandler) { break; case MSPCodes.MSP_SET_REBOOT: + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + var rebootType = data.read8(); + if (rebootType === self.REBOOT_TYPES.MSC) { + if (data.read8() === 0) { + console.log('Storage device not ready.'); + + showErrorDialog(i18n.getMessage('storageDeviceNotReady')); + break; + } + } + } console.log('Reboot request accepted'); break; @@ -1185,6 +1202,11 @@ MspHelper.prototype.process_data = function(dataHandler) { console.log('Unknown code detected: ' + code); } else { console.log('FC reports unsupported message error: ' + code); + + switch (code) { + case MSPCodes.MSP_SET_REBOOT: + showErrorDialog(i18n.getMessage('operationNotSupported')); + } } } // trigger callbacks, cleanup/remove callback after trigger @@ -1207,7 +1229,6 @@ MspHelper.prototype.process_data = function(dataHandler) { } } - /** * Encode the request body for the MSP request with the given code and return it as an array of bytes. */ diff --git a/src/js/tabs/setup.js b/src/js/tabs/setup.js index 686b06987..6682c6db5 100755 --- a/src/js/tabs/setup.js +++ b/src/js/tabs/setup.js @@ -59,9 +59,31 @@ TABS.setup.initialize = function (callback) { self.initializeInstruments(); - $('#arming-disable-flag-row').attr('title', i18n.getMessage('initialSetupArmingDisableFlagsTooltip')); + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + if (isExpertModeEnabled()) { + $('.initialSetupRebootBootloader').show(); + } else { + $('.initialSetupRebootBootloader').hide(); + } + + $('a.rebootBootloader').click(function () { + var buffer = []; + buffer.push(1); + MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); + }); + + $('a.rebootMsc').click(function () { + var buffer = []; + buffer.push(2); + MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); + }); + } else { + $('.initialSetupRebootBootloader').hide(); + $('.initialSetupRebootMsc').hide(); + } + // UI Hooks $('a.calibrateAccel').click(function () { var self = $(this); diff --git a/src/main.html b/src/main.html index cdd9775b4..94b1652e6 100755 --- a/src/main.html +++ b/src/main.html @@ -323,5 +323,15 @@

+ +

+
+
+
+
+ +
+
+ diff --git a/src/tabs/setup.html b/src/tabs/setup.html index e531d0718..c8d03858f 100644 --- a/src/tabs/setup.html +++ b/src/tabs/setup.html @@ -46,6 +46,12 @@
+
+ +
+
+ +
@@ -61,6 +67,12 @@
+
+ +
+
+ +
From 7fddb38fb7b466f63206f8f8da45eea67ec523f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Mon, 16 Jul 2018 17:18:39 +0200 Subject: [PATCH 018/104] fix throttle position preview --- src/js/tabs/osd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index d5c87efbb..719c6adf3 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -342,7 +342,7 @@ OSD.constants = { default_position: -9, draw_order: 110, positionable: true, - preview: FONT.symbol(SYM.THR) + FONT.symbol(SYM.THR1) + '69' + preview: FONT.symbol(SYM.THR) + FONT.symbol(SYM.THR1) + ' 69' }, CPU_LOAD: { name: 'CPU_LOAD', From eec1388a2d7767f0ad278ad9b7d3b4bacd95275c Mon Sep 17 00:00:00 2001 From: mikeller Date: Tue, 17 Jul 2018 22:01:18 +1200 Subject: [PATCH 019/104] Set file type descriptions for open / save dialogs. --- package-lock.json | 2 +- src/js/LogoManager.js | 2 +- src/js/backup_restore.js | 4 ++-- src/js/tabs/cli.js | 2 +- src/js/tabs/firmware_flasher.js | 4 ++-- src/js/tabs/logging.js | 2 +- src/js/tabs/onboard_logging.js | 2 +- src/js/tabs/osd.js | 4 ++-- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73e367005..774272817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "betaflight-configurator", - "version": "10.3.0", + "version": "10.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/js/LogoManager.js b/src/js/LogoManager.js index d80ecb640..a7d9aa01f 100644 --- a/src/js/LogoManager.js +++ b/src/js/LogoManager.js @@ -26,7 +26,7 @@ var LogoManager = LogoManager || { }, // config for logo image selection dialog acceptFileTypes: [ - { extensions: ['png', 'bmp'] }, + { description: 'images', extensions: ['png', 'bmp'] }, ], }; diff --git a/src/js/backup_restore.js b/src/js/backup_restore.js index 32b973ca2..7e106a2ba 100644 --- a/src/js/backup_restore.js +++ b/src/js/backup_restore.js @@ -206,7 +206,7 @@ function configuration_backup(callback) { var filename = generateFilename(prefix, suffix); var accepts = [{ - extensions: [suffix] + description: suffix.toUpperCase() + ' files', extensions: [suffix] }]; // create or load the file @@ -277,7 +277,7 @@ function configuration_restore(callback) { var chosenFileEntry = null; var accepts = [{ - extensions: ['json'] + description: 'JSON files', extensions: ['json'] }]; // load up the file diff --git a/src/js/tabs/cli.js b/src/js/tabs/cli.js index 608f12e96..db34a4aa0 100644 --- a/src/js/tabs/cli.js +++ b/src/js/tabs/cli.js @@ -67,7 +67,7 @@ TABS.cli.initialize = function (callback) { var filename = generateFilename(prefix, suffix); var accepts = [{ - extensions: [suffix], + description: suffix.toUpperCase() + ' files', extensions: [suffix], }]; chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename, accepts: accepts}, function(entry) { diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index 3ca6f2159..a518fbf58 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -325,7 +325,7 @@ TABS.firmware_flasher.initialize = function (callback) { // UI Hooks $('a.load_file').click(function () { - chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{extensions: ['hex']}]}, function (fileEntry) { + chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{description: 'HEX files', extensions: ['hex']}]}, function (fileEntry) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); @@ -465,7 +465,7 @@ TABS.firmware_flasher.initialize = function (callback) { $(document).on('click', 'span.progressLabel a.save_firmware', function () { var summary = $('select[name="firmware_version"] option:selected').data('summary'); - chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: summary.file, accepts: [{extensions: ['hex']}]}, function (fileEntry) { + chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: summary.file, accepts: [{description: 'HEX files', extensions: ['hex']}]}, function (fileEntry) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); return; diff --git a/src/js/tabs/logging.js b/src/js/tabs/logging.js index a7eb269c1..5b3d65d0d 100644 --- a/src/js/tabs/logging.js +++ b/src/js/tabs/logging.js @@ -236,7 +236,7 @@ TABS.logging.initialize = function (callback) { var filename = generateFilename(prefix, suffix); var accepts = [{ - extensions: [suffix], + description: suffix.toUpperCase() + ' files', extensions: [suffix], }]; // create or load the file diff --git a/src/js/tabs/onboard_logging.js b/src/js/tabs/onboard_logging.js index 68dc1d128..cd8e72fbb 100644 --- a/src/js/tabs/onboard_logging.js +++ b/src/js/tabs/onboard_logging.js @@ -445,7 +445,7 @@ TABS.onboard_logging.initialize = function (callback) { var filename = generateFilename(prefix, suffix); chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename, - accepts: [{extensions: [suffix]}]}, function(fileEntry) { + accepts: [{description: suffix.toUpperCase() + ' files', extensions: [suffix]}]}, function(fileEntry) { var error = chrome.runtime.lastError; if (error) { diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 719c6adf3..8e40d93b8 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -129,7 +129,7 @@ FONT.parseMCMFontFile = function(data) { FONT.openFontFile = function($preview) { return new Promise(function(resolve) { - chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{extensions: ['mcm']}]}, function (fileEntry) { + chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{description: 'MCM files', extensions: ['mcm']}]}, function (fileEntry) { FONT.data.loaded_font_file = fileEntry.name; if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); @@ -2047,7 +2047,7 @@ TABS.osd.initialize = function (callback) { }) $(document).on('click', 'span.progressLabel a.save_font', function () { - chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'baseflight', accepts: [{extensions: ['mcm']}]}, function (fileEntry) { + chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'baseflight', accepts: [{description: 'MCM files', extensions: ['mcm']}]}, function (fileEntry) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); return; From 3caf2d8ff55ee4cc2e975b9f62eb763b8adeb08f Mon Sep 17 00:00:00 2001 From: mikeller Date: Wed, 18 Jul 2018 01:00:12 +1200 Subject: [PATCH 020/104] Moved MSC button to blackbox tab. --- locales/en/messages.json | 18 ++++++++++++------ src/css/tabs/onboard_logging.css | 18 +++++++++++++++++- src/js/tabs/onboard_logging.js | 26 ++++++++++++++++++++++++++ src/js/tabs/setup.js | 7 ------- src/tabs/onboard_logging.html | 17 +++++++++++++++++ src/tabs/setup.html | 6 ------ 6 files changed, 72 insertions(+), 20 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index acf7a1a83..c29bba7b6 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -610,18 +610,12 @@ "initialSetupButtonRebootBootloader": { "message": "Activate Boot Loader / DFU" }, - "initialSetupButtonRebootMsc": { - "message": "Activate Mass Storage Device Mode" - }, "initialSetupBackupRestoreText": { "message": "Backup your configuration in case of an accident, CLI settings are not included - use the command 'diff all' in CLI for this." }, "initialSetupRebootBootloaderText": { "message": "Reboot into boot loader / DFU mode." }, - "initialSetupRebootMscText": { - "message": "Reboot into mass storage device (MSC) mode. Once activated, the onboard flash or SD card on your flight controller will be recognised as a storage device by your computer, and allow you to download your log files. Eject and power cycel your flight controller to leave mass storage device mode." - }, "initialSetupBackupSuccess": { "message": "Backup saved successfully" }, @@ -3597,6 +3591,18 @@ "onboardLoggingOnboardSDCard": { "message": "Onboard SD card" }, + "onboardLoggingMsc": { + "message": "Mass Storage Mode" + }, + "onboardLoggingMscNote": { + "message": "Reboot into mass storage device (MSC) mode. Once activated, the onboard flash or SD card on your flight controller will be recognised as a storage device by your computer, and allow you to download your log files. Eject and power cycel your flight controller to leave mass storage device mode." + }, + "onboardLoggingRebootMscText": { + "message": "Activate Mass Storage Device Mode" + }, + "onboardLoggingMscNotReady": { + "message": "Mass storage mode can not be activated because the storage device is not ready." + }, "dialogConfirmResetTitle": { "message": "Confirm" }, diff --git a/src/css/tabs/onboard_logging.css b/src/css/tabs/onboard_logging.css index 87d48452b..11e5b4318 100644 --- a/src/css/tabs/onboard_logging.css +++ b/src/css/tabs/onboard_logging.css @@ -206,6 +206,22 @@ display: none; } +.require-msc-supported { + display: none; +} + +.tab-onboard_logging.msc-supported .require-msc-supported { + display: block; +} + +.require-msc-not-ready { + display: none; +} + +.tab-onboard_logging.msc-not-ready .require-msc-not-ready { + display: block; +} + @media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) { .tab-onboard_logging table thead tr:first-child { font-size: 12px; @@ -300,4 +316,4 @@ pointer-events: none; text-shadow: none; opacity: 0.5; -} \ No newline at end of file +} diff --git a/src/js/tabs/onboard_logging.js b/src/js/tabs/onboard_logging.js index 68dc1d128..688ab7cae 100644 --- a/src/js/tabs/onboard_logging.js +++ b/src/js/tabs/onboard_logging.js @@ -145,6 +145,20 @@ TABS.onboard_logging.initialize = function (callback) { $("div.blackboxRate").show(); } }).change(); + + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + if (SDCARD.supported || DATAFLASH.supported) { + + $(".tab-onboard_logging") + .toggleClass("msc-supported", true); + + $('a.onboardLoggingRebootMsc').click(function () { + var buffer = []; + buffer.push(2); + MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); + }); + } + } update_html(); @@ -296,6 +310,18 @@ TABS.onboard_logging.initialize = function (callback) { .toggleClass("sdcard-error", SDCARD.state === MSP.SDCARD_STATE_FATAL) .toggleClass("sdcard-initializing", SDCARD.state === MSP.SDCARD_STATE_CARD_INIT || SDCARD.state === MSP.SDCARD_STATE_FS_INIT) .toggleClass("sdcard-ready", SDCARD.state === MSP.SDCARD_STATE_READY); + + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + var mscIsReady = (DATAFLASH.totalSize > 0) || (SDCARD.state === MSP.SDCARD_STATE_READY); + $(".tab-onboard_logging") + .toggleClass("msc-not-ready", !mscIsReady); + + if (!mscIsReady) { + $('a.onboardLoggingRebootMsc').addClass('disabled'); + } else { + $('a.onboardLoggingRebootMsc').removeClass('disabled'); + } + } switch (SDCARD.state) { case MSP.SDCARD_STATE_NOT_PRESENT: diff --git a/src/js/tabs/setup.js b/src/js/tabs/setup.js index 6682c6db5..c3f6663f6 100755 --- a/src/js/tabs/setup.js +++ b/src/js/tabs/setup.js @@ -73,15 +73,8 @@ TABS.setup.initialize = function (callback) { buffer.push(1); MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); }); - - $('a.rebootMsc').click(function () { - var buffer = []; - buffer.push(2); - MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); - }); } else { $('.initialSetupRebootBootloader').hide(); - $('.initialSetupRebootMsc').hide(); } // UI Hooks diff --git a/src/tabs/onboard_logging.html b/src/tabs/onboard_logging.html index 2a70b0b5d..ca85163bc 100644 --- a/src/tabs/onboard_logging.html +++ b/src/tabs/onboard_logging.html @@ -133,6 +133,23 @@

+
+
+
+
+
+
+
+

+ +
+ +
+
+ +

+
+
diff --git a/src/tabs/setup.html b/src/tabs/setup.html index c8d03858f..1e93dbd8b 100644 --- a/src/tabs/setup.html +++ b/src/tabs/setup.html @@ -49,9 +49,6 @@
-
- -
@@ -70,9 +67,6 @@
-
- -
From bd4f88093ff8c6d69aeefd005026a3912910b400 Mon Sep 17 00:00:00 2001 From: leocb Date: Tue, 17 Jul 2018 12:30:27 -0300 Subject: [PATCH 021/104] Added suport for OSD Max G-Force Stat --- locales/en/messages.json | 3 +++ src/js/tabs/osd.js | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index c29bba7b6..06cc5da29 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3364,6 +3364,9 @@ "osdDescStatBattery": { "message": "Voltage of the battery in real time" }, + "osdDescStatGForce": { + "message": "Max G-Force experienced by the craft" + }, "osdTimerSource": { diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 719c6adf3..52eb170c6 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -873,6 +873,10 @@ OSD.constants = { STAT_BATTERY: { name: 'BATTERY_VOLTAGE', desc: 'osdDescStatBattery' + }, + MAX_G_FORCE: { + name: 'MAX_G_FORCE', + desc: 'osdDescStatGForce' } }, ALL_WARNINGS: { @@ -1095,7 +1099,8 @@ OSD.chooseFields = function () { F.USED_MAH, F.MAX_ALTITUDE, F.BLACKBOX, - F.BLACKBOX_LOG_NUMBER + F.BLACKBOX_LOG_NUMBER, + F.MAX_G_FORCE ]; } From 27bd8429faa924a8e42e17b281cdc9350d8b0e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Tue, 19 Jun 2018 11:40:18 +0200 Subject: [PATCH 022/104] initial version of Log Status OSD element config --- locales/en/messages.json | 4 ++++ src/js/tabs/osd.js | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index c29bba7b6..ab9e314d3 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -3316,6 +3316,10 @@ "osdDescGForce": { "message": "Shows how much G-Force the craft is experiencing" }, + "osdDescElementLogStatus": { + "message": "Blackbox number and warnings" + }, + "osdDescStatMaxSpeed": { "message": "Maximum recorded speed" }, diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 719c6adf3..781f023dc 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -800,7 +800,15 @@ OSD.constants = { draw_order: 15, positionable: true, preview: '1.0G' - } + }, + LOG_STATUS: { + name: 'LOG_STATUS', + desc: 'osdDescElementLogStatus', + default_position: -1, + draw_order: 330, + positionable: true, + preview: 'L16' + }, }, UNKNOWN_DISPLAY_FIELD: { name: 'UNKNOWN_', @@ -1014,14 +1022,20 @@ OSD.chooseFields = function () { OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ F.ANTI_GRAVITY ]); - if (semver.gte(CONFIG.apiVersion, "1.40.0")) { - OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ - F.G_FORCE - ]); + if (semver.gte(CONFIG.apiVersion, "1.39.0")) { + OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ + F.ANTI_GRAVITY + ]); + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ + F.LOG_STATUS, + F.G_FORCE, + ]); + } } } } - } + } } } } From de395f0f58f0db84afc040ab67e2a50a966f186b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Tue, 3 Jul 2018 16:50:38 +0200 Subject: [PATCH 023/104] rebase error and element ordering fix --- src/js/tabs/osd.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 781f023dc..0eda9cb3b 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -1022,16 +1022,11 @@ OSD.chooseFields = function () { OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ F.ANTI_GRAVITY ]); - if (semver.gte(CONFIG.apiVersion, "1.39.0")) { + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ - F.ANTI_GRAVITY - ]); - if (semver.gte(CONFIG.apiVersion, "1.40.0")) { - OSD.constants.DISPLAY_FIELDS = OSD.constants.DISPLAY_FIELDS.concat([ - F.LOG_STATUS, - F.G_FORCE, - ]); - } + F.G_FORCE, + F.LOG_STATUS, + ]); } } } From 2f3cd09740526b9e1fa00fd867454881801d00ad Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Fri, 20 Jul 2018 16:18:18 +0200 Subject: [PATCH 024/104] Fix dynamic adjustments with version --- src/js/tabs/adjustments.js | 25 ++++++++++++++++--------- src/tabs/adjustments.html | 33 +++++---------------------------- 2 files changed, 21 insertions(+), 37 deletions(-) diff --git a/src/js/tabs/adjustments.js b/src/js/tabs/adjustments.js index e5f723d89..490a16321 100644 --- a/src/js/tabs/adjustments.js +++ b/src/js/tabs/adjustments.js @@ -20,7 +20,6 @@ TABS.adjustments.initialize = function (callback) { } function load_html() { - self.adjust_template(); $('#content').load("./tabs/adjustments.html", process_html); } @@ -153,6 +152,8 @@ TABS.adjustments.initialize = function (callback) { function process_html() { + self.adjust_template(); + var auxChannelCount = RC.active_channels - 4; var modeTableBodyElement = $('.tab-adjustments .adjustments tbody'); @@ -272,14 +273,20 @@ TABS.adjustments.cleanup = function (callback) { }; TABS.adjustments.adjust_template = function () { - var availableFunctionCount; - if (semver.lt(CONFIG.apiVersion, "1.31.0")) { - availableFunctionCount = 21; // Available in betaflight 2.9 + + var selectFunction = $('#functionSelectionSelect'); + var elementsNumber; + + if (semver.gte(CONFIG.apiVersion, "1.39.0")) { + elementsNumber = 26; // PID Audio + } else if (semver.gte(CONFIG.apiVersion, "1.37.0")) { + elementsNumber = 25; // Horizon Strength } else { - availableFunctionCount = 24; // RC rate Yaw / D setpoint / D setpoint transition added to 3.1.0 + elementsNumber = 24; // Setpoint transition + } + + for (let i = 0; i < elementsNumber; i++) { + selectFunction.append(new Option(i18n.getMessage('adjustmentsFunction' + i), i)); } - var template = $('#tab-adjustments-templates .adjustments .adjustment'); - var functionList = $(template).find('.functionSelection .function'); - var functionListOptions = $(functionList).find('option').slice(0,availableFunctionCount); - functionList.empty().append(functionListOptions); + }; diff --git a/src/tabs/adjustments.html b/src/tabs/adjustments.html index 14c08aae2..4cf8260bd 100644 --- a/src/tabs/adjustments.html +++ b/src/tabs/adjustments.html @@ -66,34 +66,11 @@
- + + + @@ -322,8 +322,60 @@ + + + + + +
+ +
+
+ + + + + + + +
+ +
+
+ + + + + + + +
+ +
+
+ + + + + + +
+ +
+
+ + + - +
+ + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + From 1488f1c6c074166ab2d7b1923d15ecc7b82b44c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Thu, 19 Jul 2018 22:23:20 +0200 Subject: [PATCH 026/104] Add option to reopen last tab on connect --- locales/en/messages.json | 3 +++ src/js/gui.js | 16 ++++++++++++++++ src/js/main.js | 16 +++++++++++++++- src/js/serial_backend.js | 2 +- src/main.html | 4 +++- src/tabs/options.html | 3 +++ 6 files changed, 41 insertions(+), 3 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 643498698..0ac830f56 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -60,6 +60,9 @@ "permanentExpertMode": { "message": "Permanently enable Expert Mode" }, + "rememberLastTab": { + "message": "Reopen last tab on connect" + }, "userLanguageSelect": { "message": "Language (need to restart the application for the changes to take effect)" }, diff --git a/src/js/gui.js b/src/js/gui.js index b3261d54e..54e247121 100644 --- a/src/js/gui.js +++ b/src/js/gui.js @@ -321,5 +321,21 @@ GUI_control.prototype.content_ready = function (callback) { if (callback) callback(); } +GUI_control.prototype.selectDefaultTabWhenConnected = function() { + chrome.storage.local.get(['rememberLastTab', 'lastTab'], function (result) { + let fallbackTab = '#tabs ul.mode-connected .tab_setup a'; + if (!(result.rememberLastTab && !!result.lastTab)) { + $(fallbackTab).click(); + return; + } + let $savedTab = $("#tabs ul.mode-connected ." + result.lastTab + " a"); + if (!!$savedTab.data("ignore-reopen")) { + $(fallbackTab).click(); + } else { + $savedTab.click(); + } + }); +}; + // initialize object into GUI variable var GUI = new GUI_control(); diff --git a/src/js/main.js b/src/js/main.js index 9ebe303af..979724eea 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -91,7 +91,14 @@ function startProcess() { GUI.tab_switch_cleanup(function () { // disable previously active tab highlight $('li', ui_tabs).removeClass('active'); - + + // store last active tab only when connected + if (GUI.connected_to) { + chrome.storage.local.set({ + lastTab: $(self).parent().attr("class") + }); + } + // Highlight selected tab $(self).parent().addClass('active'); @@ -217,6 +224,13 @@ function startProcess() { }).change(); }); + chrome.storage.local.get('rememberLastTab', function (result) { + $('div.rememberLastTab input') + .prop('checked', !!result.rememberLastTab) + .change(function() { chrome.storage.local.set({rememberLastTab: $(this).is(':checked')}) }) + .change(); + }); + if (GUI.operating_system !== 'ChromeOS') { chrome.storage.local.get('checkForConfiguratorUnstableVersions', function (result) { if (result.checkForConfiguratorUnstableVersions) { diff --git a/src/js/serial_backend.js b/src/js/serial_backend.js index 30128eb92..b225d6b0f 100755 --- a/src/js/serial_backend.js +++ b/src/js/serial_backend.js @@ -299,7 +299,7 @@ function finishOpen() { onConnect(); - $('#tabs ul.mode-connected .tab_setup a').click(); + GUI.selectDefaultTabWhenConnected(); } function connectCli() { diff --git a/src/main.html b/src/main.html index 94b1652e6..85d235fae 100755 --- a/src/main.html +++ b/src/main.html @@ -268,7 +268,9 @@ -->
    -
  • +
  • + +
diff --git a/src/tabs/options.html b/src/tabs/options.html index d79dca351..1de44b984 100644 --- a/src/tabs/options.html +++ b/src/tabs/options.html @@ -4,6 +4,9 @@
+
+ +
From c4e9d1778c822bdc7d1cd123599e4b7a3a8f035e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Sun, 22 Jul 2018 10:49:04 +0200 Subject: [PATCH 028/104] load mixer config on demand --- src/js/gui.js | 10 ++-------- src/js/main.js | 2 +- src/js/tabs/motors.js | 6 +++++- src/js/tabs/pid_tuning.js | 6 +++++- src/js/tabs/receiver.js | 6 +++++- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/js/gui.js b/src/js/gui.js index 54e247121..b29d2cc22 100644 --- a/src/js/gui.js +++ b/src/js/gui.js @@ -323,17 +323,11 @@ GUI_control.prototype.content_ready = function (callback) { GUI_control.prototype.selectDefaultTabWhenConnected = function() { chrome.storage.local.get(['rememberLastTab', 'lastTab'], function (result) { - let fallbackTab = '#tabs ul.mode-connected .tab_setup a'; if (!(result.rememberLastTab && !!result.lastTab)) { - $(fallbackTab).click(); + $('#tabs ul.mode-connected .tab_setup a').click(); return; } - let $savedTab = $("#tabs ul.mode-connected ." + result.lastTab + " a"); - if (!!$savedTab.data("ignore-reopen")) { - $(fallbackTab).click(); - } else { - $savedTab.click(); - } + $("#tabs ul.mode-connected ." + result.lastTab + " a").click(); }); }; diff --git a/src/js/main.js b/src/js/main.js index b4c66ad17..0d8c308a3 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -98,7 +98,7 @@ function startProcess() { GUI.tab_switch_cleanup(function () { // disable previously active tab highlight $('li', ui_tabs).removeClass('active'); - + // Highlight selected tab $(self).parent().addClass('active'); diff --git a/src/js/tabs/motors.js b/src/js/tabs/motors.js index d90e3fa4b..d8d6e4d58 100644 --- a/src/js/tabs/motors.js +++ b/src/js/tabs/motors.js @@ -45,7 +45,11 @@ TABS.motors.initialize = function (callback) { } function load_motor_data() { - MSP.send_message(MSPCodes.MSP_MOTOR, false, false, load_html); + MSP.send_message(MSPCodes.MSP_MOTOR, false, false, load_mixer_config); + } + + function load_mixer_config() { + MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_html); } function load_html() { diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index c29c574b7..ca60d0caf 100755 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -39,9 +39,13 @@ TABS.pid_tuning.initialize = function (callback) { }).then(function() { return MSP.promise(MSPCodes.MSP_RC_DEADBAND); }).then(function() { - $('#content').load("./tabs/pid_tuning.html", process_html); + MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_html); }); + function load_html() { + $('#content').load("./tabs/pid_tuning.html", process_html); + } + function pid_and_rc_to_form() { self.setProfile(); if (semver.gte(CONFIG.apiVersion, "1.20.0")) { diff --git a/src/js/tabs/receiver.js b/src/js/tabs/receiver.js index 2347065a4..3d252bef4 100644 --- a/src/js/tabs/receiver.js +++ b/src/js/tabs/receiver.js @@ -40,7 +40,7 @@ TABS.receiver.initialize = function (callback) { } function load_rx_config() { - var next_callback = load_html; + var next_callback = load_mixer_config; if (semver.gte(CONFIG.apiVersion, "1.20.0")) { MSP.send_message(MSPCodes.MSP_RX_CONFIG, false, false, next_callback); } else { @@ -48,6 +48,10 @@ TABS.receiver.initialize = function (callback) { } } + function load_mixer_config() { + MSP.send_message(MSPCodes.MSP_MIXER_CONFIG, false, false, load_html); + } + function load_html() { $('#content').load("./tabs/receiver.html", process_html); } From 25e4e7f6caf27c5305ebd598f3d452305c059bdf Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 9 Jul 2018 18:17:08 +0200 Subject: [PATCH 029/104] Add feedforward support --- locales/en/messages.json | 9 ++++++++ src/css/tabs/pid_tuning.css | 6 ++--- src/js/fc.js | 4 ++++ src/js/msp/MSPHelper.js | 37 +++++++++++++++++++++---------- src/js/tabs/pid_tuning.js | 44 ++++++++++++++++++++++++++++++++++--- src/tabs/pid_tuning.html | 23 ++++++++++++++++--- 6 files changed, 103 insertions(+), 20 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 643498698..354107670 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1276,6 +1276,12 @@ "receiverRcInterpolationInterval": { "message": "RC Interpolation Interval [ms]" }, + "pidTuningFeedforwardTransition": { + "message": "Feedforward transition" + }, + "pidTuningFeedforwardTransitionHelp": { + "message": "With this parameter, the Feedforward term can be reduced near the center of the sticks, which results in smoother end of flips and rolls.
The value represents a point of stick deflection: 0 - stick centered, 1 - full deflection. When the stick is above that point, Feedforward is kept constant at its configured value. When the stick is positioned below that point, Feedforward is reduced proportionally, reaching 0 at the stick center position.
Value of 1 gives maximum smoothing effect, while value of 0 keeps the Feedforward fixed at its configured value over the whole stick range." + }, "pidTuningDtermSetpointTransition": { "message": "D Setpoint transition" }, @@ -1300,6 +1306,9 @@ "pidTuningDerivative": { "message": "Derivative" }, + "pidTuningFeedforward": { + "message": "Feedforward" + }, "pidTuningRcRate": { "message": "RC Rate" }, diff --git a/src/css/tabs/pid_tuning.css b/src/css/tabs/pid_tuning.css index 8879ab88d..01b254be3 100644 --- a/src/css/tabs/pid_tuning.css +++ b/src/css/tabs/pid_tuning.css @@ -244,12 +244,12 @@ padding: 5px; text-align: left; border-right: 1px solid #ccc; - width: 12.5%; + width: calc(100% / 9); } .tab-pid_tuning .pid_titlebar th:first-child { text-align: left; - width: 12.5%; + width: calc(100% / 9); } .tab-pid_tuning .pid_titlebar th:last-child { @@ -336,7 +336,7 @@ .tab-pid_tuning table td { padding: 1px; padding-left: 5px; - width: 12.5%; + width: calc(100% / 9); border-right: 1px solid #ccc; } diff --git a/src/js/fc.js b/src/js/fc.js index 7dfe0a9da..084ea1b96 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -376,6 +376,10 @@ var FC = { absoluteControlGain: 0, throttleBoost: 0, acroTrainerAngleLimit: 0, + feedforwardRoll: 0, + feedforwardPitch: 0, + feedforwardYaw: 0, + feedforwardTransition: 0, }; SENSOR_CONFIG = { diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 3f5964b31..5f046469b 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -878,7 +878,11 @@ MspHelper.prototype.process_data = function(dataHandler) { ADVANCED_TUNING.deltaMethod = data.readU8(); ADVANCED_TUNING.vbatPidCompensation = data.readU8(); if (semver.gte(CONFIG.apiVersion, "1.20.0")) { - ADVANCED_TUNING.dtermSetpointTransition = data.readU8(); + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + ADVANCED_TUNING.feedforwardTransition = data.readU8(); + } else { + ADVANCED_TUNING.dtermSetpointTransition = data.readU8(); + } ADVANCED_TUNING.dtermSetpointWeight = data.readU8(); ADVANCED_TUNING.toleranceBand = data.readU8(); ADVANCED_TUNING.toleranceBandReduction = data.readU8(); @@ -904,6 +908,9 @@ MspHelper.prototype.process_data = function(dataHandler) { ADVANCED_TUNING.absoluteControlGain = data.readU8(); ADVANCED_TUNING.throttleBoost = data.readU8(); ADVANCED_TUNING.acroTrainerAngleLimit = data.readU8(); + ADVANCED_TUNING.feedforwardRoll = data.readU16(); + ADVANCED_TUNING.feedforwardPitch = data.readU16(); + ADVANCED_TUNING.feedforwardYaw = data.readU16(); } } } @@ -1542,14 +1549,20 @@ MspHelper.prototype.crunch = function(code) { .push16(ADVANCED_TUNING.yawItermIgnoreRate) .push16(ADVANCED_TUNING.yaw_p_limit) .push8(ADVANCED_TUNING.deltaMethod) - .push8(ADVANCED_TUNING.vbatPidCompensation) - .push8(ADVANCED_TUNING.dtermSetpointTransition) - .push8(Math.min(ADVANCED_TUNING.dtermSetpointWeight, 254)) - .push8(ADVANCED_TUNING.toleranceBand) - .push8(ADVANCED_TUNING.toleranceBandReduction) - .push8(ADVANCED_TUNING.itermThrottleGain) - .push16(ADVANCED_TUNING.pidMaxVelocity) - .push16(ADVANCED_TUNING.pidMaxVelocityYaw); + .push8(ADVANCED_TUNING.vbatPidCompensation); + + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + buffer.push8(ADVANCED_TUNING.feedforwardTransition); + } else { + buffer.push8(ADVANCED_TUNING.dtermSetpointTransition); + } + + buffer.push8(Math.min(ADVANCED_TUNING.dtermSetpointWeight, 254)) + .push8(ADVANCED_TUNING.toleranceBand) + .push8(ADVANCED_TUNING.toleranceBandReduction) + .push8(ADVANCED_TUNING.itermThrottleGain) + .push16(ADVANCED_TUNING.pidMaxVelocity) + .push16(ADVANCED_TUNING.pidMaxVelocityYaw); if (semver.gte(CONFIG.apiVersion, "1.24.0")) { buffer.push8(ADVANCED_TUNING.levelAngleLimit) @@ -1569,9 +1582,11 @@ MspHelper.prototype.crunch = function(code) { .push8(ADVANCED_TUNING.itermRelaxType) .push8(ADVANCED_TUNING.absoluteControlGain) .push8(ADVANCED_TUNING.throttleBoost) - .push8(ADVANCED_TUNING.acroTrainerAngleLimit); + .push8(ADVANCED_TUNING.acroTrainerAngleLimit) + .push16(ADVANCED_TUNING.feedforwardRoll) + .push16(ADVANCED_TUNING.feedforwardPitch) + .push16(ADVANCED_TUNING.feedforwardYaw); } - } } } diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index c29c574b7..16a81cf54 100755 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -370,6 +370,28 @@ TABS.pid_tuning.initialize = function (callback) { }); acroTrainerAngleLimitNumberElement.val(ADVANCED_TUNING.acroTrainerAngleLimit).change(); + // Yaw D + $('.pid_tuning .YAW input[name="d"]').val(PIDs[2][2]); // PID Yaw D + + // Feedforward + $('.pid_tuning .ROLL input[name="f"]').val(ADVANCED_TUNING.feedforwardRoll); + $('.pid_tuning .PITCH input[name="f"]').val(ADVANCED_TUNING.feedforwardPitch); + $('.pid_tuning .YAW input[name="f"]').val(ADVANCED_TUNING.feedforwardYaw); + + var feedforwardTransitionNumberElement = $('input[name="feedforwardTransition-number"]'); + var feedforwardTransitionRangeElement = $('input[name="feedforwardTransition-range"]'); + + feedforwardTransitionNumberElement.val(ADVANCED_TUNING.feedforwardTransition / 100); + feedforwardTransitionRangeElement.val(ADVANCED_TUNING.feedforwardTransition / 100); + + feedforwardTransitionNumberElement.change(function () { + feedforwardTransitionRangeElement.val($(this).val()); + }); + feedforwardTransitionRangeElement.change(function () { + feedforwardTransitionNumberElement.val($(this).val()); + }); + + } else { $('.itermrotation').hide(); $('.smartfeedforward').hide(); @@ -377,6 +399,11 @@ TABS.pid_tuning.initialize = function (callback) { $('.absoluteControlGain').hide(); $('.throttleBoost').hide(); $('.acroTrainerAngleLimit').hide(); + $('.pid_tuning .YAW input[name="d"]').hide(); + $('.pid_tuning .ROLL input[name="f"]').hide(); + $('.pid_tuning .PITCH input[name="f"]').hide(); + $('.pid_tuning .YAW input[name="f"]').hide(); + $('#pid-tuning .feedForwardTransition').hide(); } $('input[id="gyroNotch1Enabled"]').change(function() { @@ -609,6 +636,7 @@ TABS.pid_tuning.initialize = function (callback) { } if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + ADVANCED_TUNING.itermRotation = $('input[id="itermrotation"]').is(':checked') ? 1 : 0; ADVANCED_TUNING.smartFeedforward = $('input[id="smartfeedforward"]').is(':checked') ? 1 : 0; @@ -620,8 +648,13 @@ TABS.pid_tuning.initialize = function (callback) { ADVANCED_TUNING.throttleBoost = $('input[name="throttleBoost-number"]').val(); ADVANCED_TUNING.acroTrainerAngleLimit = $('input[name="acroTrainerAngleLimit-number"]').val(); - } + ADVANCED_TUNING.feedforwardRoll = parseInt($('.pid_tuning .ROLL input[name="f"]').val()); + ADVANCED_TUNING.feedforwardPitch = parseInt($('.pid_tuning .PITCH input[name="f"]').val()); + ADVANCED_TUNING.feedforwardYaw = parseInt($('.pid_tuning .YAW input[name="f"]').val()); + + ADVANCED_TUNING.feedforwardTransition = parseInt($('input[name="feedforwardTransition-number"]').val() * 100); + } } function showAllPids() { @@ -1467,8 +1500,13 @@ TABS.pid_tuning.updatePidControllerParameters = function () { } else { $('.pid_tuning .YAW_JUMP_PREVENTION').hide(); - $('#pid-tuning .dtermSetpointTransition').show(); - $('#pid-tuning .dtermSetpoint').show(); + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + $('#pid-tuning .dtermSetpointTransition').hide(); + $('#pid-tuning .dtermSetpoint').hide(); + } else { + $('#pid-tuning .dtermSetpointTransition').show(); + $('#pid-tuning .dtermSetpoint').show(); + } $('#pid-tuning .delta').hide(); } diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html index f22496a37..8512dccaa 100755 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -72,6 +72,7 @@ + @@ -80,7 +81,7 @@ - + + @@ -119,7 +122,8 @@ - + + @@ -293,7 +297,7 @@ - + + + + + + + From 1e1952b16b02e13c479b5d44aabe00f780a64450 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Tue, 10 Jul 2018 09:26:06 +0200 Subject: [PATCH 030/104] Refactor PID table --- src/css/tabs/pid_tuning.css | 4 +--- src/js/tabs/pid_tuning.js | 11 +++++++---- src/tabs/pid_tuning.html | 12 +++++------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/css/tabs/pid_tuning.css b/src/css/tabs/pid_tuning.css index 01b254be3..e6352152b 100644 --- a/src/css/tabs/pid_tuning.css +++ b/src/css/tabs/pid_tuning.css @@ -222,6 +222,7 @@ margin: 0px; border-collapse: collapse; width: 100%; + table-layout: fixed; } .tab-pid_tuning .gui_box { @@ -244,12 +245,10 @@ padding: 5px; text-align: left; border-right: 1px solid #ccc; - width: calc(100% / 9); } .tab-pid_tuning .pid_titlebar th:first-child { text-align: left; - width: calc(100% / 9); } .tab-pid_tuning .pid_titlebar th:last-child { @@ -336,7 +335,6 @@ .tab-pid_tuning table td { padding: 1px; padding-left: 5px; - width: calc(100% / 9); border-right: 1px solid #ccc; } diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index 16a81cf54..2a033c217 100755 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -399,11 +399,14 @@ TABS.pid_tuning.initialize = function (callback) { $('.absoluteControlGain').hide(); $('.throttleBoost').hide(); $('.acroTrainerAngleLimit').hide(); + $('.pid_tuning .YAW input[name="d"]').hide(); - $('.pid_tuning .ROLL input[name="f"]').hide(); - $('.pid_tuning .PITCH input[name="f"]').hide(); - $('.pid_tuning .YAW input[name="f"]').hide(); - $('#pid-tuning .feedForwardTransition').hide(); + + // Feedforward column + $('#pid_main tr :nth-child(5)').hide(); + $('#pid_main .pid_titlebar2 th').attr("colspan", 8); + + $('#pid-tuning .feedforwardTransition').hide(); } $('input[id="gyroNotch1Enabled"]').change(function() { diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html index 8512dccaa..db58cb636 100755 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -66,8 +66,8 @@
-
+
@@ -93,6 +94,7 @@
@@ -111,6 +113,7 @@
@@ -323,6 +327,19 @@
+
+ +
+
+
- +
+ @@ -78,9 +78,7 @@ -
- - +
@@ -492,7 +490,7 @@
- +
-
@@ -505,7 +503,7 @@
+
From 19f4145965a231a24f539aa5529278dc9d7d8869 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Sat, 21 Jul 2018 08:52:00 +0200 Subject: [PATCH 031/104] Add PID F inflight adjustments --- locales/en/messages.json | 15 +++++++++++++++ src/js/tabs/adjustments.js | 18 +++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 354107670..354db4f48 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1636,15 +1636,30 @@ "adjustmentsFunction22": { "message": "D Setpoint" }, + "adjustmentsFunction22_2": { + "message": "Pitch & Roll F Adjustment" + }, "adjustmentsFunction23": { "message": "D Setpoint Transition" }, + "adjustmentsFunction23_2": { + "message": "Feedforward Transition" + }, "adjustmentsFunction24": { "message": "Horizon Strength Adjustment" }, "adjustmentsFunction25": { "message": "PID-Audio Selection" }, + "adjustmentsFunction26": { + "message": "Pitch F Adjustment" + }, + "adjustmentsFunction27": { + "message": "Roll F Adjustment" + }, + "adjustmentsFunction28": { + "message": "Yaw F Adjustment" + }, "adjustmentsSave": { "message": "Save" }, diff --git a/src/js/tabs/adjustments.js b/src/js/tabs/adjustments.js index 490a16321..38be7ab5f 100644 --- a/src/js/tabs/adjustments.js +++ b/src/js/tabs/adjustments.js @@ -277,7 +277,9 @@ TABS.adjustments.adjust_template = function () { var selectFunction = $('#functionSelectionSelect'); var elementsNumber; - if (semver.gte(CONFIG.apiVersion, "1.39.0")) { + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + elementsNumber = 29; // PID Audio + } else if (semver.gte(CONFIG.apiVersion, "1.39.0")) { elementsNumber = 26; // PID Audio } else if (semver.gte(CONFIG.apiVersion, "1.37.0")) { elementsNumber = 25; // Horizon Strength @@ -288,5 +290,19 @@ TABS.adjustments.adjust_template = function () { for (let i = 0; i < elementsNumber; i++) { selectFunction.append(new Option(i18n.getMessage('adjustmentsFunction' + i), i)); } + + // For 1.40, the D Setpoint has been replaced, so we replace it with the correct values + if (semver.gte(CONFIG.apiVersion, "1.40.0")) { + + var element22 = selectFunction.find("option[value='22']"); + var element23 = selectFunction.find("option[value='23']"); + // Change the "text" + element22.text(i18n.getMessage('adjustmentsFunction22_2')); + element23.text(i18n.getMessage('adjustmentsFunction23_2')); + + // Reorder, we insert it with the other FF elements to be coherent... + element22.insertAfter(selectFunction.find("option[value='25']")); + element23.insertAfter(selectFunction.find("option[value='28']")); + } }; From b6b5608aee288d3564d13856766f7f489486eee1 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 23 Jul 2018 09:19:50 +0200 Subject: [PATCH 032/104] Remove unused PIDs --- src/js/tabs/pid_tuning.js | 280 ++++++++++---------------------------- src/tabs/pid_tuning.html | 49 +++---- 2 files changed, 94 insertions(+), 235 deletions(-) mode change 100755 => 100644 src/js/tabs/pid_tuning.js mode change 100755 => 100644 src/tabs/pid_tuning.html diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js old mode 100755 new mode 100644 index 2a033c217..a5f8005ec --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -49,142 +49,19 @@ TABS.pid_tuning.initialize = function (callback) { } // Fill in the data from PIDs array - var i = 0; - $('.pid_tuning .ROLL input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[0][i++]); - break; - case 1: - $(this).val(PIDs[0][i++]); - break; - case 2: - $(this).val(PIDs[0][i++]); - break; - } - }); - i = 0; - $('.pid_tuning .PITCH input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[1][i++]); - break; - case 1: - $(this).val(PIDs[1][i++]); - break; - case 2: - $(this).val(PIDs[1][i++]); - break; - } - }); + // For each pid name + PID_names.forEach(function(elementPid, indexPid) { - i = 0; - $('.pid_tuning .YAW input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[2][i++]); - break; - case 1: - $(this).val(PIDs[2][i++]); - break; - } - }); - $('.pid_tuning .YAW_JUMP_PREVENTION input').each(function () { - switch (i) { - case 2: - $(this).val(PIDs[2][i++]); - break; - } - }); + // Look into the PID table to a row with the name of the pid + var searchRow = $('.pid_tuning .' + elementPid + ' input'); - i = 0; - $('.pid_tuning .ALT input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[3][i++]); - break; - case 1: - $(this).val(PIDs[3][i++]); - break; - case 2: - $(this).val(PIDs[3][i++]); - break; - } - }); - - i = 0; - $('.pid_tuning .Pos input').each(function () { - $(this).val(PIDs[4][i++]); - }); - - i = 0; - $('.pid_tuning .PosR input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[5][i++]); - break; - case 1: - $(this).val(PIDs[5][i++]); - break; - case 2: - $(this).val(PIDs[5][i++]); - break; - } - }); - - i = 0; - $('.pid_tuning .NavR input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[6][i++]); - break; - case 1: - $(this).val(PIDs[6][i++]); - break; - case 2: - $(this).val(PIDs[6][i++]); - break; - } - }); - - i = 0; - $('.pid_tuning .ANGLE input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[7][i++]); - break; - } - }); - $('.pid_tuning .HORIZON input').each(function () { - switch (i) { - case 1: - $(this).val(PIDs[7][i++]); - break; - case 2: - $(this).val(PIDs[7][i++]); - break; - } - }); - - i = 0; - $('.pid_tuning .MAG input').each(function () { - $(this).val(PIDs[8][i++]); - }); - - i = 0; - $('.pid_tuning .Vario input').each(function () { - switch (i) { - case 0: - $(this).val(PIDs[9][i++]); - break; - case 1: - $(this).val(PIDs[9][i++]); - break; - case 2: - $(this).val(PIDs[9][i++]); - break; - } + // Assign each value + searchRow.each(function (indexInput) { + if (PIDs[indexPid][indexInput] !== undefined) { + $(this).val(PIDs[indexPid][indexInput]); + } + }); }); // Fill in data from RC_tuning object @@ -519,60 +396,19 @@ TABS.pid_tuning.initialize = function (callback) { function form_to_pid_and_rc() { // Fill in the data from PIDs array // Catch all the changes and stuff the inside PIDs array - var i = 0; - $('table.pid_tuning tr.ROLL .pid_data input').each(function () { - PIDs[0][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('table.pid_tuning tr.PITCH .pid_data input').each(function () { - PIDs[1][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('table.pid_tuning tr.YAW .pid_data input').each(function () { - PIDs[2][i++] = parseFloat($(this).val()); - }); - $('table.pid_tuning tr.YAW_JUMP_PREVENTION .pid_data input').each(function () { - PIDs[2][i++] = parseFloat($(this).val()); - }); - i = 0; - $('table.pid_tuning tr.ALT input').each(function () { - PIDs[3][i++] = parseFloat($(this).val()); - }); + // For each pid name + PID_names.forEach(function(elementPid, indexPid) { - i = 0; - $('table.pid_tuning tr.Vario input').each(function () { - PIDs[9][i++] = parseFloat($(this).val()); - }); + // Look into the PID table to a row with the name of the pid + var searchRow = $('.pid_tuning .' + elementPid + ' input'); - i = 0; - $('table.pid_tuning tr.Pos input').each(function () { - PIDs[4][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('table.pid_tuning tr.PosR input').each(function () { - PIDs[5][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('table.pid_tuning tr.NavR input').each(function () { - PIDs[6][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('div.pid_tuning tr.ANGLE input').each(function () { - PIDs[7][i++] = parseFloat($(this).val()); - }); - $('div.pid_tuning tr.HORIZON input').each(function () { - PIDs[7][i++] = parseFloat($(this).val()); - }); - - i = 0; - $('div.pid_tuning tr.MAG input').each(function () { - PIDs[8][i++] = parseFloat($(this).val()); + // Assign each value + searchRow.each(function (indexInput) { + if ($(this).val()) { + PIDs[indexPid][indexInput] = parseFloat($(this).val()); + } + }); }); // catch RC_tuning changes @@ -661,37 +497,54 @@ TABS.pid_tuning.initialize = function (callback) { } function showAllPids() { - $('.tab-pid_tuning .pid_tuning').show(); - } - function hideUnusedPids() { - $('.tab-pid_tuning .pid_tuning').hide(); + // Hide all optional elements + $('.pid_optional tr').hide(); // Hide all rows + $('.pid_optional table').hide(); // Hide tables + $('.pid_optional').hide(); // Hide general div - $('#pid_main').show(); + // Only show rows supported by the firmware + PID_names.forEach(function(elementPid) { + // Show rows for the PID + $('.pid_tuning .' + elementPid).show(); - if (have_sensor(CONFIG.activeSensors, 'acc')) { - $('#pid_accel').show(); - $('#pid_level').show(); - $('#pid_sensitivity').show(); - } + // Show titles and other elements needed by the PID + $('.needed_by_' + elementPid).show(); + }); - var showTitle = false; - if (have_sensor(CONFIG.activeSensors, 'baro') || - have_sensor(CONFIG.activeSensors, 'sonar')) { - $('#pid_baro').show(); - showTitle = true; + // Special case + if (semver.lt(CONFIG.apiVersion, "1.24.0")) { + $('#pid_sensitivity').hide(); } - if (have_sensor(CONFIG.activeSensors, 'mag')) { - $('#pid_mag').show(); - showTitle = true; + + } + + function hideUnusedPids() { + + if (!have_sensor(CONFIG.activeSensors, 'acc')) { + $('#pid_accel').hide(); } - if (FEATURE_CONFIG.features.isEnabled('GPS')) { - $('#pid_gps').show(); - showTitle = true; + + var hideSensorPid = function(element, sensorReady) { + var isVisible = element.is(":visible"); + if (!isVisible || !sensorReady) { + element.hide(); + isVisible = false; + } + + return isVisible; } - if (showTitle) { - $('#pid_optional').show(); + var isVisibleBaroMagGps = false; + + isVisibleBaroMagGps |= hideSensorPid($('#pid_baro'), have_sensor(CONFIG.activeSensors, 'baro') || have_sensor(CONFIG.activeSensors, 'sonar')); + + isVisibleBaroMagGps |= hideSensorPid($('#pid_mag'), have_sensor(CONFIG.activeSensors, 'mag')); + + isVisibleBaroMagGps |= hideSensorPid($('#pid_gps'), have_sensor(CONFIG.activeSensors, 'GPS')); + + if (!isVisibleBaroMagGps) { + $('#pid_baro_mag_gps').hide(); } } @@ -873,6 +726,7 @@ TABS.pid_tuning.initialize = function (callback) { } } + showAllPids(); updatePidDisplay(); showAllButton.on('click', function(){ @@ -981,12 +835,16 @@ TABS.pid_tuning.initialize = function (callback) { $('.tab-pid_tuning .note').hide(); } + // Add a name to each row of PIDs if empty $('.pid_tuning tr').each(function(){ - for(i = 0; i < PID_names.length; i++) { - if($(this).hasClass(PID_names[i])) { - $(this).find('td:first').text(PID_names[i]); + for(i = 0; i < PID_names.length; i++) { + if($(this).hasClass(PID_names[i])) { + var firstColumn = $(this).find('td:first'); + if (!firstColumn.text()) { + firstColumn.text(PID_names[i]); + } + } } - } }); diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html old mode 100755 new mode 100644 index db58cb636..afe4673b9 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -33,7 +33,7 @@
-
+
@@ -139,17 +139,17 @@
-
- - +
+
+
- - +
+ @@ -161,16 +161,16 @@ - + - +
VEL
- - +
+ @@ -183,8 +183,8 @@
- - +
+ @@ -213,9 +213,9 @@
-
- - +
+
+
@@ -224,42 +224,43 @@
- - +
+
- - +
+ - +
- - +
+
- - +
+
+
From 16c5f9feb5d6649647e1d460a2c313ab472c9b4b Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 23 Jul 2018 11:50:47 +0200 Subject: [PATCH 033/104] Add Anti Gravity Mode --- locales/en/messages.json | 11 +++++++++++ src/js/fc.js | 1 + src/js/msp/MSPHelper.js | 4 +++- src/js/tabs/pid_tuning.js | 21 +++++++++++++++++++++ src/tabs/pid_tuning.html | 15 +++++++++++++-- 5 files changed, 49 insertions(+), 3 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 354db4f48..d02e65094 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1242,6 +1242,17 @@ "message": "Profile independent PID Controller Settings" }, + "pidTuningAntiGravityMode": { + "message": "Anti Gravity Mode" + }, + "pidTuningAntiGravityModeOptionSmooth": { + "message": "Smooth", + "description": "One of the modes of anti gravity" + }, + "pidTuningAntiGravityModeOptionStep": { + "message": "Step", + "description": "One of the modes of anti gravity" + }, "pidTuningAntiGravityGain": { "message": "Anti Gravity Gain" }, diff --git a/src/js/fc.js b/src/js/fc.js index 084ea1b96..a3cd969c8 100644 --- a/src/js/fc.js +++ b/src/js/fc.js @@ -380,6 +380,7 @@ var FC = { feedforwardPitch: 0, feedforwardYaw: 0, feedforwardTransition: 0, + antiGravityMode: 0, }; SENSOR_CONFIG = { diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index 5f046469b..59b1ccea5 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -911,6 +911,7 @@ MspHelper.prototype.process_data = function(dataHandler) { ADVANCED_TUNING.feedforwardRoll = data.readU16(); ADVANCED_TUNING.feedforwardPitch = data.readU16(); ADVANCED_TUNING.feedforwardYaw = data.readU16(); + ADVANCED_TUNING.antiGravityMode = data.readU8(); } } } @@ -1585,7 +1586,8 @@ MspHelper.prototype.crunch = function(code) { .push8(ADVANCED_TUNING.acroTrainerAngleLimit) .push16(ADVANCED_TUNING.feedforwardRoll) .push16(ADVANCED_TUNING.feedforwardPitch) - .push16(ADVANCED_TUNING.feedforwardYaw); + .push16(ADVANCED_TUNING.feedforwardYaw) + .push8(ADVANCED_TUNING.antiGravityMode); } } } diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index 2a033c217..a278ddef9 100755 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -391,6 +391,22 @@ TABS.pid_tuning.initialize = function (callback) { feedforwardTransitionNumberElement.val($(this).val()); }); + // AntiGravity Mode + var antiGravityModeSelect = $('.antigravity select[id="antiGravityMode"]'); + antiGravityModeSelect.change(function () { + var antiGravityModeValue = $('.antigravity select[id="antiGravityMode"]').val(); + + // Smooth + if (antiGravityModeValue == 0) { + $('.antigravity table th:nth-child(3)').hide(); + $('.antigravity table td:nth-child(3)').hide(); + } else { + $('.antigravity table th:nth-child(3)').show(); + $('.antigravity table td:nth-child(3)').show(); + } + }); + + antiGravityModeSelect.val(ADVANCED_TUNING.antiGravityMode).change(); } else { $('.itermrotation').hide(); @@ -407,6 +423,9 @@ TABS.pid_tuning.initialize = function (callback) { $('#pid_main .pid_titlebar2 th').attr("colspan", 8); $('#pid-tuning .feedforwardTransition').hide(); + + $('.antigravity table th:first-child').hide(); + $('.antigravity table td:first-child').hide(); } $('input[id="gyroNotch1Enabled"]').change(function() { @@ -657,6 +676,8 @@ TABS.pid_tuning.initialize = function (callback) { ADVANCED_TUNING.feedforwardYaw = parseInt($('.pid_tuning .YAW input[name="f"]').val()); ADVANCED_TUNING.feedforwardTransition = parseInt($('input[name="feedforwardTransition-number"]').val() * 100); + + ADVANCED_TUNING.antiGravityMode = $('select[id="antiGravityMode"]').val(); } } diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html index db58cb636..2c51edb30 100755 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -455,14 +455,25 @@
+ - - + + +
+ + + + + +
From c6849b1b60eb30a3873fb50c3331f001ab3a0b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Mon, 23 Jul 2018 17:43:06 +0200 Subject: [PATCH 034/104] add switch to show/hide unused modes --- locales/en/messages.json | 3 +++ src/js/tabs/auxiliary.js | 26 ++++++++++++++++++++++++-- src/tabs/auxiliary.html | 6 ++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 21c8579a2..1b3e9f770 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1504,6 +1504,9 @@ "auxiliaryHelp": { "message": "Use ranges to define the switches on your transmitter and corresponding mode assignments. A receiver channel that gives a reading between a range min/max will activate the mode. Remember to save your settings using the Save button." }, + "auxiliaryToggleUnused": { + "message": "Show/hide unused modes" + }, "auxiliaryMin": { "message": "Min" }, diff --git a/src/js/tabs/auxiliary.js b/src/js/tabs/auxiliary.js index ce987c5db..c5dbeed50 100644 --- a/src/js/tabs/auxiliary.js +++ b/src/js/tabs/auxiliary.js @@ -244,8 +244,9 @@ TABS.auxiliary.initialize = function (callback) { } function update_ui() { - for (var i = 0; i < AUX_CONFIG.length; i++) { - var modeElement = $('#mode-' + i); + let hasUsedMode = false; + for (let i = 0; i < AUX_CONFIG.length; i++) { + let modeElement = $('#mode-' + i); if (modeElement.find(' .range').length == 0) { // if the mode is unused, skip it modeElement.removeClass('off').removeClass('on'); @@ -257,8 +258,17 @@ TABS.auxiliary.initialize = function (callback) { } else { $('.mode .name').eq(i).data('modeElement').removeClass('on').addClass('off'); } + hasUsedMode = true; } + let hideUnused = hideUnusedModes && hasUsedMode; + for (let i = 0; i < AUX_CONFIG.length; i++) { + let modeElement = $('#mode-' + i); + if (modeElement.find(' .range').length == 0) { + modeElement.toggle(!hideUnused); + } + } + auto_select_channel(RC.channels); var auxChannelCount = RC.active_channels - 4; @@ -306,6 +316,18 @@ TABS.auxiliary.initialize = function (callback) { return fillPrevChannelsValues(); } + let hideUnusedModes = false; + chrome.storage.local.get('hideUnusedModes', function (result) { + $("input#switch-toggle-unused") + .change(function() { + hideUnusedModes = $(this).prop("checked"); + chrome.storage.local.set({ hideUnusedModes: hideUnusedModes }); + update_ui(); + }) + .prop("checked", !!result.hideUnusedModes) + .change(); + }); + // update ui instantly on first load update_ui(); diff --git a/src/tabs/auxiliary.html b/src/tabs/auxiliary.html index b4fb11bfb..90a44f4a4 100644 --- a/src/tabs/auxiliary.html +++ b/src/tabs/auxiliary.html @@ -7,6 +7,12 @@

+

+

+ + +
+

From ce37a5343b72e1c0c1903a9bd6f8d837bb31120c Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Wed, 25 Jul 2018 15:18:15 +0200 Subject: [PATCH 035/104] Simplify Acro Trainer Slider Limit the range to 10-80 (actually was 0, 10-80) --- locales/en/messages.json | 2 +- src/js/tabs/pid_tuning.js | 13 ++----------- src/tabs/pid_tuning.html | 4 ++-- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 1b3e9f770..8ae441ee6 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -2829,7 +2829,7 @@ "message": "Acro Trainer Angle Limit" }, "pidTuningAcroTrainerAngleLimitHelp": { - "message": "Adds a new angle limiting mode for pilots who are learning to fly in acro mode. The range valid is 10-80 (a value of 0 deactivates it)" + "message": "Adds a new angle limiting mode for pilots who are learning to fly in acro mode. The range valid is 10-80 and must be activated with a switch in the $t(tabAuxiliary.message) tab." }, "configHelp2": { diff --git a/src/js/tabs/pid_tuning.js b/src/js/tabs/pid_tuning.js index 15ef3eb41..3a1937951 100644 --- a/src/js/tabs/pid_tuning.js +++ b/src/js/tabs/pid_tuning.js @@ -234,20 +234,11 @@ TABS.pid_tuning.initialize = function (callback) { var acroTrainerAngleLimitNumberElement = $('input[name="acroTrainerAngleLimit-number"]'); var acroTrainerAngleLimitRangeElement = $('input[name="acroTrainerAngleLimit-range"]'); - var validateAcroTrainerAngle = function(value) { - // The minimum acro trainer angle is 10, but we must let zero too to deactivate it - if (value > 0 && value < 10) { - value = 10; - } - acroTrainerAngleLimitRangeElement.val(value); - acroTrainerAngleLimitNumberElement.val(value); - } - acroTrainerAngleLimitNumberElement.change(function () { - validateAcroTrainerAngle($(this).val()); + acroTrainerAngleLimitRangeElement.val($(this).val()); }); acroTrainerAngleLimitRangeElement.change(function () { - validateAcroTrainerAngle($(this).val()); + acroTrainerAngleLimitNumberElement.val($(this).val()); }); acroTrainerAngleLimitNumberElement.val(ADVANCED_TUNING.acroTrainerAngleLimit).change(); diff --git a/src/tabs/pid_tuning.html b/src/tabs/pid_tuning.html index afe4673b9..d1d91db5e 100644 --- a/src/tabs/pid_tuning.html +++ b/src/tabs/pid_tuning.html @@ -340,8 +340,8 @@ - - + + From 498160e829bfcbdae298d77cdadf9a9e3d911401 Mon Sep 17 00:00:00 2001 From: TheIsotopes Date: Sat, 28 Jul 2018 15:29:53 +0200 Subject: [PATCH 038/104] new open source disclaimer @McGiverGim @mikeller superseded #1130 --- locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 82ee8156b..afb992ec7 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -532,7 +532,7 @@ "message": "Open Source / Donation Notice" }, "defaultDonateText": { - "message": "This utility is fully open source and is available free of charge to all Betaflight users.
If you found the Betaflight or Betaflight configurator useful, please consider supporting its development by donating." + "message": "Betaflight is a flight controller software that is open source and is available free of charge without warranty to all users.
If you found the Betaflight or Betaflight configurator useful, please consider supporting its development by donating." }, "defaultDonate": { "message": "Donate" From ccc5296c9a3a5415049f773d3085fecde24465a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kiripolszky=20K=C3=A1roly?= Date: Mon, 30 Jul 2018 21:10:40 +0200 Subject: [PATCH 039/104] reopen next tab when explicitly leaving CLI, otherwise open setup tab --- src/js/gui.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/js/gui.js b/src/js/gui.js index b29d2cc22..c285a9dd0 100644 --- a/src/js/gui.js +++ b/src/js/gui.js @@ -323,7 +323,9 @@ GUI_control.prototype.content_ready = function (callback) { GUI_control.prototype.selectDefaultTabWhenConnected = function() { chrome.storage.local.get(['rememberLastTab', 'lastTab'], function (result) { - if (!(result.rememberLastTab && !!result.lastTab)) { + if (!(result.rememberLastTab + && !!result.lastTab + && result.lastTab.substring(4) != "cli")) { $('#tabs ul.mode-connected .tab_setup a').click(); return; } From 7c3bcef7e8e2c795bfe67c6fe2cd7ec70f5066aa Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 31 Jul 2018 18:13:41 +0100 Subject: [PATCH 040/104] Add vision font from inav --- resources/osd/vision.mcm | 16385 +++++++++++++++++++++++++++++++++++++ 1 file changed, 16385 insertions(+) create mode 100644 resources/osd/vision.mcm diff --git a/resources/osd/vision.mcm b/resources/osd/vision.mcm new file mode 100644 index 000000000..9f95ac518 --- /dev/null +++ b/resources/osd/vision.mcm @@ -0,0 +1,16385 @@ +MAX7456 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01000000 +10100001 +01010101 +00101000 +10100001 +01010101 +00101000 +10100001 +01010000 +00101000 +10100001 +01001010 +00101000 +10100001 +01001010 +00101000 +10100001 +01001010 +00101000 +10100001 +01010000 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100001 +01010101 +01010100 +10100001 +01010101 +01010010 +10100001 +01010101 +01001010 +10100001 +01010101 +00101010 +10100001 +01010101 +00101010 +10100001 +01010101 +01001010 +10100001 +01010101 +01010010 +10100001 +01010101 +01010100 +10100001 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01001000 +01010101 +01010101 +01001010 +00010101 +01010101 +01001010 +10000101 +01010101 +01001010 +10100001 +01010101 +01001010 +10101000 +01010101 +01001010 +10101000 +01010101 +01001010 +10100001 +01010101 +01001010 +10000101 +01010101 +01001010 +00010101 +01010101 +01001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +01010101 +01010101 +00101010 +01010101 +01010100 +10000001 +01010101 +01010110 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +01101001 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +10010101 +01010101 +01000010 +00010101 +01010101 +10101000 +01010101 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010100 +10101010 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +00010101 +01010100 +10000100 +10000101 +01010100 +10000100 +10000101 +01010100 +10000000 +10000101 +01010100 +10000010 +00010101 +01010100 +10000010 +00010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010001 +01000101 +00010001 +10001001 +00100000 +10001000 +10101000 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +10101000 +10101000 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +00010001 +00010001 +00010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000101 +01010101 +01001010 +10100001 +01010101 +01010000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010100 +10101010 +10100001 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000101 +01010101 +01001010 +10100001 +01010101 +01010000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01011010 +10100101 +01010101 +01010100 +01010101 +01010101 +01010010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010010 +10100001 +01010101 +01010010 +10101000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101000 +01010101 +01010010 +10100001 +01010101 +01010010 +10000101 +01010101 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01011010 +10100101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01011010 +10100101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010010 +10000101 +01010101 +01001010 +10000101 +01010101 +00101010 +10000101 +01010100 +10101010 +10000101 +01010101 +00101010 +10000101 +01010101 +01001010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01011010 +10100101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010001 +01010101 +01010100 +10001000 +01010101 +01010100 +10101000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010101 +00010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +00000101 +01001010 +10000010 +10100001 +01001000 +10000010 +00000101 +01001010 +10000010 +00000101 +01010000 +00010010 +10100001 +01010101 +01010010 +00000101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +00000101 +01001010 +10000010 +10100001 +01001000 +10000010 +00000101 +01001010 +10000010 +00010101 +01010000 +00010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +10100001 +01010101 +01010100 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010100 +00000101 +01001010 +10000010 +10100001 +01001000 +00010100 +10000101 +01001000 +00010100 +10000101 +01001010 +10000100 +10000101 +01001000 +00010100 +10000101 +01001000 +01010100 +10000101 +01001000 +01010100 +10000101 +01010001 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101000 +01010101 +01010101 +10000001 +01010101 +01010101 +10000100 +00000101 +00010001 +00010010 +10100000 +10001000 +01010010 +00000100 +10101000 +01010010 +00000100 +10101000 +01010010 +00100000 +10001000 +00010010 +10100000 +10001000 +10000100 +00000101 +00010001 +10000001 +01010101 +01010101 +10101000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00101010 +01010101 +01010101 +01000010 +01000001 +01010001 +01010010 +00101000 +01001000 +01010100 +00100010 +00001000 +01010101 +00101000 +01001000 +01010101 +00100010 +00001000 +00010101 +00101000 +01001010 +10000100 +01000001 +01010000 +00010010 +01010101 +01010101 +01000010 +01010101 +01010101 +00101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00010101 +00000001 +00101010 +10000100 +10101000 +01001010 +00010101 +00100001 +01001010 +10000101 +00100001 +01001000 +10100001 +00100001 +01001000 +00101000 +00100001 +01001000 +01001010 +00100001 +01001000 +01010010 +10100001 +01001000 +01010100 +10100001 +01001000 +01010101 +00100001 +01001000 +01010101 +00100001 +00101010 +00010100 +10101000 +01000000 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01001010 +00000010 +10100001 +01001000 +01010100 +00100001 +01001000 +01010101 +01000101 +01001010 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +10100001 +01000101 +01010101 +00100001 +00100000 +01010101 +00100001 +00101010 +00000000 +10100001 +01001010 +10101010 +10000101 +01010000 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01001010 +00000000 +10100001 +01001000 +01010101 +00000101 +01001000 +01010001 +01010101 +01001000 +00001000 +01010101 +01001010 +10101000 +01010101 +01001000 +00001000 +01010101 +01001000 +01010001 +01000101 +01001000 +01010101 +00100001 +01001010 +00000000 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +01010101 +00000001 +00101010 +00010100 +10101000 +01001000 +01010101 +00100001 +01001000 +01010101 +00100001 +01001000 +01010101 +00100001 +01001000 +01000001 +00100001 +01001000 +00101000 +00100001 +01001010 +00101000 +10100001 +01010010 +00101000 +10000101 +01010010 +10101010 +10000101 +01010100 +10000010 +00010101 +01010100 +10000010 +00010101 +01010101 +00010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01001000 +01010000 +00000000 +00001010 +01001010 +10101010 +10001010 +01001001 +10011001 +10001010 +01001010 +10101010 +10101010 +01001001 +10011001 +10001010 +01001010 +10101010 +10001010 +01010000 +00000000 +00010010 +01010101 +01010101 +01010100 +01010101 +01010101 +00000000 +01010101 +01010101 +10101010 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +01010101 +01010110 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +10100000 +00000000 +00000101 +10100010 +10101010 +10100001 +10100010 +01100110 +01100001 +10101010 +10101010 +10100001 +10100010 +01100110 +01100001 +10100010 +10101010 +10100001 +10000100 +00000000 +00000101 +00010101 +01010101 +01010101 +00000000 +01010101 +01010101 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010101 +10101010 +10010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010000 +00010000 +00010101 +10001010 +10001010 +10000101 +10001000 +10001000 +10000101 +10001000 +10001000 +10000101 +10001000 +10001000 +10000101 +10001010 +10001010 +10000101 +00010000 +00010000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000001 +00000001 +00000001 +10101000 +10101000 +10101000 +10000000 +10001000 +10001000 +10101000 +10001000 +10001000 +00001000 +10001000 +10001000 +10101000 +10101000 +10101000 +00000001 +00000001 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +00000001 +10101000 +00010000 +10101000 +00001000 +10001000 +10000001 +10101000 +10100000 +10101000 +10000000 +10100001 +00001000 +10101000 +10001000 +10101000 +00000001 +00010001 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010001 +01000101 +00010001 +10001000 +00100000 +10001000 +10101000 +10001000 +10001000 +10001000 +10101000 +00100001 +10001000 +10001000 +10001000 +10001000 +10001000 +10001000 +00010001 +00010001 +00010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010101 +01000001 +01001010 +00010101 +00100001 +01001010 +00010100 +10000101 +01010000 +01010010 +00010101 +01010101 +01001000 +01010101 +01010101 +00100001 +01010101 +01010100 +10000101 +00000101 +01010010 +00010100 +10100001 +01001000 +01010100 +10100001 +01000001 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01011010 +10101010 +10101010 +01010000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10100101 +00000000 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010101 +00000101 +01001010 +00010100 +10100001 +01010010 +10000010 +10000101 +01010000 +10101010 +00000101 +01001010 +10101010 +10100001 +01010000 +10101010 +00000101 +01010010 +10000010 +10000101 +01001010 +00010100 +10100001 +01010000 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010100 +00101000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00101000 +00010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001000 +01010101 +01010101 +00101000 +01010101 +01010101 +00100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010101 +01010101 +01001010 +00010101 +01010101 +00101010 +00010101 +01010100 +10101010 +00010101 +01010101 +00001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +00001010 +00000101 +01010100 +10101010 +10100001 +01010100 +10101010 +10100001 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010100 +00010100 +10100001 +01010101 +01010010 +10000101 +01010101 +01001010 +10000101 +01010101 +00101010 +00010101 +01010100 +10101000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10100001 +01010100 +00000000 +10100001 +01010101 +01010000 +10100001 +01010101 +01001010 +10100001 +01010101 +01001010 +10100001 +01010101 +01010000 +10100001 +01010100 +00000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10100001 +01010101 +00000000 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +00000101 +01010010 +10000000 +00010101 +01010010 +10101010 +10000101 +01010100 +10101010 +10100001 +01010101 +00000000 +10100001 +01010100 +00000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010100 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +00000101 +01010010 +10000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +10100001 +01010101 +01010100 +10100001 +01010101 +01010010 +10100001 +01010101 +01010010 +10000101 +01010101 +01001010 +10000101 +01010101 +01001010 +00010101 +01010101 +00101010 +00010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000000 +10100001 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10100001 +01010101 +00000000 +10100001 +01010100 +00000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010010 +10000101 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01010010 +10000101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010010 +00000000 +10000101 +01001000 +00000000 +00100001 +00100000 +10100010 +00001000 +00100010 +00001010 +00001000 +00100010 +00000010 +00001000 +00100010 +00001010 +00001000 +00100000 +10100010 +00100000 +00100000 +00000000 +10000001 +00001000 +00000100 +00000101 +01000010 +00000000 +00100001 +01010000 +10101010 +10000001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +01010101 +01010101 +00101010 +00010101 +01010100 +10101010 +10000101 +01010010 +10100010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000101 +00000101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +00000101 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000010 +10100001 +01010010 +10101010 +10000101 +01010010 +10101010 +00010101 +01010100 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010100 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +00000101 +01010010 +10000000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +00010101 +01010010 +10000000 +01010101 +01010010 +10000000 +00000101 +01010010 +10101010 +10100001 +01010100 +10101010 +10100001 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +00000101 +01010010 +10000101 +01010101 +01010010 +10000000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +00010101 +01010010 +10000000 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010100 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +00000101 +01010010 +10000100 +00000101 +01010010 +10000010 +10100001 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00101000 +00010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010100 +00101000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000101 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010100 +00010100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000010 +10100001 +01010010 +10001010 +10000101 +01010010 +10101010 +00010101 +01010010 +10101000 +01010101 +01010010 +10101010 +00010101 +01010010 +10001010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000000 +00000001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10100010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10001000 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10100000 +10100001 +01010010 +10101000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10001010 +10100001 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010010 +10000000 +00010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000010 +10100001 +01010010 +10001010 +10000101 +01010010 +10101010 +10000101 +01010100 +10101010 +10100001 +01010101 +00000000 +10100001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010010 +10101010 +10100001 +01010010 +10000000 +10100001 +01010010 +10000100 +10100001 +01010010 +10000010 +10000101 +01010010 +10001010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010100 +10101010 +10000101 +01010010 +10101010 +10000101 +01010010 +10000000 +00000101 +01010010 +10000000 +00010101 +01010100 +10101010 +10000101 +01010101 +00000010 +10100001 +01010101 +01010100 +10100001 +01010100 +00000000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000000 +00000101 +01001010 +10101010 +10100001 +01001010 +10101010 +10100001 +01010000 +00101000 +00000101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010100 +10101010 +10000101 +01010101 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +10100010 +10000101 +01010100 +10100010 +10000101 +01010101 +00101010 +00010101 +01010101 +00101010 +00010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000000 +10100001 +01010010 +10001000 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10100010 +10100001 +01010010 +10000100 +10100001 +01010010 +00010101 +00100001 +01010100 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +00000101 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10100010 +10100001 +01010100 +10101010 +10000101 +01010101 +00101010 +00010101 +01010100 +10101010 +10000101 +01010010 +10100010 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010010 +10000100 +10100001 +01010100 +00010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010101 +00000101 +01001010 +00010100 +10100001 +01001010 +00010100 +10100001 +01001010 +10000010 +10100001 +01010010 +10000010 +10000101 +01010010 +10101010 +10000101 +01010100 +10101010 +00010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +10100001 +01010101 +01010010 +10100001 +01010101 +01001010 +10000101 +01010101 +00101010 +00010101 +01010100 +10101000 +01010101 +01010010 +10100000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10000000 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000000 +01010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +10000101 +01010101 +01010100 +10100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010101 +00000010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010101 +00000010 +00010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010100 +10101010 +00010101 +01010010 +10000010 +10000101 +01010010 +00010100 +10000101 +01010100 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000000 +00000101 +01001010 +10101010 +10100001 +01001010 +10101010 +10100001 +01010000 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01000101 +00100001 +01010101 +00100001 +00101000 +01010100 +10100001 +01001010 +00010010 +10000101 +01001010 +10001010 +10000101 +01010010 +10101010 +00010101 +01010010 +10101010 +00010101 +01010100 +10101000 +01010101 +01010100 +10101000 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01000101 +01010100 +10000101 +00100000 +00010010 +10000101 +01001010 +10000010 +10000101 +01010010 +10101010 +10000101 +01010100 +10101010 +10000101 +01010101 +00101010 +10000101 +01010101 +01001010 +10000101 +01010101 +01010010 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01001000 +01010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01000000 +00001010 +10000101 +00101010 +10101010 +10000101 +01001010 +10101010 +10000101 +01010000 +00101010 +10100001 +01010101 +01000000 +10100001 +01010101 +01010101 +00001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010010 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10100001 +01010101 +01010100 +10101000 +01010101 +01010101 +00101010 +00010101 +01010100 +00101010 +10000101 +01000010 +10101010 +10100001 +00101010 +10101010 +10101000 +01000000 +00000000 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +00010101 +01010101 +01001010 +10000001 +01010101 +01000010 +10101000 +00010101 +01010000 +10101010 +10000001 +01010100 +00101010 +10101000 +01010000 +10101010 +10000001 +01000010 +10101000 +00010101 +01001010 +10000001 +01010101 +00101000 +00010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00000000 +00000001 +00101010 +10101010 +10101000 +01000010 +10101010 +10100001 +01010100 +00101010 +10000101 +01010101 +00101010 +00010101 +01010100 +10101000 +01010101 +01010100 +10100001 +01010101 +01010100 +10000101 +01010101 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +00001000 +01010101 +01000000 +10100001 +01010000 +00101010 +10100001 +01001010 +10101010 +10000101 +00101010 +10101010 +10000101 +01000000 +00001010 +10000101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010010 +10000101 +01010101 +01001010 +10000101 +01010101 +00101010 +10000101 +01010100 +10101010 +10000101 +01010010 +10101010 +10000101 +01001010 +10000010 +10000101 +00100000 +00010010 +10000101 +01000101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010100 +10101000 +01010101 +01010100 +10101000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +00010101 +01001010 +10001010 +10000101 +01001010 +00010010 +10000101 +00101000 +01010100 +10100001 +00100001 +01010101 +00100001 +01000101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010010 +10100001 +01010101 +01010010 +10101000 +01010101 +01010010 +10101010 +00010101 +01010010 +10101010 +10000101 +01010010 +10000010 +10100001 +01010010 +10000100 +00001000 +01010010 +00010101 +01010001 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100000 +01010101 +01010101 +01001010 +00000001 +01010101 +01001010 +10101000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10101000 +01010010 +10100000 +00000001 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00000000 +00000001 +00101010 +10101010 +10101000 +01001010 +10101010 +10000001 +01010010 +10101000 +00010101 +01010100 +10101000 +01010101 +01010101 +00101010 +00010101 +01010101 +01001010 +00010101 +01010101 +01010010 +00010101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010100 +00101000 +01010101 +01000010 +10100001 +01010100 +00101010 +10000101 +01000010 +10101010 +00010101 +00101010 +10101000 +01010101 +01000010 +10101010 +00010101 +01010100 +00101010 +10000101 +01010101 +01000010 +10100001 +01010101 +01010100 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010010 +00010101 +01010101 +01001010 +00010101 +01010101 +00101010 +00010101 +01010100 +10101000 +01010101 +01010010 +10101000 +00010101 +01001010 +10101010 +10000001 +00101010 +10101010 +10101000 +01000000 +00000000 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +00100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010010 +10100000 +00000001 +01010010 +10101010 +10101000 +01010010 +10101010 +10100001 +01001010 +10101000 +00000101 +01001010 +00000001 +01010101 +00100000 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010010 +00010101 +01010101 +01010010 +00010101 +01010001 +01010010 +10000100 +00001000 +01010010 +10000010 +10100001 +01010010 +10101010 +10000101 +01010010 +10101010 +00010101 +01010010 +10101000 +01010101 +01010010 +10100001 +01010101 +01010010 +10000101 +01010101 +01010010 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +01010101 +01001010 +10001010 +00010101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001010 +10001000 +10000101 +01010000 +00010000 +00010101 +01001000 +10001010 +00010101 +01001000 +10001000 +10000101 +01001010 +10001010 +00010101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01010001 +00010001 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010001 +01010101 +01001010 +10001000 +01010101 +01001000 +01001000 +01010101 +01001010 +00001000 +01010101 +01001000 +01001000 +00010101 +01001000 +01001010 +10000101 +01010000 +00010000 +00010101 +01001000 +10001010 +00010101 +01001000 +10001000 +10000101 +01001010 +10001010 +00010101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01010001 +00010001 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +00100001 +01010101 +01010100 +10101000 +01010101 +01010010 +10101010 +00010101 +01010100 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000001 +01010101 +01010010 +10101000 +01010101 +01010100 +10101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10100001 +01010101 +01010100 +10101000 +01010101 +01010100 +10100001 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01001000 +01010101 +01010101 +00101000 +01010101 +01010100 +10101000 +01010101 +01010010 +10101000 +01010101 +01010100 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +01010101 +01010010 +10101010 +00010101 +01010100 +10101000 +01010101 +01010101 +00100001 +01010101 +01010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10100001 +01010101 +01010100 +10101000 +01010101 +01010100 +10101010 +00010101 +01010101 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01001000 +01010101 +01010101 +00101000 +01010101 +01010100 +10101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01001000 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010100 +10101010 +00010101 +01010100 +10101000 +01010101 +01010100 +10100001 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +00101000 +01010101 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010010 +10000101 +01010101 +01010100 +10100001 +01010101 +01010101 +00101000 +01010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +01001010 +00010101 +01010101 +00101000 +01010101 +01010100 +10100001 +01010101 +01010010 +10000101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10000101 +01010101 +01010010 +00100001 +01010101 +01001000 +01001000 +01010101 +00100001 +01010010 +00010100 +10000101 +01010100 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +00010101 +01010010 +00010100 +10000101 +01001000 +01010101 +00100001 +00100001 +01010101 +01001000 +10000101 +01010101 +01010010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +00010101 +01010101 +01010100 +10000101 +01010101 +01010100 +10000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00010101 +01010010 +10101010 +10000101 +01010100 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00101010 +01010101 +01010101 +01000010 +01010101 +01010101 +01010010 +01010100 +10000101 +01010100 +01010000 +10000001 +01010101 +01011010 +10101001 +01010101 +01010000 +10000001 +01010101 +01010100 +10000101 +01010100 +01010101 +01010101 +01010010 +01010101 +01010101 +01000010 +01010101 +01010101 +00101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010101 +01010101 +01001010 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001000 +01010101 +01010101 +01001010 +01010101 +01010101 +01010000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +10101010 +10100001 +01010101 +10101010 +10100001 +01010101 +10101010 +10100001 +01010101 +10101010 +10100001 +01010101 +10101010 +10100001 +01010101 +10101010 +10100001 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00000000 +00000000 +00000000 +10101010 +10101010 +10101010 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +10100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +00100001 +01010101 +01010101 +10100001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000101 +01010010 +10000000 +10100001 +01010010 +10101010 +10100001 +01010010 +00101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00101010 +10100001 +01010010 +10101010 +10100001 +01010010 +00000000 +00100001 +01010010 +00100010 +10100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010010 +10001000 +10100001 +01010010 +00100010 +00100001 +01010010 +00100010 +00100001 +01010010 +00000000 +00100001 +01010010 +10101010 +10100001 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101000 +01010101 +01010101 +10000001 +01010101 +01010101 +10000100 +00000101 +00010001 +00010010 +10100000 +10001000 +01010010 +00000000 +10001000 +01010010 +10100000 +10101000 +01010010 +00100001 +00100001 +00010010 +10100001 +00100001 +10000100 +01000101 +01000101 +10000001 +01010101 +01010101 +10101000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +00010101 +01001010 +10001010 +10000101 +01001000 +00010010 +00010101 +01001010 +00010010 +00010101 +01001000 +01010010 +00010101 +01001000 +01010010 +00010101 +01010000 +00000000 +00010101 +01001010 +10101010 +10000101 +01010000 +00000000 +00010101 +01010100 +00101000 +01010101 +01010100 +10000001 +01010101 +01010100 +10101000 +01010101 +01010101 +00001000 +01010101 +01010100 +10101000 +01010101 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +00101000 +01010101 +01010100 +10000010 +00010101 +01010100 +10000010 +00010101 +01010100 +10101010 +00010101 +01010100 +10000010 +00010101 +01010100 +10000010 +00010101 +01010100 +10000010 +00010101 +01010101 +00010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +01010101 +01001010 +10001010 +00010101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001010 +10001000 +10000101 +01010000 +00010000 +00010101 +01001000 +10001010 +00010101 +01001010 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01010001 +00010001 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00010000 +01010101 +01001010 +10001000 +01010101 +01001000 +00001000 +01010101 +01001010 +10001000 +01010101 +01001000 +00001000 +00010101 +01001000 +01001010 +10000101 +01010000 +00010000 +00010101 +01001000 +10001010 +00010101 +01001010 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01001000 +10001000 +10000101 +01010001 +00010001 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101000 +01010101 +01010101 +10000000 +00000101 +01000000 +10000010 +10100001 +00101010 +00010010 +00001000 +01000010 +01010010 +00001000 +01010010 +01010010 +10100000 +01010010 +01010010 +00001000 +01010010 +00010010 +00001000 +01010010 +10000010 +00001000 +01010010 +10000000 +01010001 +01010100 +10101000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00101010 +00000101 +00010100 +01000010 +10100000 +10000010 +00010010 +00000100 +10000010 +00010000 +00010100 +10000010 +00001000 +00010100 +10101010 +00010001 +00010100 +10000010 +00001000 +00010100 +10000010 +00010000 +00010100 +10000010 +00010010 +01010101 +00010100 +01000010 +01010101 +01010101 +00101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010001 +01010101 +01010100 +10001000 +01010101 +01010100 +10101000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010100 +10001000 +01010101 +01010000 +00000000 +00010101 +01001010 +10101010 +10000101 +01010000 +00000000 +00010101 +01010100 +00101000 +01010101 +01010100 +10000001 +01010101 +01010100 +10101000 +01010101 +01010101 +00001000 +01010101 +01010100 +10101000 +01010101 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000001 +01010101 +01010101 +01010000 +00010101 +01010101 +01010000 +00000101 +01010101 +01010000 +00000000 +01010101 +01010100 +01010000 +00000101 +01010100 +00010101 +00000000 +01010101 +00010101 +01010000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +00000101 +01010100 +01000000 +00000101 +01010101 +01010000 +00000101 +01010101 +01010000 +00000001 +01010101 +01010100 +01010101 +01010101 +01010100 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00000101 +01010101 +01010101 +01000001 +01010101 +01010101 +01010001 +01010101 +01010101 +01010000 +01010101 +01010101 +01010100 +01010101 +01010101 +01010100 +00010101 +01010101 +01010101 +00000101 +01010101 +01010101 +01000101 +01010101 +01010101 +01010000 +01010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000001 +01010101 +01010101 +01000000 +00010101 +01010101 +01010100 +00000001 +01010101 +01010101 +01000000 +00010101 +01010101 +01010000 +00000101 +01010101 +01010101 +00000000 +01010101 +01010101 +01010000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010101 +01000001 +01010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +00000000 +01010101 +01010101 +01010000 +00010101 +01010101 +01010100 +00000001 +01010101 +01010101 +01000000 +00010101 +01010101 +01010100 +00000001 +00010101 +01010101 +01000000 +00000000 +01010101 +01010100 +01010000 +00000101 +01010100 +01010101 +00000000 +01010100 +01010101 +01010000 +00001010 +01010101 +01010010 +00101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +01010000 +01010101 +01010101 +01010000 +01010101 +01010101 +00000000 +01010101 +01010100 +00000000 +00010101 +01010100 +00000000 +00000101 +01010100 +00000000 +10101010 +01010100 +00000000 +00101010 +00000000 +00000000 +10101010 +10000000 +00000000 +10100000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000101 +01010101 +01010101 +00000001 +01010101 +01010101 +00000000 +00010101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000001 +01010101 +00000001 +01000000 +01010101 +00000101 +01010100 +00010101 +00000101 +01010101 +00000101 +00000001 +01010101 +01000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10100101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10010101 +01100101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01011001 +01010101 +01011010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010110 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000000 +01010101 +01010101 +01000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00000000 +10101010 +00000000 +00000110 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +01101010 +01010101 +01010101 +01101010 +01010101 +01010101 +01000000 +01010101 +01010100 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000000 +01010101 +00100000 +00000000 +01010101 +10101010 +00100000 +01010101 +10101010 +10101010 +01010101 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10100000 +00000000 +00000000 +10000000 +00000000 +00000000 +10000000 +00000000 +00000101 +10000000 +00000000 +00000101 +10000000 +00000000 +00010101 +10000000 +00000000 +00010101 +10100000 +00000001 +01010101 +10000000 +00000101 +01010101 +00000000 +01010101 +01010101 +00000000 +00010101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000000 +01010101 +00000000 +00000000 +00000101 +00000000 +00000000 +00000001 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +10000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +01010101 +01010001 +00000000 +00000101 +01010000 +00000000 +00000000 +00010000 +01010000 +00000000 +00000000 +01010101 +01010101 +01010000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00000001 +01010101 +01010101 +00000000 +00000101 +00000000 +00000000 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010000 +01010101 +01010101 +00000001 +01010101 +01010101 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010110 +01010101 +01010101 +01010110 +01010101 +01010101 +01010110 +01010101 +01010101 +01011010 +01010101 +01010101 +01011010 +01010101 +01010101 +01011010 +01010101 +01010101 +01101010 +01010101 +01010101 +01101010 +01010101 +01010101 +01101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010110 +10101010 +01010101 +01010110 +10101010 +01010101 +01010110 +10101010 +01010101 +01011010 +10101010 +01010101 +01011010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10010101 +01011010 +10101010 +10010101 +01010110 +10101010 +01010101 +01010110 +10101010 +01010101 +01011010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10100101 +01010101 +01101010 +10100101 +01010101 +01101010 +10010101 +01010101 +01101010 +10010101 +01010101 +10101010 +10010101 +01011010 +10101010 +10101010 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10010101 +01010110 +10101010 +10010101 +01010110 +10101010 +10100101 +01010110 +10101010 +10010101 +01011010 +10101010 +10010101 +01011010 +10101010 +10010101 +01011010 +10101010 +01010101 +01101010 +10101001 +01010101 +01101010 +10100101 +01010101 +01101010 +10100101 +01010101 +10101010 +10100101 +01010101 +10101010 +10101001 +01010101 +10101010 +10101001 +01010110 +10101010 +10101001 +01010110 +10101010 +10101001 +01011010 +10101010 +10101001 +01011010 +10101010 +10100101 +01011010 +10101010 +10100101 +01101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +01010101 +01010101 +10101001 +01010101 +01010101 +10101001 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10010101 +01010101 +01010101 +10010101 +01010101 +01010101 +10010101 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10010101 +10101010 +10101010 +10010101 +10101010 +10101010 +10010110 +10101010 +10101010 +01010110 +10101010 +10101010 +01010110 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10100101 +01010101 +01010101 +10010101 +01010101 +01010110 +10010101 +01010101 +01010110 +01010101 +01010101 +01010110 +01010101 +01010101 +01011010 +01010101 +01010101 +01011010 +01010101 +01010101 +01101010 +01010101 +01010101 +01101010 +01010101 +01010101 +01101010 +01010101 +01010101 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +01101010 +10101001 +01010101 +10101010 +10101001 +01010101 +10101010 +10100101 +01010101 +10101010 +10100101 +01010101 +10101010 +10100101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010110 +10101001 +01010101 +01010110 +10101001 +01010101 +01011010 +10101001 +01010101 +01101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101001 +01010101 +01101010 +10101001 +01010101 +01101010 +10100101 +01010101 +10101010 +10100101 +01010110 +10101010 +10100101 +01011010 +10101010 +01010101 +01011010 +10101010 +01010101 +01101010 +10101010 +01010101 +10101010 +10101010 +01010101 +10101010 +10010110 +01010110 +10101010 +10010110 +01011010 +10101010 +01010110 +01011010 +10101001 +01010110 +01101010 +10101001 +01010110 +10101010 +10100101 +01010110 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010101 +10101010 +10010101 +01010100 +10101010 +10010101 +01010100 +10101010 +10010101 +01010100 +10101010 +10010101 +01010000 +10101010 +10010101 +01010000 +10101010 +10010101 +01010000 +10101010 +10010101 +01000000 +10101010 +10010101 +01000000 +10101010 +10010101 +01000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +00000000 +01010000 +00000000 +00000000 +01010000 +00000000 +00000000 +01010000 +00000000 +00000000 +01000000 +00000000 +00000000 +01000000 +00000001 +01010101 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +00010101 +01010101 +00000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000001 +01010101 +01010101 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000001 +01010100 +00000000 +00000001 +01010000 +00000000 +00000001 +01010000 +00000000 +00000101 +01000000 +00000000 +00000101 +01000000 +01010101 +01010101 +01000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000000 +00000001 +01010101 +00000000 +00000001 +01010100 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +00000000 +00000101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010101 +00000000 +00010101 +01010101 +00000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000001 +01010101 +01010101 +00000001 +01010101 +01010101 +00000101 +01010101 +01010101 +00000101 +01010101 +01010101 +00000101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +00000000 +00010101 +01010000 +00000000 +00010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010100 +01000000 +00000001 +01010100 +01000000 +00000001 +01010100 +00000000 +00000001 +01010100 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +01010101 +01010100 +00000000 +01010101 +01000000 +00000000 +01010101 +00000000 +00000000 +01010100 +00000000 +00000001 +01010100 +00000000 +00000101 +01010000 +00000000 +00010101 +01000000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000001 +01010101 +00000000 +00000000 +01010101 +00000000 +00000000 +00000000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +00000000 +00000000 +00000101 +00000000 +00000000 +00000101 +01010100 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00000000 +00000101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +00000000 +00000001 +01010100 +00000000 +00000001 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +00000000 +00010101 +01010100 +00000000 +00000000 +01010000 +00000000 +00000000 +01010000 +00000000 +00000000 +01010000 +00000000 +00000000 +01000000 +00000000 +00000000 +01000000 +00000000 +00000000 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010100 +00000000 +01010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +01000000 +00000001 +00000000 +00000000 +00000101 +00000000 +00000000 +00000101 +00000000 +00000000 +00000101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +00000000 +00000000 +00010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +01000000 +00000001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +00000000 +00000000 +00010100 +00000000 +00000000 +01010100 +00000000 +00000000 +01010100 +00000000 +00000000 +01010000 +00000000 +00000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000000 +01010101 +01010101 +00000000 +01010101 +01010100 +00000000 +01010101 +01010100 +00000000 +01010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01010000 +00000000 +01010101 +01000000 +00000000 +01010101 +01000000 +00000001 +01010101 +01000000 +00000001 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000001 +00000000 +00000000 +00000101 +00000000 +00000000 +00000101 +00000000 +00000000 +00000101 +00000000 +00000000 +00010101 +00000001 +01010101 +01010101 +00000101 +01010101 +01010101 +00000101 +01010101 +01010101 +00000101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +01010101 +00100010 +10100000 +01010101 +01101000 +00000000 +01010101 +01000000 +00000010 +01010101 +01010000 +00101000 +01010101 +01010100 +00101010 +01010101 +01010101 +00101010 +01010101 +01010101 +01010110 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00100000 +00000000 +00001000 +10100000 +00000000 +00100010 +10000000 +00000000 +10101010 +10100000 +00000000 +10101010 +00000000 +00000010 +10101010 +10000000 +00101010 +10101000 +10000000 +10001010 +10101000 +00000000 +00001001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +01010100 +00000000 +00000000 +01010000 +00000000 +00000000 +00000101 +00000000 +00000000 +00010101 +00000000 +00000001 +01010101 +00000000 +00010101 +01010101 +10000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01011010 +10101010 +01010101 +01101010 +10101010 +01010101 +01101010 +10101010 +01010101 +01101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10101010 +10100101 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10010101 +01101010 +10101010 +01010101 +01101010 +10101010 +01010101 +10101010 +10101010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10101010 +10101001 +10101010 +10101010 +10101001 +10101010 +10101010 +10101001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +01010101 +01010101 +10101010 +01010101 +01010110 +10101010 +01010101 +01010110 +10010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10100101 +01010101 +01101010 +10100101 +01010101 +10101010 +10100101 +01010110 +10101010 +10010101 +01010110 +01010110 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101001 +01010101 +01011010 +10100101 +01010101 +01011010 +10100101 +01010101 +01011010 +10010101 +01010101 +01011010 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +10101010 +10010101 +00000000 +10101010 +10010101 +00000000 +10101010 +10010101 +00000000 +01010110 +10010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000001 +01010101 +01010101 +00000101 +01010101 +01010101 +00000101 +01010101 +01010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +01010101 +00000000 +00000000 +01010100 +00000000 +00000000 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +01010100 +00000000 +00000000 +01010100 +00000000 +00000000 +01010000 +01010101 +01010001 +01010000 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010101 +00000000 +00010101 +01010101 +00000000 +00010101 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +01010000 +00000000 +00000000 +01010100 +00000000 +00000101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000001 +01010100 +00000000 +00000101 +01010000 +01010000 +00000101 +01010000 +01010001 +00010101 +01010001 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00010101 +01010101 +00000000 +00010101 +01010101 +00000000 +01010101 +01010100 +01010100 +01010101 +01010100 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000001 +01010101 +00000000 +00000101 +01010101 +00000000 +00000101 +01010101 +00010101 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +00000000 +00000101 +01010100 +00000000 +00000101 +01010100 +00000000 +00010101 +01010100 +01010100 +00010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 +01010101 \ No newline at end of file From 8b59d051072bde27ba6ffbc50201114926c02bb8 Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 31 Jul 2018 21:21:16 +0100 Subject: [PATCH 041/104] Added vision font to OSD tab. --- src/js/tabs/osd.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 8e40d93b8..a66151f12 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -913,7 +913,8 @@ OSD.constants = { { file: "extra_large", name: "Extra Large" }, { file: "betaflight", name: "Betaflight" }, { file: "digital", name: "Digital" }, - { file: "clarity", name: "Clarity" } + { file: "clarity", name: "Clarity" }, + { file: "vision", name: "Vision" } ] }; From 4d582f45c8ad705545cecca697f0c3e96c6a90eb Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Tue, 31 Jul 2018 21:57:47 +0100 Subject: [PATCH 042/104] Change Extra Large font name to X-Large to fix UI overflow. --- src/js/tabs/osd.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index a66151f12..51ff10213 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -910,7 +910,7 @@ OSD.constants = { { file: "default", name: "Default" }, { file: "bold", name: "Bold" }, { file: "large", name: "Large" }, - { file: "extra_large", name: "Extra Large" }, + { file: "extra_large", name: "X-Large" }, { file: "betaflight", name: "Betaflight" }, { file: "digital", name: "Digital" }, { file: "clarity", name: "Clarity" }, From 3d1ad1088f038bc04fd16b2c7623eeebd769d116 Mon Sep 17 00:00:00 2001 From: mikeller Date: Wed, 1 Aug 2018 21:22:12 +1200 Subject: [PATCH 043/104] Removed cleaning steps from 'debug' build. --- gulpfile.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 9b2107735..91e8ec9b1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -60,13 +60,14 @@ gulp.task('clean-release', clean_release); gulp.task('clean-cache', clean_cache); -var distBuild = gulp.series(clean_dist, dist_src, dist_locale, dist_libraries, dist_resources); -gulp.task('dist', distBuild); +var distBuild = gulp.series(dist_src, dist_locale, dist_libraries, dist_resources); +var distRebuild = gulp.series(clean_dist, distBuild); +gulp.task('dist', distRebuild); -var appsBuild = gulp.series(gulp.parallel(clean_apps, distBuild), apps, gulp.parallel(listPostBuildTasks(APPS_DIR))); +var appsBuild = gulp.series(gulp.parallel(clean_apps, distRebuild), apps, gulp.parallel(listPostBuildTasks(APPS_DIR))); gulp.task('apps', appsBuild); -var debugBuild = gulp.series(gulp.parallel(clean_debug, distBuild), debug, gulp.parallel(listPostBuildTasks(DEBUG_DIR)), start_debug) +var debugBuild = gulp.series(distBuild, debug, gulp.parallel(listPostBuildTasks(DEBUG_DIR)), start_debug) gulp.task('debug', debugBuild); var releaseBuild = gulp.series(gulp.parallel(clean_release, appsBuild), gulp.parallel(listReleaseTasks())); From 40cf5667710a2ede2bbdc0ef3b0ab3de3169ab5e Mon Sep 17 00:00:00 2001 From: Richard Cooper Date: Wed, 1 Aug 2018 22:46:51 +0100 Subject: [PATCH 044/104] Change font presets to new dropdown UI. --- src/css/tabs/osd.css | 6 +++++- src/js/tabs/osd.js | 34 +++++++++++++++++++--------------- src/tabs/osd.html | 6 +++++- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/css/tabs/osd.css b/src/css/tabs/osd.css index d45af866e..6084a4f66 100644 --- a/src/css/tabs/osd.css +++ b/src/css/tabs/osd.css @@ -402,13 +402,17 @@ button { cursor: pointer; } -.fontbuttons { +.fontpresets_wrapper { display: inline-block; position: absolute; right: 1.2em; top: .8em; } +.fontpresets { + border: 1px solid #cccccc; +} + .tab-osd .switchable-field { padding: 3px; border: 1px solid transparent; diff --git a/src/js/tabs/osd.js b/src/js/tabs/osd.js index 51ff10213..7c84282d2 100755 --- a/src/js/tabs/osd.js +++ b/src/js/tabs/osd.js @@ -910,7 +910,7 @@ OSD.constants = { { file: "default", name: "Default" }, { file: "bold", name: "Bold" }, { file: "large", name: "Large" }, - { file: "extra_large", name: "X-Large" }, + { file: "extra_large", name: "Extra Large" }, { file: "betaflight", name: "Betaflight" }, { file: "digital", name: "Digital" }, { file: "clarity", name: "Clarity" }, @@ -1471,17 +1471,18 @@ TABS.osd.initialize = function (callback) { } $('#content').load("./tabs/osd.html", function () { - - // Generate font type buttons - var fontbuttons = $('.fontbuttons'); + // Generate font type select element + var fontselect = $('.fontpresets'); OSD.constants.FONT_TYPES.forEach(function(e, i) { - var button = $('
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
+ + +
+ +
+
+
+
+ + +
+ +
+
+
+
+
+ +
+
+
+ + +
+ +
+
+
+
+
+ +
+
+
+ + +
+ +
+
+
+
+ + +
+ +
+
+
+
+
From 402863837ce15baafd7d56661d8e848b0c6aef78 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Tue, 7 Aug 2018 11:07:04 +0300 Subject: [PATCH 048/104] Fixed caching for Jenkins, added enumeration of Firmware view --- locales/en/messages.json | 11 ++- src/js/jenkins_loader.js | 127 ++++++++++++++++++++++---------- src/js/tabs/firmware_flasher.js | 32 ++++---- 3 files changed, 117 insertions(+), 53 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index b9a7a9b46..bcc0f6940 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -389,6 +389,15 @@ "message" : "Running - OS: {{operatingSystem}}, Chrome: {{chromeVersion}}, Configurator: {{configuratorVersion}}", "description": "Message that appears in the GUI log panel indicating operating system, Chrome version and Configurator version" }, + "buildServerLoaded": { + "message" : "Loaded builds information for $1 from build server." + }, + "buildServerLoadFailed": { + "message" : "Build server query for $1 releases failed, using cached information. Reason: $2" + }, + "buildServerUsingCached": { + "message" : "Using cached builds information for $1." + }, "releaseCheckLoaded": { "message" : "Loaded release information for $1 from GitHub." }, @@ -2242,7 +2251,7 @@ "message": "Baud Rate" }, "firmwareFlasherShowDevelopmentReleases":{ - "message": "Show unstable releases" + "message": "Show unstable and additional releases" }, "firmwareFlasherShowDevelopmentReleasesDescription":{ "message": "Show Release-Candidates and Development Releases." diff --git a/src/js/jenkins_loader.js b/src/js/jenkins_loader.js index 8cdf040f8..67497b7ad 100644 --- a/src/js/jenkins_loader.js +++ b/src/js/jenkins_loader.js @@ -1,66 +1,118 @@ 'use strict;' -var JenkinsLoader = function (url, jobName) { +var JenkinsLoader = function (url) { + this._url = url; + this._jobs = []; + this._cacheExpirationPeriod = 3600 * 1000; + + this._jobsRequest = '/api/json?tree=jobs[name]'; + this._buildsRequest = '/api/json?tree=builds[number,result,timestamp,artifacts[relativePath],changeSet[items[commitId,msg]]]'; +} + +JenkinsLoader.prototype.loadJobs = function (viewName, callback) { var self = this; - - self._url = url; - self._jobName = jobName; - self._jobUrl = self._url + '/job/' + self._jobName; - self._buildsRequest = '/api/json?tree=builds[number,result,timestamp,artifacts[relativePath],changeSet[items[commitId,msg]]]'; - self._builds = {}; - - self._buildsDataTag = `${self._jobUrl}BuildsData`; - self._cacheLastUpdateTag = `${self._jobUrl}BuildsLastUpdate` + + var viewUrl = `${self._url}/view/${viewName}`; + var jobsDataTag = '${viewUrl}JobsData'; + var cacheLastUpdateTag = '${viewUrl}JobsLastUpdate'; + + var wrappedCallback = jobs => { + self._jobs = jobs; + callback(jobs); + }; + + chrome.storage.local.get([cacheLastUpdateTag, jobsDataTag], function (result) { + var jobsDataTimestamp = $.now(); + var cachedJobsData = result[jobsDataTag]; + var cachedJobsLastUpdate = result[cacheLastUpdateTag]; + + if (!cachedJobsData || !cachedJobsLastUpdate || jobsDataTimestamp - cachedJobsLastUpdate > self._cacheExpirationPeriod) { + var url = `${viewUrl}${self._jobsRequest}`; + + $.get(url, jobsInfo => { + GUI.log(i18n.getMessage('buildServerLoaded', ['jobs'])); + + // remove Betaflight prefix, rename Betaflight job to Development + var jobs = jobsInfo.jobs.map(job => { + return { title: job.name.replace('Betaflight ', '').replace('Betaflight', 'Development'), name: job.name }; + }) + + // cache loaded info + object = {} + object[jobsDataTag] = jobs; + object[cacheLastUpdateTag] = $.now(); + chrome.storage.local.set(object); + + wrappedCallback(jobs); + }).error(xhr => { + GUI.log(i18n.getMessage('buildServerLoadFailed', ['jobs', `HTTP ${xhr.status}`])); + }).fail(() => wrappedCallback([])); + } else { + if (cachedJobsData) { + GUI.log(i18n.getMessage('buildServerUsingCached', ['jobs'])); + } + + wrappedCallback(cachedJobsData); + } + }); } -JenkinsLoader.prototype.loadBuilds = function (callback) { +JenkinsLoader.prototype.loadBuilds = function (jobName, callback) { var self = this; - chrome.storage.local.get([self._cacheLastUpdateTag, self._buildsDataTag], function (result) { + var jobUrl = `${self._url}/job/${jobName}`; + var buildsDataTag = `${jobUrl}BuildsData`; + var cacheLastUpdateTag = `${jobUrl}BuildsLastUpdate` + + chrome.storage.local.get([cacheLastUpdateTag, buildsDataTag], function (result) { var buildsDataTimestamp = $.now(); - var cachedBuildsData = result[self._buildsDataTag]; - var cachedBuildsLastUpdate = result[self._cacheLastUpdateTag]; + var cachedBuildsData = result[buildsDataTag]; + var cachedBuildsLastUpdate = result[cacheLastUpdateTag]; - if (!cachedBuildsData || !cachedBuildsLastUpdate || buildsDataTimestamp - cachedBuildsLastUpdate > 3600 * 1000) { - var request = self._jobUrl + self._buildsRequest; + if (!cachedBuildsData || !cachedBuildsLastUpdate || buildsDataTimestamp - cachedBuildsLastUpdate > self._cacheExpirationPeriod) { + var url = `${jobUrl}${self._buildsRequest}`; + + $.get(url, function (buildsInfo) { + GUI.log(i18n.getMessage('buildServerLoaded', [jobName])); - $.get(request, function (buildsInfo) { // filter successful builds - self._builds = buildsInfo.builds.filter(build => build.result == 'SUCCESS') + var builds = buildsInfo.builds.filter(build => build.result == 'SUCCESS') .map(build => ({ number: build.number, artifacts: build.artifacts.map(artifact => artifact.relativePath), changes: build.changeSet.items.map(item => '* ' + item.msg).join('
\n'), - date: new Date(build.timestamp) + timestamp: build.timestamp })); - self._parseBuilds(callback); - }).fail(function (data) { - GUI.log(i18n.getMessage('releaseCheckFailed', [self._jobName, 'failed to load builds'])); - - self._builds = cachedBuildsData; - self._parseBuilds(callback); + // cache loaded info + object = {} + object[buildsDataTag] = builds; + object[cacheLastUpdateTag] = $.now(); + chrome.storage.local.set(object); + + self._parseBuilds(jobUrl, jobName, builds, callback); + }).error(xhr => { + GUI.log(i18n.getMessage('buildServerLoadFailed', [jobName, `HTTP ${xhr.status}`])); + }).fail(() => { + self._parseBuilds(jobUrl, jobName, [], callback); }); } else { if (cachedBuildsData) { - GUI.log(i18n.getMessage('releaseCheckCached', [self._jobName])); + GUI.log(i18n.getMessage('buildServerUsingCached', [jobName])); } - self._builds = cachedBuildsData; - self._parseBuilds(callback); + self._parseBuilds(jobUrl, jobName, cachedBuildsData, callback); } }); } -JenkinsLoader.prototype._parseBuilds = function (callback) { - var self = this; - +JenkinsLoader.prototype._parseBuilds = function (jobUrl, jobName, builds, callback) { // convert from `build -> targets` to `target -> builds` mapping var targetBuilds = {}; var targetFromFilenameExpression = /betaflight_([\d.]+)?_?(\w+)(\-.*)?\.(.*)/; - self._builds.forEach(build => { + builds.forEach(build => { build.artifacts.forEach(relativePath => { var match = targetFromFilenameExpression.exec(relativePath); @@ -70,15 +122,16 @@ JenkinsLoader.prototype._parseBuilds = function (callback) { var version = match[1]; var target = match[2]; + var date = new Date(build.timestamp); - var formattedDate = ("0" + build.date.getDate()).slice(-2) + "-" + ("0" + (build.date.getMonth()+1)).slice(-2) + "-" + - build.date.getFullYear() + " " + ("0" + build.date.getHours()).slice(-2) + ":" + ("0" + build.date.getMinutes()).slice(-2); + var formattedDate = ("0" + date.getDate()).slice(-2) + "-" + ("0" + (date.getMonth()+1)).slice(-2) + "-" + + date.getFullYear() + " " + ("0" + date.getHours()).slice(-2) + ":" + ("0" + date.getMinutes()).slice(-2); var descriptor = { - 'releaseUrl': self._jobUrl + '/' + build.number, - 'name' : self._jobName + ' #' + build.number, + 'releaseUrl': jobUrl + '/' + build.number, + 'name' : jobName + ' #' + build.number, 'version' : version + ' #' + build.number, - 'url' : self._jobUrl + '/' + build.number + '/artifact/' + relativePath, + 'url' : jobUrl + '/' + build.number + '/artifact/' + relativePath, 'file' : relativePath.split('/').slice(-1)[0], 'target' : target, 'date' : formattedDate, diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index a518fbf58..f88640441 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -2,7 +2,8 @@ TABS.firmware_flasher = { releases: null, - releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases') + releaseChecker: new ReleaseChecker('firmware', 'https://api.github.com/repos/betaflight/betaflight/releases'), + jenkinsLoader: new JenkinsLoader('https://ci.betaflight.tech') }; TABS.firmware_flasher.initialize = function (callback) { @@ -28,7 +29,7 @@ TABS.firmware_flasher.initialize = function (callback) { : "normal"); } - $('#content').load("./tabs/firmware_flasher.html", function () { + function onDocumentLoad() { FirmwareCache.load(); FirmwareCache.onPutToCache(onFirmwareCacheUpdate); FirmwareCache.onRemoveFromCache(onFirmwareCacheUpdate); @@ -243,24 +244,21 @@ TABS.firmware_flasher.initialize = function (callback) { { tag: 'firmwareFlasherOptionLabelBuildTypeReleaseCandidate', loader: () => self.releaseChecker.loadReleaseData(releaseData => buildBoardOptions(releaseData, true)) - }, - { - tag: 'firmwareFlasherOptionLabelBuildTypeDevelopment', - loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight').loadBuilds(buildJenkinsBoardOptions) - }, - { - tag: 'firmwareFlasherOptionLabelBuildTypeAKK3_3', - loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight Maintenance 3.3 (AKK - RDQ VTX Patch)').loadBuilds(buildJenkinsBoardOptions) - }, - { - tag: 'firmwareFlasherOptionLabelBuildTypeAKK3_4', - loader: () => new JenkinsLoader('https://ci.betaflight.tech', 'Betaflight Maintenance 3.4 (AKK - RDQ VTX Patch)').loadBuilds(buildJenkinsBoardOptions) } ]; + var ciBuildsTypes = self.jenkinsLoader._jobs.map(job => { + return { + title: job.title, + loader: () => self.jenkinsLoader.loadBuilds(job.name, buildJenkinsBoardOptions) + }; + }) + + buildTypes = buildTypes.concat(ciBuildsTypes); + var buildType_e = $('select[name="build_type"]'); buildTypes.forEach((build, index) => { - buildType_e.append($("".format(index, i18n.getMessage(build.tag)))) + buildType_e.append($("".format(index, build.tag ? i18n.getMessage(build.tag) : build.title))) }); showOrHideBuildTypeSelect(); @@ -626,6 +624,10 @@ TABS.firmware_flasher.initialize = function (callback) { }); GUI.content_ready(callback); + } + + self.jenkinsLoader.loadJobs('Firmware', () => { + $('#content').load("./tabs/firmware_flasher.html", onDocumentLoad); }); }; From b3ca039b9a0bc7d8fd50de6a8c2e03ee33fae936 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Tue, 7 Aug 2018 11:21:08 +0300 Subject: [PATCH 049/104] Allowed using cached CI info after timeout when GET fails --- src/js/jenkins_loader.js | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/js/jenkins_loader.js b/src/js/jenkins_loader.js index 67497b7ad..209fb642b 100644 --- a/src/js/jenkins_loader.js +++ b/src/js/jenkins_loader.js @@ -26,6 +26,14 @@ JenkinsLoader.prototype.loadJobs = function (viewName, callback) { var cachedJobsData = result[jobsDataTag]; var cachedJobsLastUpdate = result[cacheLastUpdateTag]; + var cachedCallback = () => { + if (cachedJobsData) { + GUI.log(i18n.getMessage('buildServerUsingCached', ['jobs'])); + } + + wrappedCallback(cachedJobsData ? cachedJobsData : []); + }; + if (!cachedJobsData || !cachedJobsLastUpdate || jobsDataTimestamp - cachedJobsLastUpdate > self._cacheExpirationPeriod) { var url = `${viewUrl}${self._jobsRequest}`; @@ -46,13 +54,9 @@ JenkinsLoader.prototype.loadJobs = function (viewName, callback) { wrappedCallback(jobs); }).error(xhr => { GUI.log(i18n.getMessage('buildServerLoadFailed', ['jobs', `HTTP ${xhr.status}`])); - }).fail(() => wrappedCallback([])); + }).fail(cachedCallback); } else { - if (cachedJobsData) { - GUI.log(i18n.getMessage('buildServerUsingCached', ['jobs'])); - } - - wrappedCallback(cachedJobsData); + cachedCallback(); } }); } @@ -69,6 +73,14 @@ JenkinsLoader.prototype.loadBuilds = function (jobName, callback) { var cachedBuildsData = result[buildsDataTag]; var cachedBuildsLastUpdate = result[cacheLastUpdateTag]; + var cachedCallback = () => { + if (cachedBuildsData) { + GUI.log(i18n.getMessage('buildServerUsingCached', [jobName])); + } + + self._parseBuilds(jobUrl, jobName, cachedBuildsData ? cachedBuildsData : [], callback); + }; + if (!cachedBuildsData || !cachedBuildsLastUpdate || buildsDataTimestamp - cachedBuildsLastUpdate > self._cacheExpirationPeriod) { var url = `${jobUrl}${self._buildsRequest}`; @@ -93,15 +105,9 @@ JenkinsLoader.prototype.loadBuilds = function (jobName, callback) { self._parseBuilds(jobUrl, jobName, builds, callback); }).error(xhr => { GUI.log(i18n.getMessage('buildServerLoadFailed', [jobName, `HTTP ${xhr.status}`])); - }).fail(() => { - self._parseBuilds(jobUrl, jobName, [], callback); - }); + }).fail(cachedCallback); } else { - if (cachedBuildsData) { - GUI.log(i18n.getMessage('buildServerUsingCached', [jobName])); - } - - self._parseBuilds(jobUrl, jobName, cachedBuildsData, callback); + cachedCallback(); } }); } From 3498943db46894829efa85c8543cb184f0c71677 Mon Sep 17 00:00:00 2001 From: Sean M Date: Tue, 7 Aug 2018 19:51:49 -0400 Subject: [PATCH 050/104] UI Updates --- src/css/tabs/receiver.css | 18 +++++++++++++++++- src/js/tabs/receiver.js | 4 ++++ src/tabs/receiver.html | 34 ++++++++++++++-------------------- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/css/tabs/receiver.css b/src/css/tabs/receiver.css index 9f17043f6..a577fad29 100644 --- a/src/css/tabs/receiver.css +++ b/src/css/tabs/receiver.css @@ -326,7 +326,23 @@ width: calc(100% - 8px); } -.tab-receiver .rcSmoothing-type select { +.tab-receiver .rcSmoothing-input-manual select { + height: 22px; + padding-left: 5px; + border: 1px solid silver; + margin: 4px; + width: calc(100% - 8px); +} + +.tab-receiver .rc-smoothing-type { + margin-bottom: 5px; + clear: left; + padding-bottom: 5px; + border-bottom: 1px solid silver; + width: 100%; +} + +.tab-receiver .rc-smoothing-type select { height: 22px; padding-left: 5px; border: 1px solid silver; diff --git a/src/js/tabs/receiver.js b/src/js/tabs/receiver.js index 26f323e83..e550726c9 100644 --- a/src/js/tabs/receiver.js +++ b/src/js/tabs/receiver.js @@ -341,9 +341,11 @@ TABS.receiver.initialize = function (callback) { $('.tab-receiver .rcSmoothing-input-cutoff').show(); $('select[name="rcSmoothing-input-manual-select"]').val("1"); + $('.tab-receiver .rc-smoothing-input-blank').hide(); if (RX_CONFIG.rcSmoothingInputCutoff == 0) { $('.tab-receiver .rcSmoothing-input-cutoff').hide(); $('select[name="rcSmoothing-input-manual-select"]').val("0"); + $('.tab-receiver .rc-smoothing-input-blank').show(); } $('select[name="rcSmoothing-input-manual-select"]').change(function () { if ($(this).val() == 0) { @@ -358,9 +360,11 @@ TABS.receiver.initialize = function (callback) { $('.tab-receiver .rcSmoothing-derivative-cutoff').show(); $('select[name="rcSmoothing-input-derivative-select"]').val("1"); + $('.tab-receiver .rc-smoothing-derivative-blank').hide(); if (RX_CONFIG.rcSmoothingDerivativeCutoff == 0) { $('select[name="rcSmoothing-input-derivative-select"]').val("0"); $('.tab-receiver .rcSmoothing-derivative-cutoff').hide(); + $('.tab-receiver .rc-smoothing-derivative-blank').show(); } $('select[name="rcSmoothing-input-derivative-select"]').change(function () { if ($(this).val() == 0) { diff --git a/src/tabs/receiver.html b/src/tabs/receiver.html index 3478a5987..5ed1d2568 100644 --- a/src/tabs/receiver.html +++ b/src/tabs/receiver.html @@ -117,10 +117,10 @@
- + - - + - - - - - - - - + + - - - - - + + - - - -
+
+ +
+
@@ -201,13 +198,11 @@ +
+
@@ -230,12 +226,10 @@ +
+
-
+
@@ -214,7 +214,7 @@ + + + + +
-
+ +
+ +
+
+
+
+ +
+
+
From b08d905d11bb6ad055b56d69b7ea6a34a6cbd8b3 Mon Sep 17 00:00:00 2001 From: Andrey Mironov Date: Wed, 8 Aug 2018 14:00:59 +0300 Subject: [PATCH 052/104] Added betaflight.tech to permissions --- manifest.json | 1 + 1 file changed, 1 insertion(+) diff --git a/manifest.json b/manifest.json index ab6e42263..9025484dc 100755 --- a/manifest.json +++ b/manifest.json @@ -23,6 +23,7 @@ "https://*.githubusercontent.com/", "http://*.baseflight.net/", "https://*.amazonaws.com/", + "https://*.betaflight.tech/", "serial", "usb", "storage", From 8d5d81f9cf73dc757b0d80b29029fe79f4e5eeec Mon Sep 17 00:00:00 2001 From: mikeller Date: Wed, 1 Aug 2018 01:12:24 +1200 Subject: [PATCH 053/104] Added Google analytics collection. --- libraries/google-analytics-bundle.js | 95 ++++++++++++++++++++++++++++ locales/en/messages.json | 3 + manifest.json | 1 + package-lock.json | 10 +++ package.json | 4 +- src/js/Analytics.js | 64 +++++++++++++++++++ src/js/main.js | 69 +++++++++++++++++++- src/js/serial_backend.js | 28 +++++++- src/main.html | 4 ++ src/tabs/options.html | 3 + 10 files changed, 277 insertions(+), 4 deletions(-) create mode 100644 libraries/google-analytics-bundle.js create mode 100644 src/js/Analytics.js diff --git a/libraries/google-analytics-bundle.js b/libraries/google-analytics-bundle.js new file mode 100644 index 000000000..26b3c00d1 --- /dev/null +++ b/libraries/google-analytics-bundle.js @@ -0,0 +1,95 @@ +(function() { 'use strict';var h,aa=aa||{},k=this,m=function(a){return void 0!==a},ba=function(){},ca=function(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&& +"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"==b&&"undefined"==typeof a.call)return"object";return b},n=function(a){return"array"==ca(a)},da=function(a){var b=ca(a);return"array"==b||"object"==b&&"number"==typeof a.length},p=function(a){return"string"==typeof a},ea=function(a){return"number"==typeof a},q=function(a){return"function"==ca(a)},r=function(a){var b=typeof a;return"object"==b&&null!=a||"function"==b},fa= +function(a,b,c){return a.call.apply(a.bind,arguments)},ga=function(a,b,c){if(!a)throw Error();if(2b?1:0};var la=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(p(a))return p(b)&&1==b.length?a.indexOf(b,c):-1;for(;cb?null:p(a)?a.charAt(b):a[b]},ra=function(a, +b){var c=la(a,b),d;(d=0<=c)&&Array.prototype.splice.call(a,c,1);return d},sa=function(a){return Array.prototype.concat.apply(Array.prototype,arguments)},ta=function(a,b,c){return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};var ua="StopIteration"in k?k.StopIteration:{message:"StopIteration",stack:""},va=function(){};va.prototype.next=function(){throw ua;};va.prototype.Yb=function(){return this};var wa=function(a,b,c){for(var d in a)b.call(c,a[d],d,a)},xa=function(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b},ya=function(a){var b=[],c=0,d;for(d in a)b[c++]=d;return b},za=function(a){return null!==a&&"withCredentials"in a},Aa=function(a,b){var c;a:{for(c in a)if(b.call(void 0,a[c],c,a))break a;c=void 0}return c&&a[c]},Ba="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" "),Ca=function(a,b){for(var c,d,e=1;e2*this.g&&Da(this),!0):!1};var Da=function(a){if(a.g!=a.b.length){for(var b=0,c=0;b=d.b.length)throw ua;var e=d.b[b++];return a?e:d.B[e]};return e};var A=function(a,b){return Object.prototype.hasOwnProperty.call(a,b)};var Ea,Fa,Ga={id:"hitType",name:"t",valueType:"text",maxLength:void 0,defaultValue:void 0},Ha={id:"sessionControl",name:"sc",valueType:"text",maxLength:void 0,defaultValue:void 0},Ia={id:"description",name:"cd",valueType:"text",maxLength:2048,defaultValue:void 0},Ja={id:"eventCategory",name:"ec",valueType:"text",maxLength:150,defaultValue:void 0},Ka={id:"eventAction",name:"ea",valueType:"text",maxLength:500,defaultValue:void 0},La={id:"eventLabel",name:"el",valueType:"text",maxLength:500,defaultValue:void 0}, +Ma={id:"eventValue",name:"ev",valueType:"integer",maxLength:void 0,defaultValue:void 0},Na={Id:Ga,Xb:{id:"anonymizeIp",name:"aip",valueType:"boolean",maxLength:void 0,defaultValue:void 0},Td:{id:"queueTime",name:"qt",valueType:"integer",maxLength:void 0,defaultValue:void 0},pd:{id:"cacheBuster",name:"z",valueType:"text",maxLength:void 0,defaultValue:void 0},Zd:Ha,$d:{id:"sessionGroup",name:"sg",valueType:"text",maxLength:void 0,defaultValue:void 0},pe:{id:"userId",name:"uid",valueType:"text",maxLength:void 0, +defaultValue:void 0},Qd:{id:"nonInteraction",name:"ni",valueType:"boolean",maxLength:void 0,defaultValue:void 0},zd:Ia,ie:{id:"title",name:"dt",valueType:"text",maxLength:1500,defaultValue:void 0},ld:{id:"appId",name:"aid",valueType:"text",maxLength:150,defaultValue:void 0},md:{id:"appInstallerId",name:"aiid",valueType:"text",maxLength:150,defaultValue:void 0},Cd:Ja,Bd:Ka,Dd:La,Ed:Ma,be:{id:"socialNetwork",name:"sn",valueType:"text",maxLength:50,defaultValue:void 0},ae:{id:"socialAction",name:"sa", +valueType:"text",maxLength:50,defaultValue:void 0},ce:{id:"socialTarget",name:"st",valueType:"text",maxLength:2048,defaultValue:void 0},le:{id:"transactionId",name:"ti",valueType:"text",maxLength:500,defaultValue:void 0},ke:{id:"transactionAffiliation",name:"ta",valueType:"text",maxLength:500,defaultValue:void 0},me:{id:"transactionRevenue",name:"tr",valueType:"currency",maxLength:void 0,defaultValue:void 0},ne:{id:"transactionShipping",name:"ts",valueType:"currency",maxLength:void 0,defaultValue:void 0}, +oe:{id:"transactionTax",name:"tt",valueType:"currency",maxLength:void 0,defaultValue:void 0},xd:{id:"currencyCode",name:"cu",valueType:"text",maxLength:10,defaultValue:void 0},Md:{id:"itemPrice",name:"ip",valueType:"currency",maxLength:void 0,defaultValue:void 0},Nd:{id:"itemQuantity",name:"iq",valueType:"integer",maxLength:void 0,defaultValue:void 0},Kd:{id:"itemCode",name:"ic",valueType:"text",maxLength:500,defaultValue:void 0},Ld:{id:"itemName",name:"in",valueType:"text",maxLength:500,defaultValue:void 0}, +Jd:{id:"itemCategory",name:"iv",valueType:"text",maxLength:500,defaultValue:void 0},vd:{id:"campaignSource",name:"cs",valueType:"text",maxLength:100,defaultValue:void 0},td:{id:"campaignMedium",name:"cm",valueType:"text",maxLength:50,defaultValue:void 0},ud:{id:"campaignName",name:"cn",valueType:"text",maxLength:100,defaultValue:void 0},sd:{id:"campaignKeyword",name:"ck",valueType:"text",maxLength:500,defaultValue:void 0},qd:{id:"campaignContent",name:"cc",valueType:"text",maxLength:500,defaultValue:void 0}, +rd:{id:"campaignId",name:"ci",valueType:"text",maxLength:100,defaultValue:void 0},Hd:{id:"gclid",name:"gclid",valueType:"text",maxLength:void 0,defaultValue:void 0},yd:{id:"dclid",name:"dclid",valueType:"text",maxLength:void 0,defaultValue:void 0},Sd:{id:"pageLoadTime",name:"plt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ad:{id:"dnsTime",name:"dns",valueType:"integer",maxLength:void 0,defaultValue:void 0},de:{id:"tcpConnectTime",name:"tcp",valueType:"integer",maxLength:void 0,defaultValue:void 0}, +Yd:{id:"serverResponseTime",name:"srt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Rd:{id:"pageDownloadTime",name:"pdt",valueType:"integer",maxLength:void 0,defaultValue:void 0},Ud:{id:"redirectResponseTime",name:"rrt",valueType:"integer",maxLength:void 0,defaultValue:void 0},ee:{id:"timingCategory",name:"utc",valueType:"text",maxLength:150,defaultValue:void 0},he:{id:"timingVar",name:"utv",valueType:"text",maxLength:500,defaultValue:void 0},ge:{id:"timingValue",name:"utt",valueType:"integer", +maxLength:void 0,defaultValue:void 0},fe:{id:"timingLabel",name:"utl",valueType:"text",maxLength:500,defaultValue:void 0},Fd:{id:"exDescription",name:"exd",valueType:"text",maxLength:150,defaultValue:void 0},Gd:{id:"exFatal",name:"exf",valueType:"boolean",maxLength:void 0,defaultValue:"1"}},Oa=function(a){if(1>a||200a||200< +a)throw Error("Expected metric index range 1-200, but was : "+a);return{id:"metric"+a,name:"cm"+a,valueType:"integer",maxLength:void 0,defaultValue:void 0}};var Qa=function(a){if(1>a)return"0";if(3>a)return"1-2";a=Math.floor(Math.log(a-1)/Math.log(2));return Math.pow(2,a)+1+"-"+Math.pow(2,a+1)},Ra=function(a,b){for(var c=0,d=a.length-1,e=0;c<=d;){var f=Math.floor((c+d)/2),e=a[f];if(b<=e){d=0==f?0:a[f-1];if(b>d)return(d+1).toString()+"-"+e.toString();d=f-1}else if(b>e){if(f>=a.length-1)return(a[a.length-1]+1).toString()+"+";c=f+1}}return"<= 0"};var B=function(){this.mb=[]},Sa=function(){return new B};h=B.prototype;h.when=function(a){this.mb.push(a);return this};h.Wb=function(a){var b=arguments;this.when(function(a){return 0<=la(b,a.Ab())});return this};h.hd=function(a,b){var c=ta(arguments,1);this.when(function(b){b=b.ba().get(a);return 0<=la(c,b)});return this};h.sb=function(a,b){if(r(this.h))throw Error("Filter has already been set.");this.h=r(b)?t(a,b):a;return this}; +h.qa=function(){if(0==this.mb.length)throw Error("Must specify at least one predicate using #when or a helper method.");if(!r(this.h))throw Error("Must specify a delegate filter using #applyFilter.");return t(function(a){oa(this.mb,function(b){return b(a)})&&this.h(a)},this)};var C=function(){this.rb=!1;this.Fb="";this.Rb=!1;this.Ga=null};C.prototype.cc=function(a){this.rb=!0;this.Fb=a||" - ";return this};C.prototype.$c=function(){this.Rb=!0;return this};C.prototype.Kc=function(){return Ta(this,Qa)};C.prototype.Mc=function(a){return Ta(this,ha(Ra,a))}; +var Ta=function(a,b){if(null!=a.Ga)throw Error("LabelerBuilder: Only one labeling strategy may be used.");a.Ga=t(function(a){var d=a.ba().get(Ma),e=a.ba().get(La);ea(d)&&(d=b(d),null!=e&&this.rb&&(d=e+this.Fb+d),a.ba().set(La,d))},a);return a};C.prototype.qa=function(){if(null==this.Ga)throw Error("LabelerBuilder: a labeling strategy must be specified prior to calling build().");return Sa().Wb("event").sb(t(function(a){this.Ga(a);this.Rb&&a.ba().remove(Ma)},this)).qa()};var Ua=function(a,b){var c=Array.prototype.slice.call(arguments),d=c.shift();if("undefined"==typeof d)throw Error("[goog.string.format] Template required");return d.replace(/%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g,function(a,b,d,l,x,M,V,W){if("%"==M)return"%";var Pb=c.shift();if("undefined"==typeof Pb)throw Error("[goog.string.format] Not enough arguments");arguments[0]=Pb;return D[M].apply(null,arguments)})},D={s:function(a,b,c){return isNaN(c)||""==c||a.length>=Number(c)?a:a=-1Number(a)?"-":0<=b.indexOf("+")?"+":0<=b.indexOf(" ")?" ":"";0<=Number(a)&&(d=f+d);if(isNaN(c)||d.length>=Number(c))return d;d=isNaN(e)?Math.abs(Number(a)).toString():Math.abs(Number(a)).toFixed(e);a=Number(c)-d.length-f.length;return d=0<=b.indexOf("-",0)?f+d+ja(" ",a):f+ja(0<=b.indexOf("0",0)?"0":" ",a)+d},d:function(a,b,c,d,e,f,g,l){return D.f(parseInt(a, +10),b,c,d,0,f,g,l)}};D.i=D.d;D.u=D.d;var Va=function(a){if(a.v&&"function"==typeof a.v)return a.v();if(p(a))return a.split("");if(da(a)){for(var b=[],c=a.length,d=0;dparseFloat(hb)){gb=String(jb);break a}}gb=hb} +var kb=gb,lb={},L=function(a){var b;if(!(b=lb[a])){b=0;for(var c=ia(String(kb)).split("."),d=ia(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f=a.keyCode)a.keyCode=-1}catch(b){}};var ub="closure_listenable_"+(1E6*Math.random()|0),vb=function(a){return!(!a||!a[ub])},wb=0;var xb=function(a,b,c,d,e){this.listener=a;this.proxy=null;this.src=b;this.type=c;this.sa=!!d;this.Aa=e;this.key=++wb;this.removed=this.ra=!1},yb=function(a){a.removed=!0;a.listener=null;a.proxy=null;a.src=null;a.Aa=null};var N=function(a){this.src=a;this.m={};this.na=0};N.prototype.add=function(a,b,c,d,e){var f=a.toString();a=this.m[f];a||(a=this.m[f]=[],this.na++);var g=zb(a,b,d,e);-1e.keyCode||void 0!=e.returnValue)){a:{var f=!1;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(x){f=!0}if(f||void 0==e.returnValue)e.returnValue=!0}e=[];for(f=c.currentTarget;f;f=f.parentNode)e.push(f);for(var f=a.type,g=e.length-1;!c.ea&&0<=g;g--){c.currentTarget=e[g];var l=Qb(e[g],f,!0,c),d=d&&l}for(g=0;!c.ea&& +g>>0),Fb=function(a){if(q(a))return a;a[Rb]||(a[Rb]=function(b){return a.handleEvent(b)});return a[Rb]};var O=function(){G.call(this);this.J=new N(this);this.Zb=this;this.lb=null};w(O,G);O.prototype[ub]=!0;h=O.prototype;h.addEventListener=function(a,b,c,d){Eb(this,a,b,c,d)};h.removeEventListener=function(a,b,c,d){Mb(this,a,b,c,d)}; +h.dispatchEvent=function(a){var b,c=this.lb;if(c){b=[];for(var d=1;c;c=c.lb)b.push(c),++d}c=this.Zb;d=a.type||a;if(p(a))a=new H(a,c);else if(a instanceof H)a.target=a.target||c;else{var e=a;a=new H(d,c);Ca(a,e)}var e=!0,f;if(b)for(var g=b.length-1;!a.ea&&0<=g;g--)f=a.currentTarget=b[g],e=Sb(f,d,!0,a)&&e;a.ea||(f=a.currentTarget=c,e=Sb(f,d,!0,a)&&e,a.ea||(e=Sb(f,d,!1,a)&&e));if(b)for(g=0;!a.ea&&g=b.Wa&&b.cancel())}this.Ib?this.Ib.call(this.xb,this):this.nb=!0;this.K||this.I(new wc)}};Q.prototype.wb=function(a,b){this.Ua=!1;xc(this,a,b)}; +var xc=function(a,b,c){a.K=!0;a.M=c;a.ka=!b;yc(a)},Ac=function(a){if(a.K){if(!a.nb)throw new zc;a.nb=!1}};Q.prototype.G=function(a){Ac(this);xc(this,!0,a)};Q.prototype.I=function(a){Ac(this);xc(this,!1,a)};Q.prototype.w=function(a,b){return Bc(this,a,null,b)};var Bc=function(a,b,c,d){a.Ma.push([b,c,d]);a.K&&yc(a);return a};Q.prototype.then=function(a,b,c){var d,e,f=new P(function(a,b){d=a;e=b});Bc(this,d,function(a){a instanceof wc?f.cancel():e(a)});return f.then(a,b,c)};fc(Q); +var Cc=function(a){var b=new Q;Bc(a,b.G,b.I,b);return b},Dc=function(a){return na(a.Ma,function(a){return q(a[1])})},yc=function(a){if(a.Pa&&a.K&&Dc(a)){var b=a.Pa,c=Ec[b];c&&(k.clearTimeout(c.Ca),delete Ec[b]);a.Pa=0}a.o&&(a.o.Wa--,delete a.o);for(var b=a.M,d=c=!1;a.Ma.length&&!a.Ua;){var e=a.Ma.shift(),f=e[0],g=e[1],e=e[2];if(f=a.ka?g:f)try{var l=f.call(e||a.xb,b);m(l)&&(a.ka=a.ka&&(l==b||l instanceof Error),a.M=b=l);if(gc(b)||"function"===typeof k.Promise&&b instanceof k.Promise)d=!0,a.Ua=!0}catch(x){b= +x,a.ka=!0,Dc(a)||(c=!0)}}a.M=b;d&&(l=t(a.wb,a,!0),d=t(a.wb,a,!1),b instanceof Q?(Bc(b,l,d),b.dc=!0):b.then(l,d));c&&(b=new Fc(b),Ec[b.Ca]=b,a.Pa=b.Ca)},Gc=function(a){var b=new Q;b.G(a);return b},Ic=function(){var a=Hc,b=new Q;b.I(a);return b},zc=function(){y.call(this)};w(zc,y);zc.prototype.message="Deferred has already fired";zc.prototype.name="AlreadyCalledError";var wc=function(){y.call(this)};w(wc,y);wc.prototype.message="Deferred was canceled";wc.prototype.name="CanceledError"; +var Fc=function(a){this.Ca=k.setTimeout(t(this.ad,this),0);this.va=a};Fc.prototype.ad=function(){delete Ec[this.Ca];throw this.va;};var Ec={};var Jc=function(a){this.ya=[];this.h=a};Jc.prototype.Y=function(a){if(!q(a))throw Error("Invalid filter. Must be a function.");this.ya.push(a)};Jc.prototype.send=function(a,b){if(0==this.ya.length)return this.h.send(a,b);var c=new R(a,b);return Kc(this,0,c).w(function(){if(!c.Ya)return this.h.send(a,b)},this)};var Kc=function(a,b,c){return Gc().w(function(){return this.ya[b](c)},a).w(function(){if(++bb.maxLength&&a.set(b,c.substring(0,b.maxLength))})},Dd=function(a){Xa(a,function(b,c){m(b.defaultValue)&&c==b.defaultValue&&a.remove(b)})};var Hc={status:"device-offline",ta:void 0},Ed={status:"rate-limited",ta:void 0},Fd={status:"sampled-out",ta:void 0},Gd={status:"sent",ta:void 0};var Hd=function(a,b){this.cd=a;this.h=b};Hd.prototype.send=function(a,b){var c;c=this.cd;var d=c.Sb(),e=Math.floor((d-c.Gb)*c.oc);0c.ha?c=!1:(--c.ha,c=!0);return c||"item"==a||"transaction"==a?this.h.send(a,b):Gc(Ed)};var Id=function(){this.ha=60;this.Bc=500;this.oc=5E-4;this.Sb=function(){return(new Date).getTime()};this.Gb=this.Sb()};var Jd=function(a,b){this.j=a;this.h=b};Jd.prototype.send=function(a,b){var c=b.get(Qc),c=parseInt(c.split("-")[1],16),d;"timing"!=a?d=nd(this.j):((d=b.get(Tc))&&b.remove(Tc),d=d||nd(this.j));return c<655.36*d?this.h.send(a,b):Gc(Fd)};var Kd=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/,Ld=function(a,b){if(a)for(var c=a.split("&"),d=0;dthis.Ia?c.I({status:"payload-too-big",ta:Ua("Encoded hit length == %s, but should be <= %s.",d.length,this.Ia)}):Vd(this.Uc,function(){c.G(Gd)},d);return c};var he=function(a,b){var c=new de;c.add(Ga.name,a);Xa(b,function(a,b){c.add(a.name,b.toString())});return c.toString()};var ie=function(a,b,c){this.j=a;this.Tc=b;this.Ia=c};ie.prototype.cb=function(){if(!this.D){if(!Cc(this.j.ma).K)throw Error("Cannot construct shared channel prior to settings being ready.");new zd;var a=new Bd(new ge(this.Tc,this.Ia)),b=new Id;this.D=new Ad(this.j,new Jd(this.j,new Hd(b,a)))}return this.D};var je=new z,ke=function(){Ea||(Ea=new T(new od));return Ea};v("goog.async.Deferred",Q);v("goog.async.Deferred.prototype.addCallback",Q.prototype.w);v("goog.async.Deferred.prototype.callback",Q.prototype.G);v("goog.async.Deferred.prototype.then",Q.prototype.then);v("goog.events.EventTarget",O);v("goog.events.EventTarget.prototype.listen",O.prototype.listen); +v("analytics.getService",function(a,b){var c=je.get(a,null),d=b||chrome.runtime.getManifest().version;if(null===c){c=ke();if(!Fa){var e=ke();Fa=new ud(e,new ie(e,"https://www.google-analytics.com/collect",8192))}c=new bd("ca1.6.0",a,d,c,Fa);je.set(a,c)}return c});v("analytics.internal.GoogleAnalyticsService",bd);v("analytics.internal.GoogleAnalyticsService.prototype.getTracker",bd.prototype.tc);v("analytics.internal.GoogleAnalyticsService.prototype.getConfig",bd.prototype.rc); +v("analytics.internal.ServiceSettings",T);v("analytics.internal.ServiceSettings.prototype.setTrackingPermitted",T.prototype.Wc);v("analytics.internal.ServiceSettings.prototype.isTrackingPermitted",T.prototype.Fa);v("analytics.internal.ServiceSettings.prototype.setSampleRate",T.prototype.Vc);v("analytics.internal.ServiceSettings.prototype.resetUserId",T.prototype.Nc);v("analytics.internal.ServiceTracker",S);v("analytics.internal.ServiceTracker.prototype.send",S.prototype.send); +v("analytics.internal.ServiceTracker.prototype.sendAppView",S.prototype.Pc);v("analytics.internal.ServiceTracker.prototype.sendEvent",S.prototype.Qc);v("analytics.internal.ServiceTracker.prototype.sendSocial",S.prototype.Sc);v("analytics.internal.ServiceTracker.prototype.sendException",S.prototype.Rc);v("analytics.internal.ServiceTracker.prototype.sendTiming",S.prototype.Pb);v("analytics.internal.ServiceTracker.prototype.startTiming",S.prototype.Zc);v("analytics.internal.ServiceTracker.Timing",ad); +v("analytics.internal.ServiceTracker.Timing.prototype.send",ad.prototype.send);v("analytics.internal.ServiceTracker.prototype.forceSessionStart",S.prototype.qc);v("analytics.internal.ServiceTracker.prototype.addFilter",S.prototype.Y);v("analytics.internal.FilterChannel.Hit",R);v("analytics.internal.FilterChannel.Hit.prototype.getHitType",R.prototype.Ab);v("analytics.internal.FilterChannel.Hit.prototype.getParameters",R.prototype.ba);v("analytics.internal.FilterChannel.Hit.prototype.cancel",R.prototype.cancel); +v("analytics.ParameterMap",E);v("analytics.ParameterMap.Entry",E.Entry);v("analytics.ParameterMap.prototype.set",E.prototype.set);v("analytics.ParameterMap.prototype.get",E.prototype.get);v("analytics.ParameterMap.prototype.remove",E.prototype.remove);v("analytics.ParameterMap.prototype.toObject",E.prototype.Ub);v("analytics.HitTypes.APPVIEW","appview");v("analytics.HitTypes.EVENT","event");v("analytics.HitTypes.SOCIAL","social");v("analytics.HitTypes.TRANSACTION","transaction"); +v("analytics.HitTypes.ITEM","item");v("analytics.HitTypes.TIMING","timing");v("analytics.HitTypes.EXCEPTION","exception");v("analytics.createDimensionParam",Oa);v("analytics.createMetricParam",Pa);wa(Na,function(a){var b=a.id.replace(/[A-Z]/,"_$&").toUpperCase();v("analytics.Parameters."+b,a)});v("analytics.filters.EventLabelerBuilder",C);v("analytics.filters.EventLabelerBuilder.prototype.appendToExistingLabel",C.prototype.cc);v("analytics.filters.EventLabelerBuilder.prototype.stripValue",C.prototype.$c); +v("analytics.filters.EventLabelerBuilder.prototype.powersOfTwo",C.prototype.Kc);v("analytics.filters.EventLabelerBuilder.prototype.rangeBounds",C.prototype.Mc);v("analytics.filters.EventLabelerBuilder.prototype.build",C.prototype.qa);v("analytics.filters.FilterBuilder",B);v("analytics.filters.FilterBuilder.builder",Sa);v("analytics.filters.FilterBuilder.prototype.when",B.prototype.when);v("analytics.filters.FilterBuilder.prototype.whenHitType",B.prototype.Wb); +v("analytics.filters.FilterBuilder.prototype.whenValue",B.prototype.hd);v("analytics.filters.FilterBuilder.prototype.applyFilter",B.prototype.sb);v("analytics.filters.FilterBuilder.prototype.build",B.prototype.qa);v("analytics.EventBuilder",F);v("analytics.EventBuilder.builder",function(){return Ya});v("analytics.EventBuilder.prototype.category",F.prototype.ec);v("analytics.EventBuilder.prototype.action",F.prototype.action);v("analytics.EventBuilder.prototype.label",F.prototype.label); +v("analytics.EventBuilder.prototype.value",F.prototype.value);v("analytics.EventBuilder.prototype.dimension",F.prototype.mc);v("analytics.EventBuilder.prototype.metric",F.prototype.Cc);v("analytics.EventBuilder.prototype.send",F.prototype.send); }).call(this); diff --git a/locales/en/messages.json b/locales/en/messages.json index bcc0f6940..dd72c614f 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -63,6 +63,9 @@ "rememberLastTab": { "message": "Reopen last tab on connect" }, + "analyticsOptOut": { + "message": "Opt out of the anonymised collection of statistics data" + }, "userLanguageSelect": { "message": "Language (need to restart the application for the changes to take effect)" }, diff --git a/manifest.json b/manifest.json index 9025484dc..34c1617fd 100755 --- a/manifest.json +++ b/manifest.json @@ -24,6 +24,7 @@ "http://*.baseflight.net/", "https://*.amazonaws.com/", "https://*.betaflight.tech/", + "https://www.google-analytics.com/", "serial", "usb", "storage", diff --git a/package-lock.json b/package-lock.json index 774272817..398c1cf40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5900,6 +5900,11 @@ } } }, + "object-hash": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.0.tgz", + "integrity": "sha512-05KzQ70lSeGSrZJQXE5wNDiTkBJDlUT/myi6RX9dVIvz7a7Qh4oH93BQdiPMn27nldYvVQCKMUaM83AfizZlsQ==" + }, "object-keys": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", @@ -7237,6 +7242,11 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "short-unique-id": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/short-unique-id/-/short-unique-id-1.1.1.tgz", + "integrity": "sha512-gyWJ4pknxpCx0WlUIdCIwHiQ/4sCy0i0YpDOniXP/TboMMRs6rkg6PPKR2nmNfZ9VYeAIm0x9qz/QmJysd9jNg==" + }, "shortid": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.8.tgz", diff --git a/package.json b/package.json index 418328de7..30011d485 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,9 @@ "i18next": "^10.3.0", "i18next-xhr-backend": "^1.5.1", "lru_map": "^0.3.3", - "marked": "^0.3.12" + "marked": "^0.3.12", + "object-hash": "^1.3.0", + "short-unique-id": "^1.1.1" }, "devDependencies": { "chai": "^4.1.2", diff --git a/src/js/Analytics.js b/src/js/Analytics.js new file mode 100644 index 000000000..9240eb9ab --- /dev/null +++ b/src/js/Analytics.js @@ -0,0 +1,64 @@ +'use strict'; + +var Analytics = function (serviceName, trackingId, operatingSystem) { + this.eventBuilder = analytics.EventBuilder; + this.service = analytics.getService(serviceName); + this.tracker = this.service.getTracker(trackingId); + + this.DATA = { + BOARD_TYPE: 'boardType', + FIRMWARE_TYPE: 'firmwareType', + FIRMWARE_VERSION: 'firmwareVersion', + API_VERSION: 'apiVersion', + MCU_ID: 'mcuId', + }; + + this.DIMENSIONS = { + OS: 1, + BOARD_TYPE: 2, + FIRMWARE_TYPE: 3, + FIRMWARE_VERSION: 4, + API_VERSION: 5, + }; + + this.APPLICATION_EVENT = this.eventBuilder.builder() + .category('Application') + .dimension(this.DIMENSIONS.OS, operatingSystem); + + this.resetFlightControllerData(); +}; + +Analytics.prototype.setTrackingPermitted = function (permitted) { + this.service.getConfig().addCallback(function(config) { + config.setTrackingPermitted(permitted); + }); +} + +Analytics.prototype.send = function (event) { + this.tracker.send(event); +} + +Analytics.prototype.sendAppView = function (viewName) { + this.tracker.sendAppView(viewName); +} + +Analytics.prototype.rebuildFlightControllerEvent = function () { + this.FLIGHT_CONTROLLER_EVENT = this.eventBuilder.builder() + .category('FlightController') + .dimension(this.DIMENSIONS.BOARD_TYPE, this.flightControllerData[this.DATA.BOARD_TYPE]) + .dimension(this.DIMENSIONS.FIRMWARE_TYPE, this.flightControllerData[this.DATA.FIRMWARE_TYPE]) + .dimension(this.DIMENSIONS.FIRMWARE_VERSION, this.flightControllerData[this.DATA.FIRMWARE_VERSION]) + .dimension(this.DIMENSIONS.API_VERSION, this.flightControllerData[this.DATA.API_VERSION]); +} + +Analytics.prototype.setFlightControllerData = function (property, value) { + this.flightControllerData[property] = value; + + this.rebuildFlightControllerEvent(); +} + +Analytics.prototype.resetFlightControllerData = function () { + this.flightControllerData = {}; + + this.rebuildFlightControllerEvent(); +} diff --git a/src/js/main.js b/src/js/main.js index 0d8c308a3..dfe9e4537 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,19 +1,60 @@ 'use strict'; +var analytics; + openNewWindowsInExternalBrowser(); //Asynchronous configuration to be done. //When finish the startProcess() function must be called $(document).ready(function () { i18n.init(function() { - startProcess(); + setupAnalytics(); initializeSerialBackend(); }); }); +function setupAnalytics() { + analytics = new Analytics('com.betaflight.configurator', 'UA-123002063-1', GUI.operating_system); + chrome.storage.local.get('userId', function (result) { + var userId; + if (result.userId) { + userId = result.userId; + } else { + var uid = new ShortUniqueId(); + userId = uid.randomUUID(13); + + chrome.storage.local.set({'userId': userId}); + } + + analytics.tracker.set('userId', userId); + + analytics.tracker.set('sessionControl', 'start'); + analytics.send(analytics.APPLICATION_EVENT.action('AppStart')) + + function sendCloseEvent() { + analytics.send(analytics.APPLICATION_EVENT.action('AppClose')) + analytics.tracker.set('sessionControl', 'end'); + } + + try { + var gui = require('nw.gui'); + var win = gui.Window.get(); + win.on('close', function () { + sendCloseEvent(); + + this.close(true); + }); + } catch (ex) { + // Looks like we're in Chrome - but the event does not actually get fired + chrome.runtime.onSuspend.addListener(sendCloseEvent); + } + + startProcess(); + }); +} + //Process to execute to real start the app function startProcess() { - // translate to user-selected language i18n.localizePage(); @@ -113,6 +154,8 @@ function startProcess() { GUI.tab_switch_in_progress = false; } + analytics.sendAppView(tab); + switch (tab) { case 'landing': TABS.landing.initialize(content_ready); @@ -249,6 +292,28 @@ function startProcess() { $('div.checkForConfiguratorUnstableVersions').hide(); } + chrome.storage.local.get('analyticsOptOut', function (result) { + if (result.analyticsOptOut) { + $('div.analyticsOptOut input').prop('checked', true); + } + + $('div.analyticsOptOut input').change(function () { + var checked = $(this).is(':checked'); + + chrome.storage.local.set({'analyticsOptOut': checked}); + + if (checked) { + analytics.send(analytics.APPLICATION_EVENT.action('OptOut')); + } + + analytics.setTrackingPermitted(!checked); + + if (!checked) { + analytics.send(analytics.APPLICATION_EVENT.action('OptIn')); + } + }).change(); + }); + chrome.storage.local.get('userLanguageSelect', function (result) { var userLanguage_e = $('div.userLanguage select'); diff --git a/src/js/serial_backend.js b/src/js/serial_backend.js index b225d6b0f..a64a714ce 100755 --- a/src/js/serial_backend.js +++ b/src/js/serial_backend.js @@ -1,6 +1,8 @@ 'use strict'; var mspHelper; +var analyticsTimer; + function initializeSerialBackend() { GUI.updateManualPortVisibility = function(){ @@ -124,6 +126,14 @@ function initializeSerialBackend() { function finishClose(finishedCallback) { var wasConnected = CONFIGURATOR.connectionValid; + analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Disconnected')); + if (analyticsTimer) { + analyticsTimer.send(); + + analyticsTimer = undefined; + } + analytics.resetFlightControllerData(); + serial.disconnect(onClosed); MSP.disconnect_cleanup(); @@ -200,13 +210,17 @@ function onOpen(openInfo) { // request configuration data MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () { + analytics.setFlightControllerData(analytics.DATA.API_VERSION, CONFIG.apiVersion); + GUI.log(i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion])); if (semver.gte(CONFIG.apiVersion, CONFIGURATOR.apiVersionAccepted)) { MSP.send_message(MSPCodes.MSP_FC_VARIANT, false, false, function () { + analytics.setFlightControllerData(analytics.DATA.FIRMWARE_TYPE, CONFIG.flightControllerIdentifier); if (CONFIG.flightControllerIdentifier === 'BTFL') { MSP.send_message(MSPCodes.MSP_FC_VERSION, false, false, function () { + analytics.setFlightControllerData(analytics.DATA.FIRMWARE_VERSION, CONFIG.flightControllerVersion); GUI.log(i18n.getMessage('fcInfoReceived', [CONFIG.flightControllerIdentifier, CONFIG.flightControllerVersion])); updateStatusBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier); @@ -217,13 +231,19 @@ function onOpen(openInfo) { GUI.log(i18n.getMessage('buildInfoReceived', [CONFIG.buildInfo])); MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, function () { + analytics.setFlightControllerData(analytics.DATA.BOARD_TYPE, CONFIG.boardIdentifier); GUI.log(i18n.getMessage('boardInfoReceived', [CONFIG.boardIdentifier, CONFIG.boardVersion])); updateStatusBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier, CONFIG.boardIdentifier); updateTopBarVersion(CONFIG.flightControllerVersion, CONFIG.flightControllerIdentifier, CONFIG.boardIdentifier); MSP.send_message(MSPCodes.MSP_UID, false, false, function () { - GUI.log(i18n.getMessage('uniqueDeviceIdReceived', [CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16)])); + var uniqueDeviceIdentifier = CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16); + + analytics.setFlightControllerData(analytics.DATA.MCU_ID, objectHash.sha1(uniqueDeviceIdentifier)); + analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Connected')); + analyticsTimer = analytics.tracker.startTiming('FlightController', 'Connected'); + GUI.log(i18n.getMessage('uniqueDeviceIdReceived', [uniqueDeviceIdentifier])); if (semver.gte(CONFIG.apiVersion, "1.20.0")) { MSP.send_message(MSPCodes.MSP_NAME, false, false, function () { @@ -240,6 +260,8 @@ function onOpen(openInfo) { }); }); } else { + analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused')); + var dialog = $('.dialogConnectWarning')[0]; $('.dialogConnectWarning-content').html(i18n.getMessage('firmwareTypeNotSupported')); @@ -254,6 +276,8 @@ function onOpen(openInfo) { } }); } else { + analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused')); + var dialog = $('.dialogConnectWarning')[0]; $('.dialogConnectWarning-content').html(i18n.getMessage('firmwareVersionNotSupported', [CONFIGURATOR.apiVersionAccepted])); @@ -268,6 +292,8 @@ function onOpen(openInfo) { } }); } else { + analytics.send(analytics.APPLICATION_EVENT.action('SerialPortFailed')); + console.log('Failed to open serial port'); GUI.log(i18n.getMessage('serialPortOpenFail')); diff --git a/src/main.html b/src/main.html index 2b397d3ea..8fb778ad4 100755 --- a/src/main.html +++ b/src/main.html @@ -39,6 +39,8 @@ + + @@ -54,6 +56,7 @@ + @@ -79,6 +82,7 @@ + diff --git a/src/tabs/options.html b/src/tabs/options.html index 1de44b984..43be4837f 100644 --- a/src/tabs/options.html +++ b/src/tabs/options.html @@ -7,6 +7,9 @@
+
+ +
+
+
+ +
+
+
+ +
+
+
diff --git a/src/tabs/privacy_policy.html b/src/tabs/privacy_policy.html new file mode 100644 index 000000000..99c1ae3cf --- /dev/null +++ b/src/tabs/privacy_policy.html @@ -0,0 +1,104 @@ +

Privacy Policy

+ + +

Effective date: August 06, 2018

+ + +

The Betaflight Group ("us", "we", or "our") operates the website and the Betaflight Configurator mobile application (the "Service").

+ +

This page informs you of our policies regarding the collection, use, and disclosure of personal data when you use our Service and the choices you have associated with that data. This Privacy Policy for The Betaflight Group is powered by FreePrivacyPolicy.com.

+ +

We use your data to provide and improve the Service. By using the Service, you agree to the collection and use of information in accordance with this policy. Unless otherwise defined in this Privacy Policy, terms used in this Privacy Policy have the same meanings as in our Terms and Conditions.

+ + +

Information Collection And Use

+ +

We collect several different types of information for various purposes to provide and improve our Service to you.

+ +

Types of Data Collected

+ +

Usage Data

+ +

We may also collect information that your browser sends whenever you visit our Service or when you access the Service by or through a mobile device ("Usage Data").

+

This Usage Data may include information such as your computer's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that you visit, the time and date of your visit, the time spent on those pages, unique device identifiers and other diagnostic data.

+

When you access the Service by or through a mobile device, this Usage Data may include information such as the type of mobile device you use, your mobile device unique ID, the IP address of your mobile device, your mobile operating system, the type of mobile Internet browser you use, unique device identifiers and other diagnostic data.

+ +

Tracking & Cookies Data

+

We use cookies and similar tracking technologies to track the activity on our Service and hold certain information.

+

Cookies are files with small amount of data which may include an anonymous unique identifier. Cookies are sent to your browser from a website and stored on your device. Tracking technologies also used are beacons, tags, and scripts to collect and track information and to improve and analyze our Service.

+

Examples of Cookies we use:

+
    +
  • Session Cookies. We use Session Cookies to operate our Service.
  • +
  • Preference Cookies. We use Preference Cookies to remember your preferences and various settings.
  • +
+ +

Use of Data

+ +

The Betaflight Group uses the collected data for various purposes:

+
    +
  • To provide and maintain the Service
  • +
  • To notify you about changes to our Service
  • +
  • To allow you to participate in interactive features of our Service when you choose to do so
  • +
  • To provide customer care and support
  • +
  • To provide analysis or valuable information so that we can improve the Service
  • +
  • To monitor the usage of the Service
  • +
  • To detect, prevent and address technical issues
  • +
+ +

Transfer Of Data

+

Your information, including Personal Data, may be transferred to — and maintained on — computers located outside of your state, province, country or other governmental jurisdiction where the data protection laws may differ than those from your jurisdiction.

+

If you are located outside United States and choose to provide information to us, please note that we transfer the data, including Personal Data, to United States and process it there.

+

Your consent to this Privacy Policy followed by your submission of such information represents your agreement to that transfer.

+

The Betaflight Group will take all steps reasonably necessary to ensure that your data is treated securely and in accordance with this Privacy Policy and no transfer of your Personal Data will take place to an organization or a country unless there are adequate controls in place including the security of your data and other personal information.

+ +

Disclosure Of Data

+ +

Legal Requirements

+

The Betaflight Group may disclose your Personal Data in the good faith belief that such action is necessary to:

+
    +
  • To comply with a legal obligation
  • +
  • To protect and defend the rights or property of The Betaflight Group
  • +
  • To prevent or investigate possible wrongdoing in connection with the Service
  • +
  • To protect the personal safety of users of the Service or the public
  • +
  • To protect against legal liability
  • +
+ +

Security Of Data

+

The security of your data is important to us, but remember that no method of transmission over the Internet, or method of electronic storage is 100% secure. While we strive to use commercially acceptable means to protect your Personal Data, we cannot guarantee its absolute security.

+ +

Service Providers

+

We may employ third party companies and individuals to facilitate our Service ("Service Providers"), to provide the Service on our behalf, to perform Service-related services or to assist us in analyzing how our Service is used.

+

These third parties have access to your Personal Data only to perform these tasks on our behalf and are obligated not to disclose or use it for any other purpose.

+ +

Analytics

+

We may use third-party Service Providers to monitor and analyze the use of our Service.

+
    +
  • +

    Google Analytics

    +

    Google Analytics is a web analytics service offered by Google that tracks and reports website traffic. Google uses the data collected to track and monitor the use of our Service. This data is shared with other Google services. Google may use the collected data to contextualize and personalize the ads of its own advertising network.

    +

    For more information on the privacy practices of Google, please visit the Google Privacy & Terms web page: https://policies.google.com/privacy?hl=en

    +
  • +
+ + +

Links To Other Sites

+

Our Service may contain links to other sites that are not operated by us. If you click on a third party link, you will be directed to that third party's site. We strongly advise you to review the Privacy Policy of every site you visit.

+

We have no control over and assume no responsibility for the content, privacy policies or practices of any third party sites or services.

+ + +

Children's Privacy

+

Our Service does not address anyone under the age of 18 ("Children").

+

We do not knowingly collect personally identifiable information from anyone under the age of 18. If you are a parent or guardian and you are aware that your Children has provided us with Personal Data, please contact us. If we become aware that we have collected Personal Data from children without verification of parental consent, we take steps to remove that information from our servers.

+ + +

Changes To This Privacy Policy

+

We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page.

+

We will let you know via email and/or a prominent notice on our Service, prior to the change becoming effective and update the "effective date" at the top of this Privacy Policy.

+

You are advised to review this Privacy Policy periodically for any changes. Changes to this Privacy Policy are effective when they are posted on this page.

+ + +

Contact Us

+

If you have any questions about this Privacy Policy, please contact us:

+
    +
  • By visiting this page on our website: https://github.com/betaflight/betaflight-configurator/issues
  • +
From da2206fb8aa11ae525065f8f1725439b7bee31b8 Mon Sep 17 00:00:00 2001 From: mikeller Date: Mon, 6 Aug 2018 23:46:49 +1200 Subject: [PATCH 056/104] Some fixes. --- src/js/Features.js | 8 ++++---- src/js/main.js | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/js/Features.js b/src/js/Features.js index a5dc71d88..16e1b7c76 100644 --- a/src/js/Features.js +++ b/src/js/Features.js @@ -227,18 +227,18 @@ Features.prototype.updateData = function (featureElement) { var controlElements = featureElement.children(); var selectedBit = featureElement.val(); if (selectedBit !== -1) { - var featureName; + var selectedFeature; for (var i = 0; i < controlElements.length; i++) { var bit = controlElements[i].value; if (selectedBit === bit) { self._featureMask = bit_set(self._featureMask, bit); - featureName = self.findFeatureByBit(bit).name; + selectedFeature = self.findFeatureByBit(bit); } else { self._featureMask = bit_clear(self._featureMask, bit); } } - if (featureName) { - self._analyticsChanges['Feature' + featureName] = 'On'; + if (selectedFeature) { + self._analyticsChanges['FeatureGroup-' + selectedFeature.group] = selectedFeature.name; } } } diff --git a/src/js/main.js b/src/js/main.js index e37d66c8c..f6093ccc5 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -4,8 +4,6 @@ var analytics; openNewWindowsInExternalBrowser(); -// Asynchronous configuration to be done. -// When finish the startProcess() function must be called $(document).ready(function () { i18n.init(function() { setupAnalytics(); @@ -25,7 +23,7 @@ function setupAnalytics() { chrome.storage.local.set({ 'userId': userId }); } - var optOut = !!result.analyticsOptOut + var optOut = !!result.analyticsOptOut; var debugMode = process.versions['nw-flavor'] === 'sdk'; From 3451316bd246933da74750ed2f54aa9f73869b29 Mon Sep 17 00:00:00 2001 From: mikeller Date: Tue, 7 Aug 2018 01:43:47 +1200 Subject: [PATCH 057/104] Added firmware data collection. --- src/js/Analytics.js | 44 +++++++++++++++++++++++++++------ src/js/tabs/firmware_flasher.js | 24 ++++++++++++++++-- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/js/Analytics.js b/src/js/Analytics.js index 8697a80e1..c556a3472 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -26,6 +26,7 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op this.EVENT_CATEGORIES = { APPLICATION: 'Application', FLIGHT_CONTROLLER: 'FlightController', + FIRMWARE: 'Firmware', }; this.DATA = { @@ -34,6 +35,10 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_VERSION: 'firmwareVersion', API_VERSION: 'apiVersion', MCU_ID: 'mcuId', + FIRMWARE_NAME: 'firmwareName', + FIRMWARE_CHECKSUM: 'firmwareChecksum', + FIRMWARE_CHANNEL: 'firmwareChannel', + FIRMWARE_ERASE_ALL: 'firmwareEraseAll', }; this.DIMENSIONS = { @@ -42,11 +47,15 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_TYPE: 3, FIRMWARE_VERSION: 4, API_VERSION: 5, + FIRMWARE_NAME: 6, + FIRMWARE_CHANNEL: 7, + FIRMWARE_ERASE_ALL: 8, }; this.setDimension(this.DIMENSIONS.BUILD_TYPE, buildType); this.resetFlightControllerData(); + this.resetFirmwareData(); }; Analytics.prototype.setDimension = function (dimension, value) { @@ -55,8 +64,7 @@ Analytics.prototype.setDimension = function (dimension, value) { } Analytics.prototype.sendEvent = function (category, action, options) { - options = options || {}; - options.eventLabel = options.eventLabel || this.flightControllerData[this.DATA.MCU_ID]; +// options.eventLabel = options.eventLabel || this._flightControllerData[this.DATA.MCU_ID]; this._analytics.event(category, action, options); } @@ -88,20 +96,40 @@ Analytics.prototype.setOptOut = function (optOut) { } Analytics.prototype._rebuildFlightControllerEvent = function () { - this.setDimension(this.DIMENSIONS.BOARD_TYPE, this.flightControllerData[this.DATA.BOARD_TYPE]); - this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this.flightControllerData[this.DATA.FIRMWARE_TYPE]); - this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this.flightControllerData[this.DATA.FIRMWARE_VERSION]); - this.setDimension(this.DIMENSIONS.API_VERSION, this.flightControllerData[this.DATA.API_VERSION]); + this.setDimension(this.DIMENSIONS.BOARD_TYPE, this._flightControllerData[this.DATA.BOARD_TYPE]); + this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this._flightControllerData[this.DATA.FIRMWARE_TYPE]); + this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this._flightControllerData[this.DATA.FIRMWARE_VERSION]); + this.setDimension(this.DIMENSIONS.API_VERSION, this._flightControllerData[this.DATA.API_VERSION]); + this._analytics.set('eventLabel', this._flightControllerData[this.DATA.MCU_ID]); } Analytics.prototype.setFlightControllerData = function (property, value) { - this.flightControllerData[property] = value; + this._flightControllerData[property] = value; this._rebuildFlightControllerEvent(); } Analytics.prototype.resetFlightControllerData = function () { - this.flightControllerData = {}; + this._flightControllerData = {}; this._rebuildFlightControllerEvent(); } + +Analytics.prototype._rebuildFirmwareEvent = function () { + this.setDimension(this.DIMENSIONS.FIRMWARE_NAME, this._firmwareData[this.DATA.FIRMWARE_NAME]); + this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]); + this.setDimension(this.DIMENSIONS.FIRMWARE_ERASE_ALL, this._firmwareData[this.DATA.FIRMWARE_ERASE_ALL]); + this._analytics.set('eventLabel', this._firmwareData[this.DATA.FIRMWARE_CHECKSUM]); +} + +Analytics.prototype.setFirmwareData = function (property, value) { + this._firmwareData[property] = value; + + this._rebuildFirmwareEvent(); +} + +Analytics.prototype.resetFirmwareData = function () { + this._firmwareData = {}; + + this._rebuildFirmwareEvent(); +} diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index f88640441..dd251dc6e 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -50,6 +50,8 @@ TABS.firmware_flasher.initialize = function (callback) { function process_hex(data, summary) { intel_hex = data; + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHECKSUM, objectHash.sha1(intel_hex)); + parse_hex(intel_hex, function (data) { parsed_hex = data; @@ -323,6 +325,8 @@ TABS.firmware_flasher.initialize = function (callback) { // UI Hooks $('a.load_file').click(function () { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'file'); + chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{description: 'HEX files', extensions: ['hex']}]}, function (fileEntry) { if (chrome.runtime.lastError) { console.error(chrome.runtime.lastError.message); @@ -337,6 +341,7 @@ TABS.firmware_flasher.initialize = function (callback) { console.log('Loading file from: ' + path); fileEntry.file(function (file) { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, file.name); var reader = new FileReader(); reader.onprogress = function (e) { @@ -353,6 +358,8 @@ TABS.firmware_flasher.initialize = function (callback) { intel_hex = e.target.result; + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHECKSUM, objectHash.sha1(intel_hex)); + parse_hex(intel_hex, function (data) { parsed_hex = data; @@ -383,7 +390,10 @@ TABS.firmware_flasher.initialize = function (callback) { let isCached = FirmwareCache.has(release); if (evt.target.value=="0" || isCached) { if (isCached) { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'cache'); + FirmwareCache.get(release, cached => { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, release.file); console.info("Release found in cache: " + release.file); onLoadSuccess(cached.hexdata, release); }); @@ -396,6 +406,7 @@ TABS.firmware_flasher.initialize = function (callback) { }); $('a.load_remote_file').click(function (evt) { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'http'); if ($('select[name="firmware_version"]').val() == "0") { GUI.log(i18n.getMessage('firmwareFlasherNoFirmwareSelected')); @@ -411,6 +422,7 @@ TABS.firmware_flasher.initialize = function (callback) { var summary = $('select[name="firmware_version"] option:selected').data('summary'); if (summary) { // undefined while list is loading or while running offline + analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, summary.file); $("a.load_remote_file").text(i18n.getMessage('firmwareFlasherButtonDownloading')); $("a.load_remote_file").addClass('disabled'); $.get(summary.url, onLoadSuccess).fail(failed_to_load); @@ -425,14 +437,17 @@ TABS.firmware_flasher.initialize = function (callback) { if (parsed_hex != false) { var options = {}; + var eraseAll = false; if ($('input.erase_chip').is(':checked')) { options.erase_chip = true; + + eraseAll = true } + analytics.setFirmwareData(analytics.DATA.FIRMWARE_ERASE_ALL, eraseAll.toString()); if (String($('div#port-picker #port').val()) != 'DFU') { if (String($('div#port-picker #port').val()) != '0') { - var port = String($('div#port-picker #port').val()), - baud; + var port = String($('div#port-picker #port').val()), baud; baud = 115200; if ($('input.updating').is(':checked')) { @@ -445,6 +460,7 @@ TABS.firmware_flasher.initialize = function (callback) { baud = parseInt($('#flash_manual_baud_rate').val()); } + analytics.sendEvent(analytics.EVENT_CATEGORIES.FIRMWARE, 'Flashing'); STM32.connect(port, baud, parsed_hex, options); } else { @@ -452,6 +468,8 @@ TABS.firmware_flasher.initialize = function (callback) { GUI.log(i18n.getMessage('firmwareFlasherNoValidPort')); } } else { + analytics.sendEvent(analytics.EVENT_CATEGORIES.FIRMWARE, 'Flashing'); + STM32DFU.connect(usbDevices.STM32DFU, parsed_hex, options); } } else { @@ -639,5 +657,7 @@ TABS.firmware_flasher.cleanup = function (callback) { $(document).unbind('keypress'); $(document).off('click', 'span.progressLabel a'); + analytics.resetFirmwareData(); + if (callback) callback(); }; From ff30958d73e1127e0e2a3b205a2c806707f4e461 Mon Sep 17 00:00:00 2001 From: mikeller Date: Wed, 8 Aug 2018 23:19:56 +1200 Subject: [PATCH 058/104] Removed 'mobile' from privacy policy. --- src/tabs/privacy_policy.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tabs/privacy_policy.html b/src/tabs/privacy_policy.html index 99c1ae3cf..232317463 100644 --- a/src/tabs/privacy_policy.html +++ b/src/tabs/privacy_policy.html @@ -4,7 +4,7 @@

Privacy Policy

Effective date: August 06, 2018

-

The Betaflight Group ("us", "we", or "our") operates the website and the Betaflight Configurator mobile application (the "Service").

+

The Betaflight Group ("us", "we", or "our") operates the website and the Betaflight Configurator application (the "Service").

This page informs you of our policies regarding the collection, use, and disclosure of personal data when you use our Service and the choices you have associated with that data. This Privacy Policy for The Betaflight Group is powered by FreePrivacyPolicy.com.

@@ -19,9 +19,9 @@

Types of Data Collected

Usage Data

-

We may also collect information that your browser sends whenever you visit our Service or when you access the Service by or through a mobile device ("Usage Data").

+

We may also collect information that your browser sends whenever you visit our Service or when you access the Service by or through a device ("Usage Data").

This Usage Data may include information such as your computer's Internet Protocol address (e.g. IP address), browser type, browser version, the pages of our Service that you visit, the time and date of your visit, the time spent on those pages, unique device identifiers and other diagnostic data.

-

When you access the Service by or through a mobile device, this Usage Data may include information such as the type of mobile device you use, your mobile device unique ID, the IP address of your mobile device, your mobile operating system, the type of mobile Internet browser you use, unique device identifiers and other diagnostic data.

+

When you access the Service by or through a device, this Usage Data may include information such as the type of device you use, your device unique ID, the IP address of your device, your operating system, the type of Internet browser you use, unique device identifiers and other diagnostic data.

Tracking & Cookies Data

We use cookies and similar tracking technologies to track the activity on our Service and hold certain information.

From 237dc08ca600b2c82ccf3fb007e353dfe34354f2 Mon Sep 17 00:00:00 2001 From: mikeller Date: Thu, 9 Aug 2018 01:08:17 +1200 Subject: [PATCH 059/104] Made initialisation lazy, added tracking for expert mode. --- src/js/Analytics.js | 7 +-- src/js/main.js | 114 +++++++++++++++++++++++++------------------- 2 files changed, 70 insertions(+), 51 deletions(-) diff --git a/src/js/Analytics.js b/src/js/Analytics.js index c556a3472..6b51cee87 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -5,7 +5,7 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op this.setOptOut(optOut); - this._analytics = analytics; + this._analytics = googleAnalytics; this._analytics.initialize(this._trackingId, { storage: 'none', @@ -42,7 +42,7 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op }; this.DIMENSIONS = { - BUILD_TYPE: 1, + CONFIGURATOR_BUILD_TYPE: 1, BOARD_TYPE: 2, FIRMWARE_TYPE: 3, FIRMWARE_VERSION: 4, @@ -50,9 +50,10 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_NAME: 6, FIRMWARE_CHANNEL: 7, FIRMWARE_ERASE_ALL: 8, + CONFIGURATOR_EXPERT_MODE: 9, }; - this.setDimension(this.DIMENSIONS.BUILD_TYPE, buildType); + this.setDimension(this.DIMENSIONS.CONFIGURATOR_BUILD_TYPE, buildType); this.resetFlightControllerData(); this.resetFirmwareData(); diff --git a/src/js/main.js b/src/js/main.js index f6093ccc5..9895232cc 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -1,61 +1,74 @@ 'use strict'; -var analytics; +var googleAnalytics = analytics; +var analytics = undefined; openNewWindowsInExternalBrowser(); $(document).ready(function () { i18n.init(function() { - setupAnalytics(); + startProcess(); initializeSerialBackend(); }); }); -function setupAnalytics() { - chrome.storage.local.get(['userId', 'analyticsOptOut'], function (result) { - var userId; - if (result.userId) { - userId = result.userId; - } else { - var uid = new ShortUniqueId(); - userId = uid.randomUUID(13); +function checkSetupAnalytics(callback) { + if (!analytics) { + setTimeout(function () { + chrome.storage.local.get(['userId', 'analyticsOptOut'], function (result) { + if (!analytics) { + setupAnalytics(result); + } - chrome.storage.local.set({ 'userId': userId }); - } + callback(analytics); + }); + }); + } else if (callback) { + callback(analytics); + } +}; - var optOut = !!result.analyticsOptOut; +function setupAnalytics(result) { + var userId; + if (result.userId) { + userId = result.userId; + } else { + var uid = new ShortUniqueId(); + userId = uid.randomUUID(13); - var debugMode = process.versions['nw-flavor'] === 'sdk'; + chrome.storage.local.set({ 'userId': userId }); + } - analytics = new Analytics('UA-123002063-1', userId, 'Betaflight Configurator', getManifestVersion(), GUI.operating_system, optOut, debugMode); + var optOut = !!result.analyticsOptOut; - function logException(exception) { - analytics.sendException(exception.stack); - } + var debugMode = process.versions['nw-flavor'] === 'sdk'; - process.on('uncaughtException', logException); + analytics = new Analytics('UA-123002063-1', userId, 'Betaflight Configurator', getManifestVersion(), GUI.operating_system, optOut, debugMode); - analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppStart', { sessionControl: 'start' }); + function logException(exception) { + analytics.sendException(exception.stack); + } - function sendCloseEvent() { - analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppClose', { sessionControl: 'end' }) - } + process.on('uncaughtException', logException); - try { - var gui = require('nw.gui'); - var win = gui.Window.get(); - win.on('close', function () { - sendCloseEvent(); + analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppStart', { sessionControl: 'start' }); - this.close(true); - }); - } catch (ex) { - // Looks like we're in Chrome - but the event does not actually get fired - chrome.runtime.onSuspend.addListener(sendCloseEvent); - } + function sendCloseEvent() { + analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppClose', { sessionControl: 'end' }) + } - startProcess(); - }); + try { + var gui = require('nw.gui'); + var win = gui.Window.get(); + win.on('close', function () { + sendCloseEvent(); + + this.close(true); + }); + } catch (ex) { + // Looks like we're in Chrome - but the event does not actually get fired + chrome.runtime.onSuspend.addListener(sendCloseEvent); + } } //Process to execute to real start the app @@ -159,7 +172,9 @@ function startProcess() { GUI.tab_switch_in_progress = false; } - analytics.sendAppView(tab); + checkSetupAnalytics(function (analytics) { + analytics.sendAppView(tab); + }); switch (tab) { case 'landing': @@ -265,10 +280,6 @@ function startProcess() { chrome.storage.local.set({'permanentExpertMode': checked}); $('input[name="expertModeCheckbox"]').prop('checked', checked).change(); - if (FEATURE_CONFIG) { - updateTabList(FEATURE_CONFIG.features); - } - }).change(); }); @@ -307,15 +318,17 @@ function startProcess() { chrome.storage.local.set({'analyticsOptOut': checked}); - if (checked) { - analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptOut'); - } + checkSetupAnalytics(function (analytics) { + if (checked) { + analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptOut'); + } - analytics.setOptOut(checked); + analytics.setOptOut(checked); - if (!checked) { - analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptIn'); - } + if (!checked) { + analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptIn'); + } + }); }).change(); }); @@ -469,6 +482,11 @@ function startProcess() { } $('input[name="expertModeCheckbox"]').change(function () { + var checked = $(this).is(':checked'); + checkSetupAnalytics(function (analytics) { + analytics.setDimension(analytics.DIMENSIONS.CONFIGURATOR_EXPERT_MODE, checked ? 'On' : 'Off'); + }); + if (FEATURE_CONFIG) { updateTabList(FEATURE_CONFIG.features); } From 91af936893a6b553c83199341f19251b9a2de954 Mon Sep 17 00:00:00 2001 From: mikeller Date: Thu, 9 Aug 2018 01:48:55 +1200 Subject: [PATCH 060/104] Added tracking for firmware download channel. --- src/js/Analytics.js | 7 +++++-- src/js/tabs/firmware_flasher.js | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/js/Analytics.js b/src/js/Analytics.js index 6b51cee87..9fd84293b 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -37,6 +37,7 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op MCU_ID: 'mcuId', FIRMWARE_NAME: 'firmwareName', FIRMWARE_CHECKSUM: 'firmwareChecksum', + FIRMWARE_SOURCE: 'firmwareSource', FIRMWARE_CHANNEL: 'firmwareChannel', FIRMWARE_ERASE_ALL: 'firmwareEraseAll', }; @@ -48,9 +49,10 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_VERSION: 4, API_VERSION: 5, FIRMWARE_NAME: 6, - FIRMWARE_CHANNEL: 7, + FIRMWARE_SOURCE: 7, FIRMWARE_ERASE_ALL: 8, CONFIGURATOR_EXPERT_MODE: 9, + FIRMWARE_CHANNEL: 10, }; this.setDimension(this.DIMENSIONS.CONFIGURATOR_BUILD_TYPE, buildType); @@ -118,8 +120,9 @@ Analytics.prototype.resetFlightControllerData = function () { Analytics.prototype._rebuildFirmwareEvent = function () { this.setDimension(this.DIMENSIONS.FIRMWARE_NAME, this._firmwareData[this.DATA.FIRMWARE_NAME]); - this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]); + this.setDimension(this.DIMENSIONS.FIRMWARE_SOURCE, this._firmwareData[this.DATA.FIRMWARE_SOURCE]); this.setDimension(this.DIMENSIONS.FIRMWARE_ERASE_ALL, this._firmwareData[this.DATA.FIRMWARE_ERASE_ALL]); + this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]); this._analytics.set('eventLabel', this._firmwareData[this.DATA.FIRMWARE_CHECKSUM]); } diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index dd251dc6e..f108dadee 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -270,6 +270,8 @@ TABS.firmware_flasher.initialize = function (callback) { i18n.localizePage(); buildType_e.change(function() { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, $(this).find('option:selected').text()); + $("a.load_remote_file").addClass('disabled'); var build_type = $(this).val(); @@ -325,7 +327,8 @@ TABS.firmware_flasher.initialize = function (callback) { // UI Hooks $('a.load_file').click(function () { - analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'file'); + analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, undefined); + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'file'); chrome.fileSystem.chooseEntry({type: 'openFile', accepts: [{description: 'HEX files', extensions: ['hex']}]}, function (fileEntry) { if (chrome.runtime.lastError) { @@ -390,7 +393,7 @@ TABS.firmware_flasher.initialize = function (callback) { let isCached = FirmwareCache.has(release); if (evt.target.value=="0" || isCached) { if (isCached) { - analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'cache'); + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'cache'); FirmwareCache.get(release, cached => { analytics.setFirmwareData(analytics.DATA.FIRMWARE_NAME, release.file); @@ -406,7 +409,7 @@ TABS.firmware_flasher.initialize = function (callback) { }); $('a.load_remote_file').click(function (evt) { - analytics.setFirmwareData(analytics.DATA.FIRMWARE_CHANNEL, 'http'); + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SOURCE, 'http'); if ($('select[name="firmware_version"]').val() == "0") { GUI.log(i18n.getMessage('firmwareFlasherNoFirmwareSelected')); From 8762dbc5536b12d1f2aaadaefcf58d844f6ca8c2 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Thu, 9 Aug 2018 12:43:22 +1200 Subject: [PATCH 061/104] Fixed stray comment, naming. --- src/js/Analytics.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/js/Analytics.js b/src/js/Analytics.js index 9fd84293b..8647dc14a 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -5,23 +5,23 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op this.setOptOut(optOut); - this._analytics = googleAnalytics; + this._googleAnalytics = googleAnalytics; - this._analytics.initialize(this._trackingId, { + this._googleAnalytics.initialize(this._trackingId, { storage: 'none', clientId: userId, debug: !!debugMode }); // Make it work for the Chrome App: - this._analytics.set('forceSSL', true); - this._analytics.set('transport', 'xhr'); + this._googleAnalytics.set('forceSSL', true); + this._googleAnalytics.set('transport', 'xhr'); // Make it work for NW.js: - this._analytics.set('checkProtocolTask', null); + this._googleAnalytics.set('checkProtocolTask', null); - this._analytics.set('appName', appName); - this._analytics.set('appVersion', debugMode ? appVersion + '-debug' : appVersion); + this._googleAnalytics.set('appName', appName); + this._googleAnalytics.set('appVersion', debugMode ? appVersion + '-debug' : appVersion); this.EVENT_CATEGORIES = { APPLICATION: 'Application', @@ -63,12 +63,11 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op Analytics.prototype.setDimension = function (dimension, value) { var dimensionName = 'dimension' + dimension; - this._analytics.custom(dimensionName, value); + this._googleAnalytics.custom(dimensionName, value); } Analytics.prototype.sendEvent = function (category, action, options) { -// options.eventLabel = options.eventLabel || this._flightControllerData[this.DATA.MCU_ID]; - this._analytics.event(category, action, options); + this._googleAnalytics.event(category, action, options); } Analytics.prototype.sendChangeEvents = function (category, changeList) { @@ -83,15 +82,15 @@ Analytics.prototype.sendChangeEvents = function (category, changeList) { } Analytics.prototype.sendAppView = function (viewName) { - this._analytics.screenview(viewName); + this._googleAnalytics.screenview(viewName); } Analytics.prototype.sendTiming = function (category, timing, value) { - this._analytics.timing(category, timing, value); + this._googleAnalytics.timing(category, timing, value); } Analytics.prototype.sendException = function (message) { - this._analytics.exception(message); + this._googleAnalytics.exception(message); } Analytics.prototype.setOptOut = function (optOut) { @@ -103,7 +102,7 @@ Analytics.prototype._rebuildFlightControllerEvent = function () { this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this._flightControllerData[this.DATA.FIRMWARE_TYPE]); this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this._flightControllerData[this.DATA.FIRMWARE_VERSION]); this.setDimension(this.DIMENSIONS.API_VERSION, this._flightControllerData[this.DATA.API_VERSION]); - this._analytics.set('eventLabel', this._flightControllerData[this.DATA.MCU_ID]); + this._googleAnalytics.set('eventLabel', this._flightControllerData[this.DATA.MCU_ID]); } Analytics.prototype.setFlightControllerData = function (property, value) { @@ -123,7 +122,7 @@ Analytics.prototype._rebuildFirmwareEvent = function () { this.setDimension(this.DIMENSIONS.FIRMWARE_SOURCE, this._firmwareData[this.DATA.FIRMWARE_SOURCE]); this.setDimension(this.DIMENSIONS.FIRMWARE_ERASE_ALL, this._firmwareData[this.DATA.FIRMWARE_ERASE_ALL]); this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]); - this._analytics.set('eventLabel', this._firmwareData[this.DATA.FIRMWARE_CHECKSUM]); + this._googleAnalytics.set('eventLabel', this._firmwareData[this.DATA.FIRMWARE_CHECKSUM]); } Analytics.prototype.setFirmwareData = function (property, value) { From d9e8330997d1d21c5c5fbf436a271361e1dafe38 Mon Sep 17 00:00:00 2001 From: mikeller Date: Fri, 10 Aug 2018 09:01:07 +1200 Subject: [PATCH 062/104] Added more metrics, fixed bug in CLI save. --- src/js/Analytics.js | 24 +++++++++++++++++++++--- src/js/backup_restore.js | 3 +++ src/js/tabs/cli.js | 5 +++-- src/js/tabs/firmware_flasher.js | 6 ++++-- src/js/tabs/onboard_logging.js | 23 ++++++++++++++++++++++- 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/js/Analytics.js b/src/js/Analytics.js index 8647dc14a..474c41643 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -31,15 +31,18 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op this.DATA = { BOARD_TYPE: 'boardType', + API_VERSION: 'apiVersion', FIRMWARE_TYPE: 'firmwareType', FIRMWARE_VERSION: 'firmwareVersion', - API_VERSION: 'apiVersion', - MCU_ID: 'mcuId', FIRMWARE_NAME: 'firmwareName', FIRMWARE_CHECKSUM: 'firmwareChecksum', FIRMWARE_SOURCE: 'firmwareSource', FIRMWARE_CHANNEL: 'firmwareChannel', FIRMWARE_ERASE_ALL: 'firmwareEraseAll', + FIRMWARE_SIZE: 'firmwareSize', + MCU_ID: 'mcuId', + LOGGING_STATUS: 'loggingStatus', + LOG_SIZE: 'logSize', }; this.DIMENSIONS = { @@ -53,6 +56,13 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_ERASE_ALL: 8, CONFIGURATOR_EXPERT_MODE: 9, FIRMWARE_CHANNEL: 10, + LOGGING_STATUS: 11, + MCU_ID: 12, + }; + + this.METRICS = { + FIRMWARE_SIZE: 1, + LOG_SIZE: 2, }; this.setDimension(this.DIMENSIONS.CONFIGURATOR_BUILD_TYPE, buildType); @@ -66,6 +76,11 @@ Analytics.prototype.setDimension = function (dimension, value) { this._googleAnalytics.custom(dimensionName, value); } +Analytics.prototype.setMetric = function (metric, value) { + var metricName = 'metric' + metric; + this._googleAnalytics.custom(metricName, value); +} + Analytics.prototype.sendEvent = function (category, action, options) { this._googleAnalytics.event(category, action, options); } @@ -102,7 +117,9 @@ Analytics.prototype._rebuildFlightControllerEvent = function () { this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this._flightControllerData[this.DATA.FIRMWARE_TYPE]); this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this._flightControllerData[this.DATA.FIRMWARE_VERSION]); this.setDimension(this.DIMENSIONS.API_VERSION, this._flightControllerData[this.DATA.API_VERSION]); - this._googleAnalytics.set('eventLabel', this._flightControllerData[this.DATA.MCU_ID]); + this.setDimension(this.DIMENSIONS.LOGGING_STATUS, this._flightControllerData[this.DATA.LOGGING_STATUS]); + this.setDimension(this.DIMENSIONS.MCU_ID, this._flightControllerData[this.DATA.MCU_ID]); + this.setMetric(this.METRICS.LOG_SIZE, this._flightControllerData[this.DATA.LOG_SIZE]); } Analytics.prototype.setFlightControllerData = function (property, value) { @@ -122,6 +139,7 @@ Analytics.prototype._rebuildFirmwareEvent = function () { this.setDimension(this.DIMENSIONS.FIRMWARE_SOURCE, this._firmwareData[this.DATA.FIRMWARE_SOURCE]); this.setDimension(this.DIMENSIONS.FIRMWARE_ERASE_ALL, this._firmwareData[this.DATA.FIRMWARE_ERASE_ALL]); this.setDimension(this.DIMENSIONS.FIRMWARE_CHANNEL, this._firmwareData[this.DATA.FIRMWARE_CHANNEL]); + this.setMetric(this.METRICS.FIRMWARE_SIZE, this._firmwareData[this.DATA.FIRMWARE_SIZE]); this._googleAnalytics.set('eventLabel', this._firmwareData[this.DATA.FIRMWARE_CHECKSUM]); } diff --git a/src/js/backup_restore.js b/src/js/backup_restore.js index 7e106a2ba..284895103 100644 --- a/src/js/backup_restore.js +++ b/src/js/backup_restore.js @@ -254,6 +254,7 @@ function configuration_backup(callback) { return; } + analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Backup'); console.log('Write SUCCESSFUL'); if (callback) callback(); }; @@ -337,6 +338,8 @@ function configuration_restore(callback) { configuration.FEATURE_CONFIG.features = features; } + analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Restore'); + configuration_upload(configuration, callback); } else { GUI.log(i18n.getMessage('backupFileIncompatible')); diff --git a/src/js/tabs/cli.js b/src/js/tabs/cli.js index db34a4aa0..4fbb55a93 100644 --- a/src/js/tabs/cli.js +++ b/src/js/tabs/cli.js @@ -60,7 +60,6 @@ TABS.cli.initialize = function (callback) { var textarea = $('.tab-cli textarea'); $('.tab-cli .save').click(function() { - var prefix = 'cli'; var suffix = 'txt'; @@ -87,9 +86,11 @@ TABS.cli.initialize = function (callback) { }; writer.onwriteend = function () { - if (writer.length === 0) { + if (self.outputHistory.length > 0 && writer.length === 0) { writer.write(new Blob([self.outputHistory], {type: 'text/plain'})); } else { + analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'CliSave', self.outputHistory.length); + console.log('write complete'); } }; diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index f108dadee..5d17f5af3 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -56,12 +56,12 @@ TABS.firmware_flasher.initialize = function (callback) { parsed_hex = data; if (parsed_hex) { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SIZE, parsed_hex.bytes_total); + if (!FirmwareCache.has(summary)) { FirmwareCache.put(summary, intel_hex); } - var url; - $('span.progressLabel').html('Loaded Online Firmware: (' + parsed_hex.bytes_total + ' bytes)'); $('a.flash_firmware').removeClass('disabled'); @@ -367,6 +367,8 @@ TABS.firmware_flasher.initialize = function (callback) { parsed_hex = data; if (parsed_hex) { + analytics.setFirmwareData(analytics.DATA.FIRMWARE_SIZE, parsed_hex.bytes_total); + $('a.flash_firmware').removeClass('disabled'); $('span.progressLabel').text(i18n.getMessage('firmwareFlasherFirmwareLocalLoaded', parsed_hex.bytes_total)); diff --git a/src/js/tabs/onboard_logging.js b/src/js/tabs/onboard_logging.js index 92937ac9b..0c41b141e 100644 --- a/src/js/tabs/onboard_logging.js +++ b/src/js/tabs/onboard_logging.js @@ -153,6 +153,8 @@ TABS.onboard_logging.initialize = function (callback) { .toggleClass("msc-supported", true); $('a.onboardLoggingRebootMsc').click(function () { + analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'RebootMsc'); + var buffer = []; buffer.push(2); MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false); @@ -298,6 +300,8 @@ TABS.onboard_logging.initialize = function (callback) { } function update_html() { + var dataflashPresent = DATAFLASH.totalSize > 0; + update_bar_width($(".tab-onboard_logging .dataflash-used"), DATAFLASH.usedSize, DATAFLASH.totalSize, i18n.getMessage('dataflashUsedSpace'), false); update_bar_width($(".tab-onboard_logging .dataflash-free"), DATAFLASH.totalSize - DATAFLASH.usedSize, DATAFLASH.totalSize, i18n.getMessage('dataflashFreeSpace'), false); @@ -312,7 +316,7 @@ TABS.onboard_logging.initialize = function (callback) { .toggleClass("sdcard-ready", SDCARD.state === MSP.SDCARD_STATE_READY); if (semver.gte(CONFIG.apiVersion, "1.40.0")) { - var mscIsReady = (DATAFLASH.totalSize > 0) || (SDCARD.state === MSP.SDCARD_STATE_READY); + var mscIsReady = dataflashPresent || (SDCARD.state === MSP.SDCARD_STATE_READY); $(".tab-onboard_logging") .toggleClass("msc-not-ready", !mscIsReady); @@ -323,26 +327,38 @@ TABS.onboard_logging.initialize = function (callback) { } } + var loggingStatus switch (SDCARD.state) { case MSP.SDCARD_STATE_NOT_PRESENT: $(".sdcard-status").text(i18n.getMessage('sdcardStatusNoCard')); + loggingStatus = 'SdCard: NotPresent'; break; case MSP.SDCARD_STATE_FATAL: $(".sdcard-status").html(i18n.getMessage('sdcardStatusReboot')); + loggingStatus = 'SdCard: Error'; break; case MSP.SDCARD_STATE_READY: $(".sdcard-status").text(i18n.getMessage('sdcardStatusReady')); + loggingStatus = 'SdCard: Ready'; break; case MSP.SDCARD_STATE_CARD_INIT: $(".sdcard-status").text(i18n.getMessage('sdcardStatusStarting')); + loggingStatus = 'SdCard: Init'; break; case MSP.SDCARD_STATE_FS_INIT: $(".sdcard-status").text(i18n.getMessage('sdcardStatusFileSystem')); + loggingStatus = 'SdCard: FsInit'; break; default: $(".sdcard-status").text(i18n.getMessage('sdcardStatusUnknown',[SDCARD.state])); } + if (dataflashPresent && SDCARD.state === MSP.SDCARD_STATE_NOT_PRESENT) { + loggingStatus = 'Dataflash'; + analytics.setFlightControllerData(analytics.DATA.LOG_SIZE, DATAFLASH.usedSize); + } + analytics.setFlightControllerData(analytics.DATA.LOGGING_STATUS, loggingStatus); + if (SDCARD.supported && !sdcardTimer) { // Poll for changes in SD card status sdcardTimer = setTimeout(function() { @@ -374,6 +390,8 @@ TABS.onboard_logging.initialize = function (callback) { } function mark_saving_dialog_done(startTime, totalBytes, totalBytesCompressed) { + analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'SaveDataflash'); + var totalTime = (new Date().getTime() - startTime) / 1000; console.log('Received ' + totalBytes + ' bytes in ' + totalTime.toFixed(2) + 's (' + (totalBytes / totalTime / 1024).toFixed(2) + 'kB / s) with block size ' + self.blockSize + '.'); @@ -539,6 +557,9 @@ TABS.onboard_logging.initialize = function (callback) { }; TABS.onboard_logging.cleanup = function (callback) { + analytics.setFlightControllerData(analytics.DATA.LOGGING_STATUS, undefined); + analytics.setFlightControllerData(analytics.DATA.LOG_SIZE, undefined); + if (sdcardTimer) { clearTimeout(sdcardTimer); sdcardTimer = false; From 9025430bee3a46c428d0f4d62df730237e46e446 Mon Sep 17 00:00:00 2001 From: Sean M Date: Thu, 9 Aug 2018 22:47:29 -0400 Subject: [PATCH 063/104] Updating UI for interpolation / fixing alignment --- locales/en/messages.json | 3 +++ src/css/tabs/receiver.css | 4 ++++ src/js/msp/MSPHelper.js | 14 +++++++++--- src/js/tabs/receiver.js | 10 +++++++- src/tabs/receiver.html | 48 +++++---------------------------------- 5 files changed, 33 insertions(+), 46 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index cd524e25e..98c558fe4 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1333,6 +1333,9 @@ "receiverRcInterpolationOff": { "message": "Off" }, + "receiverRcSmoothingType": { + "message": "Smoothing Type" + }, "receiverRcInterpolationDefault": { "message": "Preset" }, diff --git a/src/css/tabs/receiver.css b/src/css/tabs/receiver.css index 1ef407be2..f59c8073a 100644 --- a/src/css/tabs/receiver.css +++ b/src/css/tabs/receiver.css @@ -410,6 +410,10 @@ margin-right: 10px; } +.tab-receiver .rcInterpolation-label { + border-right: none; +} + .tab-receiver .throttle_curve { margin: 0 0px 0px 0; width: 200px; diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js index bf51b42e2..31f24533e 100644 --- a/src/js/msp/MSPHelper.js +++ b/src/js/msp/MSPHelper.js @@ -764,9 +764,6 @@ MspHelper.prototype.process_data = function(dataHandler) { RX_CONFIG.spektrum_sat_bind = data.readU8(); RX_CONFIG.rx_min_usec = data.readU16(); RX_CONFIG.rx_max_usec = data.readU16(); - RX_CONFIG.rcInterpolation = 0; - RX_CONFIG.rcInterpolationInterval = 0; - RX_CONFIG.airModeActivateThreshold = 0; if (semver.gte(CONFIG.apiVersion, "1.20.0")) { RX_CONFIG.rcInterpolation = data.readU8(); RX_CONFIG.rcInterpolationInterval = data.readU8(); @@ -784,8 +781,19 @@ MspHelper.prototype.process_data = function(dataHandler) { RX_CONFIG.rcSmoothingInputType = data.readU8(); RX_CONFIG.rcSmoothingDerivativeType = data.readU8(); } + } else { + RX_CONFIG.rxSpiProtocol = 0; + RX_CONFIG.rxSpiId = 0; + RX_CONFIG.rxSpiRfChannelCount = 0; + RX_CONFIG.fpvCamAngleDegrees = 0; } + } else { + RX_CONFIG.rcInterpolation = 0; + RX_CONFIG.rcInterpolationInterval = 0; + RX_CONFIG.airModeActivateThreshold = 0; } + + break; case MSPCodes.MSP_FAILSAFE_CONFIG: diff --git a/src/js/tabs/receiver.js b/src/js/tabs/receiver.js index 467f8be73..1b08bf905 100644 --- a/src/js/tabs/receiver.js +++ b/src/js/tabs/receiver.js @@ -325,7 +325,6 @@ TABS.receiver.initialize = function (callback) { }); // RC Smoothing - $('.tab-receiver .rcSmoothing').hide(); if (semver.gte(CONFIG.apiVersion, "1.40.0")) { $('.tab-receiver .rcSmoothing').show(); @@ -403,6 +402,15 @@ TABS.receiver.initialize = function (callback) { rc_smoothing_input_type.val(RX_CONFIG.rcSmoothingInputType); updateInterpolationView(); + } else { + $('.tab-receiver .rcInterpolation').show(); + $('.tab-receiver .rcSmoothing-derivative-cutoff').hide(); + $('.tab-receiver .rcSmoothing-input-cutoff').hide(); + $('.tab-receiver .rcSmoothing-derivative-type').hide(); + $('.tab-receiver .rcSmoothing-input-type').hide(); + $('.tab-receiver .rcSmoothing-derivative-manual').hide(); + $('.tab-receiver .rcSmoothing-input-manual').hide(); + $('.tab-receiver .rc-smoothing-type').hide(); } // Only show the MSP control sticks if the MSP Rx feature is enabled diff --git a/src/tabs/receiver.html b/src/tabs/receiver.html index 2b5577722..eee11f755 100644 --- a/src/tabs/receiver.html +++ b/src/tabs/receiver.html @@ -78,42 +78,6 @@
-
@@ -129,7 +93,7 @@ @@ -173,8 +137,8 @@ - - + - - + - - - -
+
+
- +
-
-
+
-
-
From 5a3bda615d37a4305f9980b2043bf8a5b6292f8f Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 12 Aug 2018 15:55:34 +1200 Subject: [PATCH 066/104] Fixed wrong localisation, moved to single column display. --- locales/en/messages.json | 21 ------------ src/css/tabs/receiver.css | 25 ++++++++++---- src/tabs/receiver.html | 70 +++++++++++++++++++++++---------------- 3 files changed, 59 insertions(+), 57 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index 820eb0195..a038e28a2 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -1332,12 +1332,6 @@ "receiverRcSmoothingDerivativeCutoff": { "message": "Derivative Cutoff Frequency" }, - "receiverRcSmoothingInputTypeBiquad": { - "message": "BIQUAD" - }, - "receiverRcSmoothingInputTypePt1": { - "message": "PT1" - }, "receiverRcInputType": { "message": "Input Filter Type" }, @@ -1347,21 +1341,6 @@ "receiverRcSmoothingDerivativeTypeOff": { "message": "Off" }, - "receiverRcSmoothingChannelsRP": { - "message": "RP" - }, - "receiverRcSmoothingChannelsRPY": { - "message": "Y" - }, - "receiverRcSmoothingChannelsRPYT": { - "message": "RPYT" - }, - "receiverRcSmoothingChannelsT": { - "message": "T" - }, - "receiverRcSmoothingChannelsRPT": { - "message": "RPT" - }, "receiverRcSmoothingChannel": { "message": "Channels Smoothed" }, diff --git a/src/css/tabs/receiver.css b/src/css/tabs/receiver.css index f59c8073a..cfd026125 100644 --- a/src/css/tabs/receiver.css +++ b/src/css/tabs/receiver.css @@ -315,7 +315,6 @@ padding-left: 5px; border: 1px solid silver; margin: 4px; - width: calc(100% - 8px); } .tab-receiver .rcSmoothing-input-manual select { @@ -335,6 +334,13 @@ } .tab-receiver .rc-smoothing-type { + margin-bottom: 5px; + clear: left; + padding-bottom: 5px; + width: 100%; +} + +.tab-receiver .rc-smoothing-channels { margin-bottom: 5px; clear: left; padding-bottom: 5px; @@ -350,13 +356,22 @@ width: calc(100% - 8px); } -.tab-receiver .rcSmoothing-channels select { +.tab-receiver .rc-smoothing-channels select { + height: 22px; + padding-left: 5px; + border: 1px solid silver; + margin: 4px; + width: calc(100% - 8px); +} + +.tab-receiver .rcSmoothing-input-type select { height: 22px; padding-left: 5px; border: 1px solid silver; margin: 4px; width: calc(100% - 8px); } + .tab-receiver .rcSmoothing-input-type select { height: 22px; padding-left: 5px; @@ -388,7 +403,7 @@ } .tab-receiver .rcSmoothing td:first-child { - width: 70px; + width: 120px; padding-left:8px; border-right: none; } @@ -397,10 +412,6 @@ width: calc(100% - 78px); } -.tab-receiver .rcSmoothing select { - width: 66px; -} - .tab-receiver .rcInterpolation .slider input { -webkit-appearance: slider-horizontal; } diff --git a/src/tabs/receiver.html b/src/tabs/receiver.html index bced79987..cd3bd1376 100644 --- a/src/tabs/receiver.html +++ b/src/tabs/receiver.html @@ -81,10 +81,10 @@
- + - - + + - + + + + + + + - + + - - - - + + + + + + + - - - - + + + + - - - - + + + + - - - - + + + + From 7efd76304361a19db9e82fa7dceb221f9b2acf9a Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 13 Aug 2018 12:22:09 +0200 Subject: [PATCH 071/104] Update Chinese Simplified --- locales/zh_CN/messages.json | 181 +++++++++++++++++++++++++++++++++--- 1 file changed, 168 insertions(+), 13 deletions(-) diff --git a/locales/zh_CN/messages.json b/locales/zh_CN/messages.json index 7286d298f..dd5b12aba 100644 --- a/locales/zh_CN/messages.json +++ b/locales/zh_CN/messages.json @@ -2,12 +2,21 @@ "error": { "message": "错误: {{errorMessage}}" }, + "errorTitle": { + "message": "错误" + }, "warningTitle": { "message": "警告" }, "noticeTitle": { "message": "注意" }, + "operationNotSupported": { + "message": "您的硬件不支持此操作。" + }, + "storageDeviceNotReady": { + "message": "存储设备尚未就绪。如果是 microSD 卡, 请确保它已被飞控正确识别。" + }, "options_title": { "message": "选项" }, @@ -44,6 +53,12 @@ "permanentExpertMode": { "message": "默认启用专家模式" }, + "rememberLastTab": { + "message": "连接后重新打开最后使用的选项页" + }, + "analyticsOptOut": { + "message": "退出匿名的统计数据收集" + }, "userLanguageSelect": { "message": "语言 (需要重启应用才能生效)" }, @@ -326,6 +341,15 @@ "message": "操作系统: {{operatingSystem}}<\/strong>, Chrome: {{chromeVersion}}<\/strong>, 配置程序: {{configuratorVersion}}<\/strong>", "description": "Message that appears in the GUI log panel indicating operating system, Chrome version and Configurator version" }, + "buildServerLoaded": { + "message": "已从生成服务器加载 $1 的生成信息。" + }, + "buildServerLoadFailed": { + "message": "从生成服务器获取 $1 发布版本失败,使用已缓存的信息。 失败原因:$2<\/code><\/b>" + }, + "buildServerUsingCached": { + "message": "为 $1 使用已缓存的生成信息。" + }, "releaseCheckLoaded": { "message": "从Github 载入 $1 发布信息" }, @@ -438,7 +462,7 @@ "message": "硬件" }, "defaultWelcomeText": { - "message": "本应用支持所有能运行betaflight的飞控。在”固件烧写“页面查看所有支持的飞控列表。

下载 Betaflight Blackbox Explorer<\/a>

固件源代码可以点击
这里<\/a> 下载
最新发布已编译的固件可以点击
这里<\/a> 下载

最新的
CP210x 驱动<\/a> 可以点击 这里<\/a> 下载
最新的
STM USB VCP Drivers<\/a> 可以点击 这里<\/a> 下载
最新的
Zadig<\/a>可以点击 这里<\/a> 下载
" + "message": "本应用支持所有能运行betaflight的飞控。在”固件烧写“页面查看所有支持的飞控列表。

下载 Betaflight Blackbox 日志查看工具 <\/a>

固件源代码可以点击
这里<\/a> 下载
最新发布已编译的固件可以点击
这里<\/a> 下载

最新的
CP210x 驱动<\/a> 可以点击 这里<\/a> 下载
最新的
STM USB VCP Drivers<\/a> 可以点击 这里<\/a> 下载
最新的
Zadig<\/a>可以点击 这里<\/a> 下载
" }, "defaultContributingHead": { "message": "参与开发" @@ -446,12 +470,18 @@ "defaultContributingText": { "message": "如果你想帮助betaflight变得更好,你可以:
+ + From 9c4bf731014d8955d805a28ab90deb9342280e9c Mon Sep 17 00:00:00 2001 From: Sean M Date: Thu, 13 Sep 2018 20:01:03 -0400 Subject: [PATCH 101/104] Select first value in drop down upon enabling expert mode --- src/js/tabs/firmware_flasher.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index 173eb08dc..fcc9f93d5 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -252,6 +252,7 @@ TABS.firmware_flasher.initialize = function (callback) { buildTypesToShow.forEach((build, index) => { buildType_e.append($("".format(index, build.tag ? i18n.getMessage(build.tag) : build.title))) }); + $('select[name="build_type"]').val($('select[name="build_type"] option:first').val()); } function showOrHideBuildTypes() { From e8103b24785ae3b9d3d5731aae4f65af61ea7b08 Mon Sep 17 00:00:00 2001 From: Miguel Angel Mulero Martinez Date: Mon, 17 Sep 2018 16:55:14 +0200 Subject: [PATCH 102/104] Add Russian language --- assets/windows/installer.nsi | 1 + locales/en/messages.json | 3 + locales/ru/messages.json | 3732 ++++++++++++++++++++++++++++++++++ src/js/localization.js | 2 +- 4 files changed, 3737 insertions(+), 1 deletion(-) create mode 100644 locales/ru/messages.json diff --git a/assets/windows/installer.nsi b/assets/windows/installer.nsi index 43e1caf0a..1198ffc96 100644 --- a/assets/windows/installer.nsi +++ b/assets/windows/installer.nsi @@ -54,6 +54,7 @@ OutFile "..\..\${DEST_FOLDER}\${FILE_NAME_INSTALLER}" !insertmacro MUI_LANGUAGE "Korean" !insertmacro MUI_LANGUAGE "Latvian" !insertmacro MUI_LANGUAGE "Portuguese" +!insertmacro MUI_LANGUAGE "Russian" !insertmacro MUI_LANGUAGE "SimpChinese" !insertmacro MUI_LANGUAGE "Spanish" !insertmacro MUI_LANGUAGE "Swedish" diff --git a/locales/en/messages.json b/locales/en/messages.json index 7d1be9239..5a1fb045c 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -105,6 +105,9 @@ "language_pt": { "message": "Portugu\u00EAs (pt)" }, + "language_ru": { + "message": "\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u044F\u0437\u044B\u043A (ru)" + }, "language_sv": { "message": "Svenska (sv)" }, diff --git a/locales/ru/messages.json b/locales/ru/messages.json new file mode 100644 index 000000000..e0e84974f --- /dev/null +++ b/locales/ru/messages.json @@ -0,0 +1,3732 @@ +{ + "error": { + "message": "Ошибка: {{errorMessage}}" + }, + "errorTitle": { + "message": "Ошибка" + }, + "warningTitle": { + "message": "Внимание!" + }, + "noticeTitle": { + "message": "Сообщение" + }, + "operationNotSupported": { + "message": "Операция не поддерживается устройством." + }, + "storageDeviceNotReady": { + "message": "Запоминающее устройство не готово. В случае использования microSD карты, убедитесь, что она правильно распознана вашим полетным контроллером." + }, + "options_title": { + "message": "Настройка приложения" + }, + "connect": { + "message": "Подключится" + }, + "connecting": { + "message": "Подключение" + }, + "disconnect": { + "message": "Отключить" + }, + "portsSelectManual": { + "message": "Выбрать вручную" + }, + "portOverrideText": { + "message": "Порт:" + }, + "autoConnect": { + "message": "Подключаться автоматически" + }, + "close": { + "message": "Закрыть" + }, + "autoConnectEnabled": { + "message": "Подключаться автоматически - конфигуратор будет подключаться при обнаружении нового порта" + }, + "autoConnectDisabled": { + "message": "Подключаться автоматически: если выключен, то вручную выбираем нужный порт и кликаем \"Подключить\"" + }, + "expertMode": { + "message": "Включить режим эксперта" + }, + "expertModeDescription": { + "message": "Показать невыпущенные и потенциально нестабильные сборки" + }, + "permanentExpertMode": { + "message": "Всегда включать режим эксперта" + }, + "rememberLastTab": { + "message": "Повторно открыть последнюю вкладку при подключении" + }, + "analyticsOptOut": { + "message": "Отказ от анонимной коллекции статистических данных" + }, + "userLanguageSelect": { + "message": "Язык (необходимо перезапустить приложение, чтобы изменения вступили в силу)" + }, + "language_default": { + "message": "По умолчанию" + }, + "sensorDataFlashNotFound": { + "message": "Отсутствует
модуль памяти", + "description": "Text of the dataflash image in the header of the page." + }, + "sensorDataFlashFreeSpace": { + "message": "Данные: доступное место", + "description": "Text of the dataflash image in the header of the page." + }, + "sensorStatusGyro": { + "message": "Гироскоп" + }, + "sensorStatusGyroShort": { + "message": "Гироскоп", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "sensorStatusAccel": { + "message": "Акселерометр" + }, + "sensorStatusAccelShort": { + "message": "Акселерометр", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "sensorStatusMag": { + "message": "Магнитометр" + }, + "sensorStatusMagShort": { + "message": "Компас", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "sensorStatusBaro": { + "message": "Барометр" + }, + "sensorStatusBaroShort": { + "message": "Барометр", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "sensorStatusGPS": { + "message": "GPS" + }, + "sensorStatusGPSShort": { + "message": "GPS", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "sensorStatusSonar": { + "message": "Сонар\/Дальномер" + }, + "sensorStatusSonarShort": { + "message": "Сонар", + "description": "Text of the image in the top sensors icons. Please keep it short." + }, + "checkForConfiguratorUnstableVersions": { + "message": "Показывать уведомления о появлении нестабильных версий конфигуратора" + }, + "configuratorUpdateNotice": { + "message": "Вы используете устаревшую версию Betaflight конфигуратора<\/b>.
Новая версия $1<\/b> доступна для скачивания, пожалуйста, посетите
страницу с релизами<\/a> для загрузки и установки самой последней версии с исправлениями и улучшениями.
Пожалуйста, закройте окно конфигуратора перед обновлением." + }, + "configuratorUpdateWebsite": { + "message": "Перейти на сайт с релизами" + }, + "deviceRebooting": { + "message": "Device - Перезагружается<\/span>" + }, + "deviceReady": { + "message": "Устройство - Готово<\/span>" + }, + "backupFileIncompatible": { + "message": "Файл резервной копии был сгенерирован для предыдущей версии и несовместимым с этой версией конфигуратора. Извините" + }, + "backupFileUnmigratable": { + "message": "Файл резервной копии был сгенерирован старой версией конфигуратора и не является мигрируемым для этой версии конфигуратора. Сожалеем." + }, + "configMigrationFrom": { + "message": "Миграция файла конфигурации была сгенерирована конфигуратором версии: $1" + }, + "configMigratedTo": { + "message": "Конфигурация мигрирована для конфигуратора версии: $1" + }, + "configMigrationSuccessful": { + "message": "Миграция конфигурации завершена, применено миграций: $1" + }, + "tabFirmwareFlasher": { + "message": "Программатор" + }, + "tabLanding": { + "message": "Приветствие" + }, + "tabHelp": { + "message": "Документация и поддержка" + }, + "tabSetup": { + "message": "Система" + }, + "tabSetupOSD": { + "message": "Установки OSD" + }, + "tabConfiguration": { + "message": "Конфигурация" + }, + "tabPorts": { + "message": "Порты" + }, + "tabPidTuning": { + "message": "PID настройки" + }, + "tabReceiver": { + "message": "Приёмник" + }, + "tabModeSelection": { + "message": "Переключение режимов" + }, + "tabServos": { + "message": "Сервоприводы" + }, + "tabFailsafe": { + "message": "Failsafe" + }, + "tabTransponder": { + "message": "Транспондер гонки" + }, + "tabOsd": { + "message": "OSD" + }, + "tabPower": { + "message": "Питание и Батарея" + }, + "tabGPS": { + "message": "GPS" + }, + "tabMotorTesting": { + "message": "Моторы" + }, + "tabLedStrip": { + "message": "LED лента" + }, + "tabRawSensorData": { + "message": "Датчики" + }, + "tabCLI": { + "message": "Командная строка" + }, + "tabLogging": { + "message": "Логирование через кабель" + }, + "tabOnboardLogging": { + "message": "Чёрный ящик" + }, + "tabAdjustments": { + "message": "Корректирование в полёте" + }, + "tabAuxiliary": { + "message": "Режимы" + }, + "logActionHide": { + "message": "Скрыть недавние действия" + }, + "logActionShow": { + "message": "Показать недавние действия" + }, + "serialPortOpened": { + "message": "Сериний порт успешно<\/span> открыт. ID порта: $1" + }, + "serialPortOpenFail": { + "message": "Не удалось<\/span> открыть сериний порт" + }, + "serialPortClosedOk": { + "message": "Сериний порт успешно<\/span> закрыт" + }, + "serialPortClosedFail": { + "message": "Не удалось<\/span> закрыть сериний порт" + }, + "serialUnrecoverable": { + "message": "Невосстановимый сбой<\/span> последовательного подключения, разъединяюсь..." + }, + "usbDeviceOpened": { + "message": "USB устройство успешно<\/span> подключено. ID подключения: $1" + }, + "usbDeviceOpenFail": { + "message": "Сбой<\/span> подключения к USB устройству!" + }, + "usbDeviceClosed": { + "message": "USB устройство успешно<\/span> отключено" + }, + "usbDeviceCloseFail": { + "message": "Сбой<\/span> при отключении USB устройства" + }, + "usbDeviceUdevNotice": { + "message": "Правильно ли установлены udev права<\/strong>? Смотрите инструкцию в документации" + }, + "stm32UsbDfuNotFound": { + "message": "USB DFU не найден" + }, + "stm32TimedOut": { + "message": "STM32 - не отвечает, процесс прошивки: СБОЙ" + }, + "stm32WrongResponse": { + "message": "STM32 Сбой связи, неправильный ответ, ожидалось: $1 (0x$2), а принято: $3 (0x$4)" + }, + "stm32ContactingBootloader": { + "message": "Подключение к загрузчику ..." + }, + "stm32ContactingBootloaderFailed": { + "message": "Сбой подключения к загрузчику" + }, + "stm32ResponseBootloaderFailed": { + "message": "Загрузчик не отвечает, процесс прошивки: СБОЙ" + }, + "stm32GlobalEraseExtended": { + "message": "Выполняется глобальная очистка чипа (путём расширенного стирания) ..." + }, + "stm32LocalEraseExtended": { + "message": "Выполняется локальная очистка (путём расширенного стирания) ..." + }, + "stm32GlobalErase": { + "message": "Выполняется глобальное стирание чипа ..." + }, + "stm32LocalErase": { + "message": "Выполняется локальное стирание ..." + }, + "stm32Erase": { + "message": "Очистка ..." + }, + "stm32Flashing": { + "message": "Прошивка ..." + }, + "stm32Verifying": { + "message": "Проверка ..." + }, + "stm32ProgrammingSuccessful": { + "message": "Прошивка: УСПЕШНО" + }, + "stm32ProgrammingFailed": { + "message": "Прошивка: СБОЙ" + }, + "stm32AddressLoadFailed": { + "message": "Сбой чтения адреса для option bytes. Скорее всего установлена защита от чтения." + }, + "stm32AddressLoadSuccess": { + "message": "Чтение адреса для option bytes успешно." + }, + "stm32AddressLoadUnknown": { + "message": "Сбой чтения адреса для option bytes с неизвестной ошибкой. Отмена ..." + }, + "stm32NotReadProtected": { + "message": "Защита чтения не установлена" + }, + "stm32ReadProtected": { + "message": "Видимо плата защищена от чтения. Снимаю защиту от чтения. Не отключайте устройство!" + }, + "stm32UnprotectSuccessful": { + "message": "Защита от чтения успешно снята." + }, + "stm32UnprotectUnplug": { + "message": "ТРЕБУЕТСЯ ДЕЙСТВИЕ: Отключите и снова подключите полётный контроллер в DFU-режиме, чтобы его можно было прошить." + }, + "stm32UnprotectFailed": { + "message": "Не удалось снять защиту от чтения с платы" + }, + "stm32UnprotectInitFailed": { + "message": "Не удалось начать процесс снятия защиты от чтения" + }, + "noConfigurationReceived": { + "message": "No configuration received within 10 seconds<\/span>, communication failed<\/span>" + }, + "firmwareVersionNotSupported": { + "message": "Версия этой прошивки не поддерживается<\/span> данным конфигуратором. Пожалуйста, обновите прошивку, которая поддерживает версию конфигуратора $1<\/strong> или выше. Используйте командную строку, чтобы сделать резервную копию прошивки перед тем, как обновлять прошивку. Процедура создания\/восстановления резервной копии описана в документации.
Если вы не хотите обновлять прошивку, то используйте более старую версию конфигуратора." + }, + "firmwareTypeNotSupported": { + "message": "Прошивки, кроме Cleanflight\/Betaflight не поддерживаются<\/span>, но для них доступен режим командной строки." + }, + "firmwareUpgradeRequired": { + "message": "Прошивка в этом устройстве нуждается в обновлении до новой версии. Используйте командную строку, чтобы сделать резервную копию перед обновлением прошивки. Процедура создания\/восстановления резервной копии описана в документации.
Если вы не хотите обновлять прошивку, то используйте более старую версию конфигуратора." + }, + "infoVersions": { + "message": "Запуск - ОС: {{operatingSystem}}<\/strong>, Chrome: {{chromeVersion}}<\/strong>, Конфигуратор: {{configuratorVersion}}<\/strong>", + "description": "Message that appears in the GUI log panel indicating operating system, Chrome version and Configurator version" + }, + "buildServerLoaded": { + "message": "Загружена информация о сборках для $1 от сервера сборки." + }, + "buildServerLoadFailed": { + "message": "Не удалось запросить информацию о выпуске $1 из GitHub, используется информация из кэша. Причина: $2<\/code><\/b>" + }, + "buildServerUsingCached": { + "message": "Использование кэшированной информации о сборках для $1." + }, + "releaseCheckLoaded": { + "message": "Из GitHub загружена информация о выпуске для $1." + }, + "releaseCheckFailed": { + "message": "Не удалось запросить информацию о выпуске $1 из GitHub, используется информация из кэша. Причина: $2<\/code><\/b>" + }, + "releaseCheckCached": { + "message": "Использована информация из кэша о выпусках $1." + }, + "releaseCheckNoInfo": { + "message": "Для $1 отсутствует информация о выпуске." + }, + "tabSwitchConnectionRequired": { + "message": "Вам нужно подключиться<\/strong> прежде чем увидеть любую из этих вкладок." + }, + "tabSwitchWaitForOperation": { + "message": "Вы не можете<\/span> сделать это прямо сейчас, пожалуйста, дождитесь завершения текущей операции ..." + }, + "tabSwitchUpgradeRequired": { + "message": "Вам нужно обновить<\/strong> прошивку до последней версии Betaflight прежде чем использовать вкладку $1." + }, + "firmwareVersion": { + "message": "Версия прошивки: $1<\/strong>" + }, + "apiVersionReceived": { + "message": "MultiWii API версия: $1<\/strong>" + }, + "uniqueDeviceIdReceived": { + "message": "Уникальный ID устройства: 0x$1<\/strong>" + }, + "craftNameReceived": { + "message": "Позывной пилота: $1<\/strong>" + }, + "armingDisabled": { + "message": "Arming выключен<\/strong>" + }, + "armingEnabled": { + "message": "Arming включён<\/strong>" + }, + "runawayTakeoffPreventionDisabled": { + "message": "Временное отключение функции Runaway Takeoff Prevention<\/strong>" + }, + "runawayTakeoffPreventionEnabled": { + "message": "Функция Runaway Takeoff Prevention включена<\/strong>" + }, + "boardInfoReceived": { + "message": "Плата: $1<\/strong>, версия: $2<\/strong>" + }, + "buildInfoReceived": { + "message": "Используется прошивка, выпущенная в: $1<\/strong>" + }, + "fcInfoReceived": { + "message": "Информация о полётном контроллере, идентификатор: $1<\/strong>, версия: $2<\/strong>" + }, + "versionLabelTarget": { + "message": "Цель" + }, + "versionLabelFirmware": { + "message": "Прошивка" + }, + "versionLabelConfigurator": { + "message": "Конфигуратор" + }, + "notifications_app_just_updated_to_version": { + "message": "Приложение обновлено до версии: $1" + }, + "notifications_click_here_to_start_app": { + "message": "Кликните сюда, чтобы запустить приложение" + }, + "statusbar_port_utilization": { + "message": "Загруженность порта:" + }, + "statusbar_usage_download": { + "message": "D: $1%" + }, + "statusbar_usage_upload": { + "message": "U: $1%" + }, + "statusbar_packet_error": { + "message": "Ошибки пакетов:" + }, + "statusbar_i2c_error": { + "message": "I2C ошибки:" + }, + "statusbar_cycle_time": { + "message": "Время цикла:" + }, + "statusbar_cpu_load": { + "message": "Загрузка CPU: $1%" + }, + "dfu_connect_message": { + "message": "Пожалуйста, используйте \"Программатор\" для доступа к DFU устройств" + }, + "dfu_erased_kilobytes": { + "message": "Успешно<\/span> стёрто $1 kB flash-памяти" + }, + "dfu_device_flash_info": { + "message": "Обнаружено устройство с суммарным размером flash-памяти $1 KiB" + }, + "dfu_error_image_size": { + "message": "Ошибка<\/span>: Этот образ прошивки больше, чем flash-память, доступная в этом чипе! Размер образа: $1 kiB, предельный размер: $2 kiB" + }, + "eeprom_saved_ok": { + "message": "EEPROM сохранён<\/span>" + }, + "defaultWelcomeIntro": { + "message": "Вас приветствует Betaflight конфигуратор<\/strong> - утилита разработанная для лёгкого обновления, конфигурации и настройки вашего полётного контроллера." + }, + "defaultWelcomeHead": { + "message": "Железо" + }, + "defaultWelcomeText": { + "message": "Это приложение поддерживает все устройства, которые могут запускаться в Betaflight конфигураторе. Вы также можете посмотреть весь список поддерживаемых устройств во вкладке \"Программатор\".

Скачать Betaflight Blackbox Log Viewer<\/a>

Исходный код прошивки можно скачать
здесь<\/a>

Последнюю версию
CP210x драйвера<\/a> можно скачать здесь<\/a>
Последнюю версию
STM USB VCP драйвера<\/a> можно скачать здесь<\/a>
Последнюю версию
Zadig<\/a> для установки USB драйвера под Windows можно скачать здесь<\/a>
" + }, + "defaultContributingHead": { + "message": "Содействие" + }, + "defaultContributingText": { + "message": "Если вы хотите сделать Betaflight лучше, вы можете помочь нам несколькими способами:
From a8c18b03bf9a74802e31cbf0558141400c3d10e7 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Sat, 22 Sep 2018 04:37:28 +1200 Subject: [PATCH 104/104] Updated dependency versions to remove vulnerabilities. --- package-lock.json | 1259 ++------------------------------------------- package.json | 2 +- 2 files changed, 55 insertions(+), 1206 deletions(-) diff --git a/package-lock.json b/package-lock.json index f7149d6de..b587f9bee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,28 +23,12 @@ "negotiator": "0.6.1" } }, - "addressparser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", - "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", - "dev": true, - "optional": true - }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -57,49 +41,6 @@ "json-schema-traverse": "^0.3.0" } }, - "amqplib": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", - "dev": true, - "optional": true, - "requires": { - "bitsyntax": "~0.0.4", - "bluebird": "^3.4.6", - "buffer-more-ints": "0.0.2", - "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -425,13 +366,6 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "ast-types": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", - "dev": true, - "optional": true - }, "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", @@ -498,38 +432,6 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "axios": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", - "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", - "dev": true, - "optional": true, - "requires": { - "follow-redirects": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", - "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", - "dev": true, - "optional": true, - "requires": { - "debug": "^2.2.0" - } - } - } - }, "bach": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", @@ -663,16 +565,6 @@ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", "dev": true }, - "bitsyntax": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", - "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", - "dev": true, - "optional": true, - "requires": { - "buffer-more-ints": "0.0.2" - } - }, "bl": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", @@ -711,9 +603,9 @@ "dev": true }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", + "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", "dev": true }, "body-parser": { @@ -745,15 +637,6 @@ } } }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -932,28 +815,6 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "buffer-more-ints": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", - "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=", - "dev": true - }, - "buildmail": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", - "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", - "dev": true, - "optional": true, - "requires": { - "addressparser": "1.0.1", - "libbase64": "0.1.0", - "libmime": "3.0.0", - "libqp": "1.1.0", - "nodemailer-fetch": "1.6.0", - "nodemailer-shared": "1.1.0", - "punycode": "1.4.1" - } - }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", @@ -1211,9 +1072,9 @@ "dev": true }, "colors": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.1.tgz", - "integrity": "sha512-jg/vxRmv430jixZrC+La5kMbUWqIg32/JsYNZb94+JEmzceYbWKTsv1OuTp+7EaqiaWRR2tPcykibwCRgclIsw==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", + "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==", "dev": true }, "combine-lists": { @@ -1240,13 +1101,6 @@ "integrity": "sha512-doWDvhXCcW5LK0cIUWrOQ8oMFXJv3lEQCkJpGVjM8v9SV0uhqYXB943538tEA2CiaWqSyuYUGAm5ezDwEx9xlw==", "dev": true }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true, - "optional": true - }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", @@ -1434,16 +1288,6 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.x.x" - } - }, "crypto-random-string": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", @@ -1480,13 +1324,6 @@ "assert-plus": "^1.0.0" } }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", - "dev": true, - "optional": true - }, "date-format": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", @@ -1535,13 +1372,6 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true, - "optional": true - }, "default-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", @@ -1616,18 +1446,6 @@ } } }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "dev": true, - "optional": true, - "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" - } - }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -1699,13 +1517,6 @@ "is-obj": "^1.0.0" } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", - "dev": true, - "optional": true - }, "duplexer2": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", @@ -1802,9 +1613,9 @@ } }, "engine.io": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", + "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -1812,14 +1623,13 @@ "cookie": "0.3.1", "debug": "~3.1.0", "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", "ws": "~3.3.1" } }, "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -1885,21 +1695,6 @@ "es6-symbol": "^3.1.1" } }, - "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "es6-symbol": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", @@ -1934,49 +1729,6 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", - "dev": true, - "optional": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true, - "optional": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true, - "optional": true - }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -2253,13 +2005,6 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true, - "optional": true - }, "fd-slicer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", @@ -2269,13 +2014,6 @@ "pend": "~1.2.0" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -3039,69 +2777,12 @@ } } }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, - "optional": true, - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true, - "optional": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "optional": true, - "requires": { - "is-property": "^1.0.0" - } - }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -3120,33 +2801,6 @@ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, - "get-uri": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", - "dev": true, - "optional": true, - "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", @@ -3591,17 +3245,6 @@ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, - "har-validator": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", - "dev": true, - "optional": true, - "requires": { - "ajv": "^5.3.0", - "har-schema": "^2.0.0" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3687,42 +3330,12 @@ } } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "optional": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, - "hipchat-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", - "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", - "dev": true, - "optional": true, - "requires": { - "lodash": "^4.0.0", - "request": "^2.0.0" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, "homedir-polyfill": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", @@ -3761,16 +3374,6 @@ "requires-port": "^1.0.0" } }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -3782,36 +3385,10 @@ "sshpk": "^1.7.0" } }, - "httpntlm": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", - "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", - "dev": true, - "requires": { - "httpreq": ">=0.4.22", - "underscore": "~1.7.0" - } - }, - "httpreq": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", - "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, - "i18next": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-10.6.0.tgz", - "integrity": "sha1-kP/Z+bxhfzS5oS4DcmD1JERfdoQ=" + "i18next": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-10.6.0.tgz", + "integrity": "sha1-kP/Z+bxhfzS5oS4DcmD1JERfdoQ=" }, "i18next-xhr-backend": { "version": "1.5.1", @@ -3891,12 +3468,6 @@ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", @@ -4045,27 +3616,6 @@ "is-path-inside": "^1.0.0" } }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true, - "optional": true - }, - "is-my-json-valid": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz", - "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==", - "dev": true, - "optional": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", @@ -4143,13 +3693,6 @@ "isobject": "^3.0.1" } }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true, - "optional": true - }, "is-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -4298,13 +3841,6 @@ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true, - "optional": true - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -4330,9 +3866,9 @@ "dev": true }, "karma": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.5.tgz", - "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/karma/-/karma-3.0.0.tgz", + "integrity": "sha512-ZTjyuDXVXhXsvJ1E4CnZzbCjSxD6sEdzEsFYogLuZM0yqvg/mgz+O+R1jb0J7uAQeuzdY8kJgx6hSNXLwFuHIQ==", "dev": true, "requires": { "bluebird": "^3.3.0", @@ -4350,15 +3886,15 @@ "http-proxy": "^1.13.0", "isbinaryfile": "^3.0.0", "lodash": "^4.17.4", - "log4js": "^2.5.3", - "mime": "^1.3.4", + "log4js": "^3.0.0", + "mime": "^2.3.1", "minimatch": "^3.0.2", "optimist": "^0.6.1", "qjobs": "^1.1.4", "range-parser": "^1.2.0", "rimraf": "^2.6.0", "safe-buffer": "^5.0.1", - "socket.io": "2.0.4", + "socket.io": "2.1.1", "source-map": "^0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" @@ -4479,48 +4015,6 @@ "flush-write-stream": "^1.0.2" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "optional": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "libbase64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", - "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", - "dev": true - }, - "libmime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", - "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", - "dev": true, - "requires": { - "iconv-lite": "0.4.15", - "libbase64": "0.1.0", - "libqp": "1.1.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", - "dev": true - } - } - }, - "libqp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", - "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", - "dev": true - }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", @@ -4720,166 +4214,18 @@ "dev": true }, "log4js": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.11.0.tgz", - "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.5.tgz", + "integrity": "sha512-IX5c3G/7fuTtdr0JjOT2OIR12aTESVhsH6cEsijloYwKgcPRlO6DgOU72v0UFhWcoV1HN6+M3dwT89qVPLXm0w==", "dev": true, "requires": { - "amqplib": "^0.5.2", - "axios": "^0.15.3", - "circular-json": "^0.5.4", + "circular-json": "^0.5.5", "date-format": "^1.2.0", "debug": "^3.1.0", - "hipchat-notifier": "^1.1.0", - "loggly": "^1.1.0", - "mailgun-js": "^0.18.0", - "nodemailer": "^2.5.0", - "redis": "^2.7.1", - "semver": "^5.5.0", - "slack-node": "~0.2.0", + "rfdc": "^1.1.2", "streamroller": "0.7.0" } }, - "loggly": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", - "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", - "dev": true, - "optional": true, - "requires": { - "json-stringify-safe": "5.0.x", - "request": "2.75.x", - "timespan": "2.3.x" - }, - "dependencies": { - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true, - "optional": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", - "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "optional": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - } - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true, - "optional": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", - "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.0.0", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" - } - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "optional": true, - "requires": { - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true, - "optional": true - } - } - }, "lolex": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz", @@ -4913,35 +4259,6 @@ "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" }, - "mailcomposer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", - "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", - "dev": true, - "optional": true, - "requires": { - "buildmail": "4.0.1", - "libmime": "3.0.0" - } - }, - "mailgun-js": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.1.tgz", - "integrity": "sha512-lvuMP14u24HS2uBsJEnzSyPMxzU2b99tQsIx1o6QNjqxjk8b3WvR+vq5oG1mjqz/IBYo+5gF+uSoDS0RkMVHmg==", - "dev": true, - "optional": true, - "requires": { - "async": "~2.6.0", - "debug": "~3.1.0", - "form-data": "~2.3.0", - "inflection": "~1.12.0", - "is-stream": "^1.1.0", - "path-proxy": "~1.0.0", - "promisify-call": "^2.0.2", - "proxy-agent": "~3.0.0", - "tsscmp": "~1.0.0" - } - }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -5032,9 +4349,9 @@ } }, "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", + "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==", "dev": true }, "mime-db": { @@ -5218,13 +4535,6 @@ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", - "dev": true, - "optional": true - }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", @@ -5261,91 +4571,6 @@ "lower-case": "^1.1.1" } }, - "nodemailer": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", - "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", - "dev": true, - "optional": true, - "requires": { - "libmime": "3.0.0", - "mailcomposer": "4.0.1", - "nodemailer-direct-transport": "3.3.2", - "nodemailer-shared": "1.1.0", - "nodemailer-smtp-pool": "2.8.2", - "nodemailer-smtp-transport": "2.7.2", - "socks": "1.1.9" - }, - "dependencies": { - "socks": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", - "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", - "dev": true, - "optional": true, - "requires": { - "ip": "^1.1.2", - "smart-buffer": "^1.0.4" - } - } - } - }, - "nodemailer-direct-transport": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", - "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-fetch": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", - "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", - "dev": true - }, - "nodemailer-shared": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", - "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", - "dev": true, - "requires": { - "nodemailer-fetch": "1.6.0" - } - }, - "nodemailer-smtp-pool": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", - "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-smtp-transport": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", - "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", - "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" - } - }, - "nodemailer-wellknown": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", - "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", - "dev": true - }, "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -5588,13 +4813,6 @@ } } }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "optional": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -5753,21 +4971,6 @@ } } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "optional": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, "ordered-read-streams": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", @@ -5816,50 +5019,6 @@ "integrity": "sha1-Y5y4sHJwwVtx16ZEao4wQU88ltE=", "dev": true }, - "pac-proxy-agent": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", - "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^3.0.0" - }, - "dependencies": { - "socks-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", - "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" - } - } - } - }, - "pac-resolver": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "dev": true, - "optional": true, - "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" - } - }, "package-json": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", @@ -5967,25 +5126,6 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-proxy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", - "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", - "dev": true, - "optional": true, - "requires": { - "inflection": "~1.3.0" - }, - "dependencies": { - "inflection": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", - "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", - "dev": true, - "optional": true - } - } - }, "path-root": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", @@ -6168,12 +5308,6 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -6198,40 +5332,6 @@ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, - "promisify-call": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/promisify-call/-/promisify-call-2.0.4.tgz", - "integrity": "sha1-1IwtRWUszM1SgB3ey9UzptS9X7o=", - "dev": true, - "optional": true, - "requires": { - "with-callback": "^1.0.2" - } - }, - "proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.1.tgz", - "integrity": "sha512-mAZexaz9ZxQhYPWfAjzlrloEjW+JHiBFryE4AJXFDTnaXfmH/FKqC1swTRKuEPbHWz02flQNXFOyDUF7zfEG6A==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^2.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" - } - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true, - "optional": true - }, "proxyquire": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-1.8.0.tgz", @@ -6257,13 +5357,6 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", - "dev": true, - "optional": true - }, "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", @@ -6410,32 +5503,6 @@ "integrity": "sha1-Hb9tMvPFu4083pemxYjVR6nhPVY=", "dev": true }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", - "dev": true, - "optional": true, - "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" - } - }, - "redis-commands": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", - "dev": true, - "optional": true - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", - "dev": true, - "optional": true - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -6521,48 +5588,6 @@ "remove-trailing-separator": "^1.1.0" } }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "requestretry": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", - "dev": true, - "optional": true, - "requires": { - "extend": "^3.0.0", - "lodash": "^4.15.0", - "request": "^2.74.0", - "when": "^3.7.7" - } - }, "require-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-1.0.0.tgz", @@ -6627,6 +5652,12 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "rfdc": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", + "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==", + "dev": true + }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -6961,33 +5992,6 @@ "integrity": "sha512-Z72B4a0l0IQe5uWi9yzcqX/Ml6K9e1Hp03NmkjJnRG3gDsKTX7KvLFZsVUmCaz0eqeXLLK089mwTsP1P1W+DUQ==", "dev": true }, - "slack-node": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", - "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", - "dev": true, - "optional": true, - "requires": { - "requestretry": "^1.2.2" - } - }, - "smart-buffer": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", - "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", - "dev": true, - "optional": true - }, - "smtp-connection": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", - "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", - "dev": true, - "requires": { - "httpntlm": "1.6.1", - "nodemailer-shared": "1.1.0" - } - }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7104,38 +6108,18 @@ } } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "optional": true, - "requires": { - "hoek": "2.x.x" - } - }, "socket.io": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", - "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.1.1.tgz", + "integrity": "sha512-rORqq9c+7W0DAK3cleWNSyfv/qKXV99hV4tZe+gGLfBECw3XEhBy7x85F3wypA9688LKjtwO9pX9L33/xQI8yA==", "dev": true, "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", + "debug": "~3.1.0", + "engine.io": "~3.2.0", + "has-binary2": "~1.0.2", "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.0.4", - "socket.io-parser": "~3.1.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "socket.io-client": "2.1.1", + "socket.io-parser": "~3.2.0" } }, "socket.io-adapter": { @@ -7145,46 +6129,35 @@ "dev": true }, "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "dev": true, "requires": { "backo2": "1.0.2", "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", + "socket.io-parser": "~3.2.0", "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } } }, "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { "component-emitter": "1.2.1", "debug": "~3.1.0", - "has-binary2": "~1.0.2", "isarray": "2.0.1" }, "dependencies": { @@ -7196,48 +6169,6 @@ } } }, - "socks": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", - "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", - "dev": true, - "optional": true, - "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - } - }, - "socks-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", - "dev": true, - "optional": true, - "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" - }, - "dependencies": { - "smart-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", - "dev": true, - "optional": true - }, - "socks": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz", - "integrity": "sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w==", - "dev": true, - "optional": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" - } - } - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -7585,13 +6516,6 @@ "xtend": "~4.0.0" } }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", - "dev": true, - "optional": true - }, "time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", @@ -7604,13 +6528,6 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", - "dev": true, - "optional": true - }, "title-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", @@ -7703,24 +6620,6 @@ "through2": "^2.0.3" } }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "optional": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tsscmp": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", - "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", - "dev": true, - "optional": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -7737,15 +6636,6 @@ "dev": true, "optional": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -7780,12 +6670,6 @@ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true }, - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true - }, "undertaker": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", @@ -8044,13 +6928,6 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, - "uws": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", - "dev": true, - "optional": true - }, "v8flags": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz", @@ -8147,13 +7024,6 @@ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", "dev": true }, - "when": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", - "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", - "dev": true, - "optional": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -8217,20 +7087,6 @@ "integrity": "sha1-CvyjDzxudFgFjSigtnPJ3aYiubU=", "dev": true }, - "with-callback": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/with-callback/-/with-callback-1.0.2.tgz", - "integrity": "sha1-oJYpuakgAo1yFAT7Q1vc/1yRvCE=", - "dev": true, - "optional": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true, - "optional": true - }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -8293,13 +7149,6 @@ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", "dev": true }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true, - "optional": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index 0e0ac1529..0e056d905 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,7 @@ "gulp-zip": "^4.1.0", "inflection": "1.12.0", "jquery-ui-npm": "1.12.0", - "karma": "^2.0.0", + "karma": "^3.0.0", "karma-chai": "^0.1.0", "karma-chrome-launcher": "^2.2.0", "karma-mocha": "^1.3.0",
+ +
@@ -115,7 +117,7 @@
+
@@ -142,8 +146,26 @@
+ + +
+ +
+
+
+
+
@@ -171,27 +195,11 @@
- - -
- -
-
-
-
@@ -206,13 +214,15 @@
+ +
From 6b7ac3e5423bb499ef6dba8fddc09feaea1d355e Mon Sep 17 00:00:00 2001 From: mikeller Date: Sun, 12 Aug 2018 20:19:02 +1200 Subject: [PATCH 067/104] Improvements to analytics collection. --- gulpfile.js | 19 ++++++++++- package-lock.json | 77 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + src/css/main.css | 6 ++++ src/js/Analytics.js | 6 +++- src/js/main.js | 21 ++++++++----- src/main.html | 2 +- 7 files changed, 122 insertions(+), 10 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 91e8ec9b1..d5f76f977 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -22,6 +22,7 @@ const concat = require('gulp-concat'); const install = require("gulp-install"); const rename = require('gulp-rename'); const os = require('os'); +const git = require('gulp-git'); const DIST_DIR = './dist/'; const APPS_DIR = './apps/'; @@ -60,7 +61,9 @@ gulp.task('clean-release', clean_release); gulp.task('clean-cache', clean_cache); -var distBuild = gulp.series(dist_src, dist_locale, dist_libraries, dist_resources); +gulp.task('get-changeset-id', getChangesetId); + +var distBuild = gulp.series(dist_src, dist_locale, dist_libraries, dist_resources, getChangesetId); var distRebuild = gulp.series(clean_dist, distBuild); gulp.task('dist', distRebuild); @@ -433,6 +436,20 @@ function buildNWApps(platforms, flavor, dir, done) { } } +function getChangesetId(done) { + git.exec({args : 'log -1 --format="%h"'}, function (err, stdout) { + if (err) { + throw err; + } + + var versionData = { gitChangesetId: stdout.trim() } + var destFile = path.join(DIST_DIR, 'version.json'); + + fs.writeFile(destFile, JSON.stringify(versionData) , function () { + done(); + }); + }); +} function start_debug(done) { diff --git a/package-lock.json b/package-lock.json index b2e864adc..608e9352d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -201,6 +201,12 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "any-shell-escape": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/any-shell-escape/-/any-shell-escape-0.1.1.tgz", + "integrity": "sha1-1Vq5ciRMcaml4asIefML8RCAaVk=", + "dev": true + }, "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", @@ -2374,6 +2380,15 @@ "parse-filepath": "^1.0.1" } }, + "first-chunk-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", + "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, "flagged-respawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", @@ -3465,6 +3480,43 @@ } } }, + "gulp-git": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-2.8.0.tgz", + "integrity": "sha512-45pahZGIcsb6eCJS9EGCdXqYBbxE1dtSbS03iXIF3dHHor1r37KMqwoQQJv1SXJjpLKc6ei+rdvIl7Ar6tB+ow==", + "dev": true, + "requires": { + "any-shell-escape": "^0.1.1", + "fancy-log": "^1.3.2", + "lodash.template": "^4.4.0", + "plugin-error": "^0.1.2", + "require-dir": "^1.0.0", + "strip-bom-stream": "^3.0.0", + "through2": "^2.0.3", + "vinyl": "^2.0.1" + }, + "dependencies": { + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + } + } + }, "gulp-install": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/gulp-install/-/gulp-install-1.1.0.tgz", @@ -6920,6 +6972,12 @@ "when": "^3.7.7" } }, + "require-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-1.0.0.tgz", + "integrity": "sha512-PUJcQVTP4n6F8Un1GEEWhqnmBMfukVsL5gqwBxt7RF+nP+9hSOLJ/vSs5iUoXw1UWDgzqg9B/IIb15kfQKWsAQ==", + "dev": true + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7764,6 +7822,25 @@ "is-utf8": "^0.2.0" } }, + "strip-bom-buf": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", + "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", + "dev": true, + "requires": { + "is-utf8": "^0.2.1" + } + }, + "strip-bom-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-3.0.0.tgz", + "integrity": "sha1-lWvMXYRDD2klapDtgjdlzYWOFZw=", + "dev": true, + "requires": { + "first-chunk-stream": "^2.0.0", + "strip-bom-buf": "^1.0.0" + } + }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", diff --git a/package.json b/package.json index fc371c186..94badd199 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "gulp": "~4.0.0", "gulp-concat": "~2.6.1", "gulp-debian": "~0.1.8", + "gulp-git": "^2.8.0", "gulp-install": "^1.1.0", "gulp-rename": "~1.2.2", "gulp-zip": "^4.1.0", diff --git a/src/css/main.css b/src/css/main.css index 85f5a671f..e490b0d4c 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -1473,6 +1473,12 @@ dialog { transition: none; } +.connect_b a.connect.disabled { + background-color: #808080; + pointer-events: none; + cursor: default; + } + .connect_b a.connect { background-color: #ffbb00; border: 1px solid #dba718; diff --git a/src/js/Analytics.js b/src/js/Analytics.js index 474c41643..2d4e1067b 100644 --- a/src/js/Analytics.js +++ b/src/js/Analytics.js @@ -1,6 +1,6 @@ 'use strict'; -var Analytics = function (trackingId, userId, appName, appVersion, buildType, optOut, debugMode) { +var Analytics = function (trackingId, userId, appName, appVersion, changesetId, buildType, checkForDebugVersions, optOut, debugMode) { this._trackingId = trackingId; this.setOptOut(optOut); @@ -58,6 +58,8 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op FIRMWARE_CHANNEL: 10, LOGGING_STATUS: 11, MCU_ID: 12, + CONFIGURATOR_CHANGESET_ID: 13, + CONFIGURATOR_USE_DEBUG_VERSIONS: 14, }; this.METRICS = { @@ -66,6 +68,8 @@ var Analytics = function (trackingId, userId, appName, appVersion, buildType, op }; this.setDimension(this.DIMENSIONS.CONFIGURATOR_BUILD_TYPE, buildType); + this.setDimension(this.DIMENSIONS.CONFIGURATOR_CHANGESET_ID, changesetId); + this.setDimension(this.DIMENSIONS.CONFIGURATOR_USE_DEBUG_VERSIONS, checkForDebugVersions); this.resetFlightControllerData(); this.resetFirmwareData(); diff --git a/src/js/main.js b/src/js/main.js index 9895232cc..e841b1780 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -15,12 +15,16 @@ $(document).ready(function () { function checkSetupAnalytics(callback) { if (!analytics) { setTimeout(function () { - chrome.storage.local.get(['userId', 'analyticsOptOut'], function (result) { - if (!analytics) { - setupAnalytics(result); - } + chrome.storage.local.get(['userId', 'analyticsOptOut', 'checkForConfiguratorUnstableVersions', ], function (result) { + $.getJSON('version.json', function(data) { + var gitChangesetId = data.gitChangesetId; + + if (!analytics) { + setupAnalytics(result, gitChangesetId); + } - callback(analytics); + callback(analytics); + }); }); }); } else if (callback) { @@ -28,7 +32,7 @@ function checkSetupAnalytics(callback) { } }; -function setupAnalytics(result) { +function setupAnalytics(result, gitChangesetId) { var userId; if (result.userId) { userId = result.userId; @@ -40,10 +44,11 @@ function setupAnalytics(result) { } var optOut = !!result.analyticsOptOut; + var checkForDebugVersions = !!result.checkForConfiguratorUnstableVersions; var debugMode = process.versions['nw-flavor'] === 'sdk'; - analytics = new Analytics('UA-123002063-1', userId, 'Betaflight Configurator', getManifestVersion(), GUI.operating_system, optOut, debugMode); + analytics = new Analytics('UA-123002063-1', userId, 'Betaflight Configurator', getManifestVersion(), gitChangesetId, GUI.operating_system, checkForDebugVersions, optOut, debugMode); function logException(exception) { analytics.sendException(exception.stack); @@ -69,6 +74,8 @@ function setupAnalytics(result) { // Looks like we're in Chrome - but the event does not actually get fired chrome.runtime.onSuspend.addListener(sendCloseEvent); } + + $('.connect_b a.connect').removeClass('disabled'); } //Process to execute to real start the app diff --git a/src/main.html b/src/main.html index 1fd3104c2..7bb742b52 100755 --- a/src/main.html +++ b/src/main.html @@ -125,7 +125,7 @@
- +
From ae5603af2bac4192ea06da29a6785d1504c7bab4 Mon Sep 17 00:00:00 2001 From: mikeller Date: Mon, 13 Aug 2018 00:18:06 +1200 Subject: [PATCH 068/104] Added expert mode to firmware flasher to hide unstable builds. --- locales/en/messages.json | 7 ++-- src/js/tabs/firmware_flasher.js | 59 ++++++++++++++++++++++----------- src/tabs/firmware_flasher.html | 5 +++ 3 files changed, 50 insertions(+), 21 deletions(-) diff --git a/locales/en/messages.json b/locales/en/messages.json index a038e28a2..92d69171d 100644 --- a/locales/en/messages.json +++ b/locales/en/messages.json @@ -57,6 +57,9 @@ "expertMode": { "message": "Enable Expert Mode" }, + "expertModeDescription": { + "message": "Show unreleased and potentially unstable builds" + }, "permanentExpertMode": { "message": "Permanently enable Expert Mode" }, @@ -2323,10 +2326,10 @@ "message": "Baud Rate" }, "firmwareFlasherShowDevelopmentReleases":{ - "message": "Show unstable and additional releases" + "message": "Show unstable releases" }, "firmwareFlasherShowDevelopmentReleasesDescription":{ - "message": "Show Release-Candidates and Development Releases." + "message": "Show release candidates in addition to stable releases" }, "firmwareFlasherOptionLoading": { "message": "Loading ..." diff --git a/src/js/tabs/firmware_flasher.js b/src/js/tabs/firmware_flasher.js index 5d17f5af3..173eb08dc 100755 --- a/src/js/tabs/firmware_flasher.js +++ b/src/js/tabs/firmware_flasher.js @@ -227,17 +227,6 @@ TABS.firmware_flasher.initialize = function (callback) { } }; - function showOrHideBuildTypeSelect() { - var showDevReleases = $(this).is(':checked'); - - if (showDevReleases) { - $('tr.build_type').show(); - } else { - $('tr.build_type').hide(); - buildType_e.val(0).trigger('change'); - } - } - var buildTypes = [ { tag: 'firmwareFlasherOptionLabelBuildTypeRelease', @@ -255,16 +244,48 @@ TABS.firmware_flasher.initialize = function (callback) { loader: () => self.jenkinsLoader.loadBuilds(job.name, buildJenkinsBoardOptions) }; }) - - buildTypes = buildTypes.concat(ciBuildsTypes); + var buildTypesToShow; var buildType_e = $('select[name="build_type"]'); - buildTypes.forEach((build, index) => { - buildType_e.append($("".format(index, build.tag ? i18n.getMessage(build.tag) : build.title))) - }); + function buildBuildTypeOptionsList() { + buildType_e.empty(); + buildTypesToShow.forEach((build, index) => { + buildType_e.append($("".format(index, build.tag ? i18n.getMessage(build.tag) : build.title))) + }); + } + + function showOrHideBuildTypes() { + var showExtraReleases = $(this).is(':checked'); + + if (showExtraReleases) { + $('tr.build_type').show(); + $('tr.expert_mode').show(); + } else { + $('tr.build_type').hide(); + $('tr.expert_mode').hide(); + buildType_e.val(0).trigger('change'); + } + } + + var globalExpertMode_e = $('input[name="expertModeCheckbox"]'); + function showOrHideBuildTypeSelect() { + var expertModeChecked = $(this).is(':checked'); + + globalExpertMode_e.prop('checked', expertModeChecked); + if (expertModeChecked) { + buildTypesToShow = buildTypes.concat(ciBuildsTypes); + buildBuildTypeOptionsList(); + } else { + buildTypesToShow = buildTypes; + buildBuildTypeOptionsList(); + buildType_e.val(0).trigger('change'); + } + } - showOrHideBuildTypeSelect(); - $('input.show_development_releases').change(showOrHideBuildTypeSelect); + var expertMode_e = $('.tab-firmware_flasher input.expert_mode'); + expertMode_e.prop('checked', globalExpertMode_e.is(':checked')); + $('input.show_development_releases').change(showOrHideBuildTypes).change(); + expertMode_e.change(showOrHideBuildTypeSelect).change(); // translate to user-selected language i18n.localizePage(); @@ -282,7 +303,7 @@ TABS.firmware_flasher.initialize = function (callback) { .append($("".format(i18n.getMessage('firmwareFlasherOptionLabelSelectFirmwareVersion')))); if (!GUI.connect_lock) { - buildTypes[build_type].loader(); + buildTypesToShow[build_type].loader(); } chrome.storage.local.set({'selected_build_type': build_type}); diff --git a/src/tabs/firmware_flasher.html b/src/tabs/firmware_flasher.html index df4bc6d8d..7ec807262 100755 --- a/src/tabs/firmware_flasher.html +++ b/src/tabs/firmware_flasher.html @@ -9,6 +9,11 @@
@@ -109,20 +109,20 @@
- +