├── .gitattributes ├── .github ├── scripts │ └── extract-release-notes.py └── workflows │ ├── pr.yml │ ├── push.yml │ ├── release.yml │ ├── snapshot.yml │ └── testing.yml ├── .gitignore ├── .husky └── pre-commit ├── .nvmrc ├── .prettierignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── HOWTO.md ├── LICENSE ├── Makefile ├── README.md ├── Releases.md ├── assets ├── android │ ├── drawable │ │ └── ic_launcher_foreground.xml │ ├── ic_launcher-playstore.png │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ └── values │ │ └── ic_launcher_background.xml ├── linux │ ├── copyright │ ├── icon │ │ ├── bf_icon_128.png │ │ ├── bf_icon_english_128.png │ │ └── rf_icon.png │ └── rotorflight-configurator.desktop ├── osx │ └── dmg-background.png └── windows │ ├── installer.iss │ ├── rf_installer.bmp │ ├── rf_installer_icon.ico │ ├── rf_installer_small.bmp │ └── unofficial_inno_languages │ ├── Basque.isl │ ├── ChineseSimplified.isl │ ├── ChineseTraditional.isl │ ├── Croatian.isl │ ├── Galician.isl │ ├── Hungarian.isl │ ├── Indonesian.isl │ ├── Korean.isl │ ├── Latvian.isl │ └── Swedish.isl ├── cordova ├── build.json ├── config_template.xml ├── package_template.json ├── pnpm-lock.yaml ├── release.jks └── usb_device_filter.xml ├── crowdin.yml ├── eslint.config.mjs ├── gulpfile.mjs ├── jsconfig.json ├── libraries ├── flightindicators.css ├── jquery.ba-throttle-debounce.min.js ├── jquery.flightindicators.js ├── jquery.liblink.js └── openlayers │ ├── ol.css │ ├── ol.css.map │ ├── ol.js │ └── ol.js.map ├── lint-staged.config.mjs ├── locales ├── de │ └── messages.json ├── en │ └── messages.json ├── es │ └── messages.json ├── fr │ └── messages.json ├── it │ └── messages.json ├── ja │ └── messages.json ├── ko │ └── messages.json ├── nl │ └── messages.json ├── pl │ └── messages.json ├── pt │ └── messages.json ├── pt_BR │ └── messages.json ├── zh │ └── messages.json ├── zh_CN │ └── messages.json └── zh_TW │ └── messages.json ├── package.json ├── pnpm-lock.yaml ├── prettier.config.mjs ├── public ├── images ├── libraries ├── locales ├── opensans_webfontkit │ ├── fonts.css │ ├── opensans-bold-webfont.ttf │ ├── opensans-bold-webfont.woff │ ├── opensans-bold-webfont.woff2 │ ├── opensans-bolditalic-webfont.ttf │ ├── opensans-bolditalic-webfont.woff │ ├── opensans-bolditalic-webfont.woff2 │ ├── opensans-italic-webfont.ttf │ ├── opensans-italic-webfont.woff │ ├── opensans-italic-webfont.woff2 │ ├── opensans-light-webfont.ttf │ ├── opensans-light-webfont.woff │ ├── opensans-light-webfont.woff2 │ ├── opensans-regular-webfont.ttf │ ├── opensans-regular-webfont.woff │ ├── opensans-regular-webfont.woff2 │ ├── opensans-semibold-webfont.ttf │ ├── opensans-semibold-webfont.woff │ └── opensans-semibold-webfont.woff2 └── resources ├── resources └── models │ ├── bell_ccw.bin │ ├── bell_ccw.gltf │ ├── bell_ccw.png │ ├── bell_cw.bin │ ├── bell_cw.gltf │ └── bell_cw.png ├── src ├── components │ ├── BatteryLegend.svelte │ ├── Field.svelte │ ├── HelpIcon.svelte │ ├── HoverTooltip.svelte │ ├── Logo.svelte │ ├── NumberInput.svelte │ ├── Page.svelte │ ├── Section.svelte │ ├── StatusBar.svelte │ ├── SubSection.svelte │ ├── Switch.svelte │ ├── ToggleFieldGroup.svelte │ ├── Tooltip.svelte │ └── notes │ │ ├── ErrorNote.svelte │ │ └── WarningNote.svelte ├── css │ ├── _global.scss │ ├── app.css │ ├── dark-theme.css │ ├── dropdown-lists │ │ ├── LICENSE │ │ └── css │ │ │ └── style_lists.css │ ├── main.css │ ├── main_cordova.css │ ├── select2_custom.css │ ├── slider.css │ ├── switchery_custom.css │ └── tabs │ │ ├── adjustments.css │ │ ├── auxiliary.css │ │ ├── beepers.css │ │ ├── blackbox.css │ │ ├── cli.css │ │ ├── configuration.css │ │ ├── failsafe.css │ │ ├── firmware_flasher.css │ │ ├── gps.css │ │ ├── help.css │ │ ├── landing.css │ │ ├── led_strip.css │ │ ├── mixer.css │ │ ├── motors.css │ │ ├── options.css │ │ ├── power.css │ │ ├── presets.css │ │ ├── privacy_policy.css │ │ ├── profiles.css │ │ ├── rates.css │ │ ├── receiver.css │ │ ├── receiver_msp.css │ │ ├── sensors.css │ │ ├── servos.css │ │ ├── setup.css │ │ ├── static_tab.css │ │ └── status.css ├── images │ ├── CF_settings_black.svg │ ├── CF_settings_white.svg │ ├── arrow.svg │ ├── arrows.png │ ├── bf_icon.icns │ ├── bf_icon.ico │ ├── bf_icon_128.png │ ├── bf_icon_128.psd │ ├── cf_logo_black.svg │ ├── cf_logo_white.svg │ ├── discord_logo.svg │ ├── facebook_logo.svg │ ├── flightindicators │ │ ├── altitude_pressure.svg │ │ ├── altitude_ticks.svg │ │ ├── fi_box.svg │ │ ├── fi_circle.svg │ │ ├── fi_needle.svg │ │ ├── fi_needle_small.svg │ │ ├── fi_tc_airplane.svg │ │ ├── heading_mechanics.svg │ │ ├── heading_yaw.svg │ │ ├── horizon_back.svg │ │ ├── horizon_ball.svg │ │ ├── horizon_circle.svg │ │ ├── horizon_mechanics.svg │ │ ├── speed_mechanics.svg │ │ ├── turn_coordinator.svg │ │ └── vertical_mechanics.svg │ ├── icons │ │ ├── cf_failsafe_procedure1-dark.svg │ │ ├── cf_failsafe_procedure1.svg │ │ ├── cf_failsafe_procedure2-dark.svg │ │ ├── cf_failsafe_procedure2.svg │ │ ├── cf_failsafe_procedure3-dark.svg │ │ ├── cf_failsafe_procedure3.svg │ │ ├── cf_failsafe_procedure4-dark.svg │ │ ├── cf_failsafe_procedure4.svg │ │ ├── cf_icon_adjust_grey.svg │ │ ├── cf_icon_adjust_white.svg │ │ ├── cf_icon_advanced_grey.svg │ │ ├── cf_icon_advanced_white.svg │ │ ├── cf_icon_armed_active.svg │ │ ├── cf_icon_armed_grey.svg │ │ ├── cf_icon_backup_grey.svg │ │ ├── cf_icon_backup_white.svg │ │ ├── cf_icon_bat_grey.svg │ │ ├── cf_icon_check_rf_blue.svg │ │ ├── cf_icon_cli_grey.svg │ │ ├── cf_icon_cli_white.svg │ │ ├── cf_icon_config_grey.svg │ │ ├── cf_icon_config_white.svg │ │ ├── cf_icon_data_grey.svg │ │ ├── cf_icon_data_white.svg │ │ ├── cf_icon_failsafe_active.svg │ │ ├── cf_icon_failsafe_grey.svg │ │ ├── cf_icon_failsafe_white.svg │ │ ├── cf_icon_filter.svg │ │ ├── cf_icon_flasher_grey.svg │ │ ├── cf_icon_flasher_white.svg │ │ ├── cf_icon_gps_grey.svg │ │ ├── cf_icon_gps_white.svg │ │ ├── cf_icon_heli.svg │ │ ├── cf_icon_help_grey.svg │ │ ├── cf_icon_help_white.svg │ │ ├── cf_icon_info_blue.svg │ │ ├── cf_icon_info_green.svg │ │ ├── cf_icon_info_grey.svg │ │ ├── cf_icon_info_orange.svg │ │ ├── cf_icon_info_white.svg │ │ ├── cf_icon_led_grey.svg │ │ ├── cf_icon_led_white.svg │ │ ├── cf_icon_link_active.svg │ │ ├── cf_icon_link_grey.svg │ │ ├── cf_icon_log_grey.svg │ │ ├── cf_icon_log_white.svg │ │ ├── cf_icon_mission_grey.svg │ │ ├── cf_icon_mission_white.svg │ │ ├── cf_icon_modes_grey.svg │ │ ├── cf_icon_modes_white.svg │ │ ├── cf_icon_motor_grey.svg │ │ ├── cf_icon_motor_white.svg │ │ ├── cf_icon_pid_grey.svg │ │ ├── cf_icon_pid_white.svg │ │ ├── cf_icon_pitch.svg │ │ ├── cf_icon_ports_grey.svg │ │ ├── cf_icon_ports_white.svg │ │ ├── cf_icon_position.png │ │ ├── cf_icon_position_nofix.png │ │ ├── cf_icon_power_grey.svg │ │ ├── cf_icon_power_white.svg │ │ ├── cf_icon_quad.svg │ │ ├── cf_icon_roll.svg │ │ ├── cf_icon_rx_grey.svg │ │ ├── cf_icon_rx_white.svg │ │ ├── cf_icon_sdcard.svg │ │ ├── cf_icon_search_rf_blue.svg │ │ ├── cf_icon_sensors_grey.svg │ │ ├── cf_icon_sensors_white.svg │ │ ├── cf_icon_servo_grey.svg │ │ ├── cf_icon_servo_white.svg │ │ ├── cf_icon_settings_white.svg │ │ ├── cf_icon_setup_grey.svg │ │ ├── cf_icon_setup_white.svg │ │ ├── cf_icon_transponder_grey.svg │ │ ├── cf_icon_transponder_white.svg │ │ ├── cf_icon_usb1_white.svg │ │ ├── cf_icon_usb2_white.svg │ │ ├── cf_icon_vtx_grey.svg │ │ ├── cf_icon_vtx_white.svg │ │ ├── cf_icon_welcome_grey.svg │ │ ├── cf_icon_welcome_white.svg │ │ ├── cf_icon_wizard_grey.svg │ │ ├── cf_icon_wizard_white.svg │ │ ├── cf_icon_yaw.svg │ │ ├── close1.svg │ │ ├── cross2.svg │ │ ├── icon_bracket.svg │ │ ├── icon_osd.svg │ │ ├── icon_osd_white.svg │ │ ├── scroll.svg │ │ ├── sensor_acc_off.png │ │ ├── sensor_acc_on.png │ │ ├── sensor_baro_off.png │ │ ├── sensor_baro_on.png │ │ ├── sensor_gyro_off.png │ │ ├── sensor_gyro_on.png │ │ ├── sensor_mag_off.png │ │ ├── sensor_mag_on.png │ │ ├── sensor_sat_off.png │ │ ├── sensor_sat_on.png │ │ ├── sensor_sonar_off.png │ │ ├── sensor_sonar_on.png │ │ ├── star_rf_blue.svg │ │ ├── star_rf_blue_stroke.svg │ │ └── star_transparent.svg │ ├── light-wide-1.svg │ ├── light-wide-2-compact.svg │ ├── light-wide-2.svg │ ├── loading-bars.svg │ ├── loading-spin.svg │ ├── osd-bg-1-grid.png │ ├── osd-bg-1.jpg │ ├── osd-bg-2.png │ ├── paper-dark.png │ ├── paper.png │ ├── pattern.png │ ├── rate_logos │ │ ├── actual.svg │ │ ├── betaflight.svg │ │ ├── kiss.svg │ │ ├── quickrates.svg │ │ └── raceflight.svg │ ├── rf_icon.icns │ ├── rf_icon.ico │ └── rf_icon.png ├── js │ ├── Beepers.js │ ├── CliAutoComplete.js │ ├── ConfigInserter.js │ ├── DarkTheme.js │ ├── FirmwareCache.js │ ├── GitHubApi.js │ ├── Mixer.js │ ├── RateCurve.js │ ├── backup_restore.js │ ├── cli_engine.js │ ├── clipboard.js │ ├── config.js │ ├── cordova_chromeapi.js │ ├── cordova_startup.js │ ├── data_storage.js │ ├── default_huffman_tree.js │ ├── fc.svelte.js │ ├── features.svelte.js │ ├── filesystem.js │ ├── gui.js │ ├── help.js │ ├── huffman.js │ ├── i18n.js │ ├── injected_methods.js │ ├── localization.js │ ├── main.js │ ├── main.svelte.js │ ├── main_cordova.js │ ├── model.js │ ├── msp.svelte.js │ ├── msp │ │ ├── MSPCodes.js │ │ ├── MSPConnector.js │ │ └── MSPHelper.js │ ├── phones_ui.js │ ├── port_handler.js │ ├── port_usage.svelte.js │ ├── presets │ │ ├── preset_dialog.js │ │ ├── preset_panel.js │ │ ├── preset_tracker.js │ │ ├── source │ │ │ ├── github.js │ │ │ ├── preset_instance.js │ │ │ ├── retriever.js │ │ │ └── source.js │ │ └── sources.js │ ├── protocols │ │ ├── stm32.js │ │ └── stm32usbdfu.js │ ├── release_checker.js │ ├── serial.js │ ├── serial_backend.js │ ├── tabs │ │ ├── adjustments.js │ │ ├── auxiliary.js │ │ ├── beepers.js │ │ ├── blackbox.js │ │ ├── cli.js │ │ ├── configuration.js │ │ ├── failsafe.js │ │ ├── firmware_flasher.js │ │ ├── gps.js │ │ ├── gyro.js │ │ ├── help.js │ │ ├── index.js │ │ ├── landing.js │ │ ├── led_strip.js │ │ ├── map.js │ │ ├── mixer.js │ │ ├── motors.js │ │ ├── options.js │ │ ├── power.js │ │ ├── presets.js │ │ ├── privacy_policy.js │ │ ├── profiles.js │ │ ├── rates.js │ │ ├── receiver.js │ │ ├── receiver_msp.js │ │ ├── sensors.js │ │ ├── servos.js │ │ ├── setup.js │ │ └── status.js │ ├── utils │ │ ├── CommonUtils.js │ │ ├── common.js │ │ └── window_watchers.js │ ├── virtual_fc.js │ └── workers │ │ └── hex_parser.js ├── main.html ├── main_cordova.html └── tabs │ ├── adjustments.html │ ├── auxiliary.html │ ├── beepers.html │ ├── blackbox.html │ ├── blank.html │ ├── cli.html │ ├── configuration.html │ ├── failsafe.html │ ├── firmware_flasher.html │ ├── gps.html │ ├── gyro │ ├── CustomNotches.svelte │ ├── DynamicFilter.svelte │ ├── Gyro.svelte │ ├── LowpassFilter.svelte │ ├── NotchFilter.svelte │ ├── RpmFilter.svelte │ └── filter_config.js │ ├── help.html │ ├── landing.html │ ├── led_strip.html │ ├── map.html │ ├── mixer.html │ ├── motors.html │ ├── options.html │ ├── power.html │ ├── presets │ ├── preset_dialog.html │ ├── preset_panel.html │ ├── presets.html │ ├── selected_preset_panel.svelte │ ├── selected_preset_review_dialog.svelte │ ├── source_panel.html │ └── sources_dialog.html │ ├── privacy_policy.html │ ├── profiles.html │ ├── rates.html │ ├── receiver.html │ ├── receiver │ ├── Receiver.svelte │ ├── ReceiverSettings.svelte │ ├── ReceiverType.svelte │ ├── TelemetrySensors │ │ ├── SensorsBitfield.svelte │ │ ├── SensorsOrderedList │ │ │ ├── Details.svelte │ │ │ ├── Select.svelte │ │ │ ├── SensorsOrderedList.svelte │ │ │ └── Sort.svelte │ │ ├── SensorsUnorderedList.svelte │ │ └── TelemetrySensors.svelte │ ├── TelemetrySettings.svelte │ ├── protocols.js │ └── telemetry │ │ ├── crsf.js │ │ ├── frsky_hub.js │ │ ├── ghost.js │ │ ├── sensors.js │ │ └── smartport.js │ ├── receiver_msp.html │ ├── review.html │ ├── sensors.html │ ├── servos.html │ ├── setup.html │ └── status.html ├── svelte.config.mjs ├── tools ├── locale-cherrypick ├── locale-delete-status ├── locale-filter-unused ├── locale-reformat ├── locale-update └── locale-update-all └── vite.config.mjs /.gitattributes: -------------------------------------------------------------------------------- 1 | LICENSE text eol=lf 2 | *.md text eol=lf 3 | *.c text eol=lf 4 | *.cc text eol=lf 5 | *.h text eol=lf 6 | *.cc text eol=lf 7 | *.S text eol=lf 8 | *.s text eol=lf 9 | *.hex -crlf -diff 10 | *.elf -crlf -diff 11 | *.ld text eol=lf 12 | Makefile text eol=lf 13 | *.mk text eol=lf 14 | *.nomk text eol=lf 15 | *.pl text eol=lf 16 | *.js text eol=lf 17 | *.json text eol=lf 18 | *.html text eol=lf 19 | *.css text eol=lf 20 | *.svg text eol=lf 21 | *.png -crlf -diff 22 | *.yml text eol=lf 23 | *.xml text eol=lf 24 | *.mcm text eol=lf 25 | *.nsi text eol=lf 26 | *.nsh text eol=lf 27 | *.lua text eol=lf 28 | *.txt text eol=lf 29 | *.sh text eol=lf 30 | *.config text eol=lf 31 | -------------------------------------------------------------------------------- /.github/scripts/extract-release-notes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import sys 4 | 5 | def main(args): 6 | release = args[1] 7 | inputfile = args[2] 8 | 9 | found = False 10 | 11 | with open(inputfile) as input: 12 | for line in input: 13 | if line.startswith('# '): 14 | found = line.strip() == '# ' + release 15 | elif line.startswith('***'): 16 | found = False 17 | elif found: 18 | sys.stdout.write(line) 19 | 20 | 21 | if __name__ == '__main__': main(sys.argv) 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # node.js npm related 2 | 3 | node_modules/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Configurator Build process 9 | cache/ 10 | apps/ 11 | dist/ 12 | dist_cordova/ 13 | debug/ 14 | release/ 15 | testresults/ 16 | .eslintcache 17 | public/fontawesome 18 | app/ 19 | bundle/ 20 | redist/ 21 | nwjs_cache 22 | 23 | # OSX 24 | .DS_store 25 | 26 | # artefacts for Visual Studio Code 27 | /.vscode/ 28 | 29 | # NetBeans 30 | nbproject/ 31 | 32 | # IntelliJ 33 | .idea 34 | 35 | # Eclipse 36 | .project 37 | .settings/ 38 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm exec lint-staged 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v22.5.1 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Ignore all files 2 | 3 | * 4 | 5 | # Only format allowed files 6 | 7 | !/*.mjs 8 | 9 | !/src/**/ 10 | !/src/css/app.css 11 | !/src/css/tabs/presets.css 12 | !/src/js/cli_engine.js 13 | !/src/js/clipboard.js 14 | !/src/js/config.js 15 | !/src/js/features.svelte.js 16 | !/src/js/filesystem.js 17 | !/src/js/main.svelte.js 18 | !/src/js/port_usage.js 19 | !/src/js/presets/**/* 20 | !/src/js/tabs/gyro.js 21 | !/src/js/tabs/presets.js 22 | !/src/js/virtual_fc.js 23 | !/src/tabs/gyro/filter_config.js 24 | !/src/tabs/presets/**/* 25 | !/src/tabs/receiver/**/*.js 26 | 27 | !*.scss 28 | !*.svelte 29 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Issues and Support 2 | 3 | Please remember the issue tracker on github is _not_ for user support. Please also do not email developers directly for support. Instead please use the chat or the forums first, then if the problem is confirmed create an issue that details how to repeat the problem so it can be investigated. 4 | 5 | Issues created without steps to repeat are likely to be closed. E-mail requests for support will go un-answered; All support needs to be public so that other people can read the problems and solutions. 6 | 7 | Remember that issues that are due to mis-configuration, wiring or failure to read documentation just takes time away from the developers and can often be solved without developer interaction by other users. 8 | 9 | Please search for existing issues *before* creating new ones. 10 | 11 | # Contributing 12 | 13 | Please refer to the Contributing section on the [Website](https://www.rotorflight.org/docs/Contributing/intro). 14 | 15 | -------------------------------------------------------------------------------- /HOWTO.md: -------------------------------------------------------------------------------- 1 | ## Setup 2 | 3 | 1. Install Node.js `nvm install` 4 | 2. Install pnpm `npm install -g pnpm` 5 | 3. Install dependencies `make init` 6 | 7 | ## Development 8 | 9 | ### Desktop 10 | 11 | 1. Run from source with `pnpm start` 12 | 13 | **Note:** The NW.js SDK needs to be downloaded the first time the configurator is started, and may take some time to complete. 14 | 15 | ### Android 16 | 17 | Developing for Android requires JDK 11, gradle, and Android SDK 33. 18 | 19 | 1. Start an Android emulator or connect a physical device with debugging enabled 20 | 2. Set a version for the application `SEMVER=2.1.0-dev make version` 21 | 3. Run `make android` 22 | 4. Open `chrome://inspect/#devices` in a Chrome browser to debug 23 | 24 | ## Building 25 | 26 | Tasks are defined in `gulpfile.mjs` and can be run with pnpm. 27 | 28 | ``` 29 | pnpm gulp [--debug] [--platform ] [--arch ] 30 | ``` 31 | 32 | **``** 33 | 34 | - **`bundle`** bundles the source files into `./bundle`. 35 | - **`app`** builds the application in `./app`. 36 | - **`redist`** creates redistributable archives in `./redist`. 37 | 38 | **`--debug`** Outputs builds that can be debugged with Chrome DevTools or an Android debugger. 39 | 40 | **``** Defaults to the host platform. 41 | 42 | - linux 43 | - osx 44 | - win 45 | - android 46 | 47 | **``** Defaults to the host architecture. 48 | 49 | - x86 50 | - x86_64 51 | - arm64 52 | -------------------------------------------------------------------------------- /assets/android/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/ic_launcher-playstore.png -------------------------------------------------------------------------------- /assets/android/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/android/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/android/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /assets/android/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /assets/android/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /assets/android/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /assets/android/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/android/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /assets/android/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #222222 4 | -------------------------------------------------------------------------------- /assets/linux/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: Rotorflight Configurator 3 | Source: https://github.com/rotorflight/rotorflight-configurator 4 | 5 | Files: * 6 | Copyright: Copyright 2018 The Rotorflight open source project 7 | License: GPL-3 8 | 9 | License: GPL-3 10 | This program is free software: you can redistribute it and/or modify it under 11 | the terms of the GNU General Public License as published by the Free Software 12 | Foundation, either version 3 of the License, or (at your option) any later 13 | version. 14 | . 15 | This program is distributed in the hope that it will be useful, but WITHOUT ANY 16 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 17 | PARTICULAR PURPOSE. See the GNU General Public License for more details. 18 | . 19 | You should have received a copy of the GNU General Public License along with 20 | this program. If not, see . 21 | . 22 | On Debian systems, the complete text of the GNU General Public License 23 | can be found in `/usr/share/common-licenses/GPL-3'. 24 | -------------------------------------------------------------------------------- /assets/linux/icon/bf_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/linux/icon/bf_icon_128.png -------------------------------------------------------------------------------- /assets/linux/icon/bf_icon_english_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/linux/icon/bf_icon_english_128.png -------------------------------------------------------------------------------- /assets/linux/icon/rf_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/linux/icon/rf_icon.png -------------------------------------------------------------------------------- /assets/linux/rotorflight-configurator.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Rotorflight Configurator 3 | Comment=Crossplatform configuration tool for the Rotorflight flight control system 4 | Exec=/opt/rotorflight/rotorflight-configurator/rotorflight-configurator 5 | Icon=/opt/rotorflight/rotorflight-configurator/icon/rf_icon.png 6 | Terminal=false 7 | Type=Application 8 | Categories=Utility 9 | -------------------------------------------------------------------------------- /assets/osx/dmg-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/osx/dmg-background.png -------------------------------------------------------------------------------- /assets/windows/rf_installer.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/rf_installer.bmp -------------------------------------------------------------------------------- /assets/windows/rf_installer_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/rf_installer_icon.ico -------------------------------------------------------------------------------- /assets/windows/rf_installer_small.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/rf_installer_small.bmp -------------------------------------------------------------------------------- /assets/windows/unofficial_inno_languages/Hungarian.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/unofficial_inno_languages/Hungarian.isl -------------------------------------------------------------------------------- /assets/windows/unofficial_inno_languages/Korean.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/unofficial_inno_languages/Korean.isl -------------------------------------------------------------------------------- /assets/windows/unofficial_inno_languages/Latvian.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/unofficial_inno_languages/Latvian.isl -------------------------------------------------------------------------------- /assets/windows/unofficial_inno_languages/Swedish.isl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/assets/windows/unofficial_inno_languages/Swedish.isl -------------------------------------------------------------------------------- /cordova/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "android": { 3 | "release": { 4 | "keystore": "release.jks", 5 | "storePassword": "rotorflight", 6 | "alias": "rotorflight", 7 | "password" : "rotorflight", 8 | "packageType": "apk" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /cordova/package_template.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "[INJECTED_BY_GULPFILE]", 3 | "displayName": "Rotorflight Configurator", 4 | "version": "[INJECTED_BY_GULPFILE]", 5 | "description": "[INJECTED_BY_GULPFILE]", 6 | "main": "index.js", 7 | "scripts": {}, 8 | "author": "[INJECTED_BY_GULPFILE]", 9 | "license": "[INJECTED_BY_GULPFILE]", 10 | "dependencies": { 11 | "bf-cordova-open-native-settings": "^2.0.4", 12 | "bf-cordova-plugin-appavailability": "^1.0.3", 13 | "bf-cordova-plugin-chrome-apps-usb": "^2.0.1", 14 | "bf-cordovarduino": "^1.0.0", 15 | "cordova": "^12.0.0", 16 | "cordova-android": "^12.0.0", 17 | "cordova-clipboard": "^1.3.0", 18 | "cordova-plugin-chrome-apps-common": "^1.0.7", 19 | "cordova-plugin-chrome-apps-runtime": "^2.0.0", 20 | "cordova-plugin-chrome-apps-storage": "^1.0.4", 21 | "cordova-plugin-dialogs": "^2.0.2", 22 | "cordova-plugin-file": "^8.1.0", 23 | "cordova-plugin-filechooser": "^1.2.0", 24 | "cordova-plugin-filepath": "^1.6.0", 25 | "cordova-plugin-market": "^1.2.0", 26 | "cordova-plugin-permission": "^0.1.0", 27 | "cordova-plugin-screen-orientation": "^3.0.4", 28 | "cordova-plugin-theme-detection": "^1.3.0", 29 | "cordova-plugin-usb-event": "^1.0.2", 30 | "es6-promise-plugin": "^4.2.2" 31 | }, 32 | "cordova": { 33 | "platforms": [ 34 | "android" 35 | ], 36 | "plugins": { 37 | "bf-cordova-open-native-settings": {}, 38 | "bf-cordova-plugin-appavailability": {}, 39 | "bf-cordova-plugin-chrome-apps-usb": {}, 40 | "bf-cordovarduino": {}, 41 | "cordova-clipboard": {}, 42 | "cordova-plugin-chrome-apps-common": {}, 43 | "cordova-plugin-chrome-apps-runtime": {}, 44 | "cordova-plugin-chrome-apps-storage": {}, 45 | "cordova-plugin-dialogs": {}, 46 | "cordova-plugin-file": {}, 47 | "cordova-plugin-filechooser": {}, 48 | "cordova-plugin-filepath": {}, 49 | "cordova-plugin-market": {}, 50 | "cordova-plugin-permission": {}, 51 | "cordova-plugin-screen-orientation": {}, 52 | "cordova-plugin-theme-detection": {}, 53 | "cordova-plugin-usb-event": {} 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /cordova/release.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/cordova/release.jks -------------------------------------------------------------------------------- /cordova/usb_device_filter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /crowdin.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Files configuration 3 | # 4 | "preserve_hierarchy": false 5 | 6 | files: [ 7 | { 8 | # 9 | # Source files filter 10 | # e.g. "/resources/en/*.json" 11 | # 12 | "source" : "/locales/en/messages.json", 13 | 14 | # 15 | # where translations live 16 | # e.g. "/resources/%two_letters_code%/%original_file_name%" 17 | # 18 | "translation" : "/locales/%two_letters_code%/%original_file_name%", 19 | 20 | # 21 | # Often software projects have custom names for locale directories. crowdin-cli allows you to map your own languages to be understandable by Crowdin. 22 | # 23 | "languages_mapping" : { 24 | "two_letters_code" : { 25 | "pt-BR" : "pt_BR", 26 | "zh-CN" : "zh_CN" 27 | } 28 | } 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import globals from "globals"; 2 | import pluginJs from "@eslint/js"; 3 | import pluginSvelte from "eslint-plugin-svelte"; 4 | 5 | /** @type {import('eslint').Linter.Config[]} */ 6 | export default [ 7 | { 8 | languageOptions: { 9 | globals: { ...globals.browser, ...globals.node, ...globals.jquery }, 10 | }, 11 | }, 12 | pluginJs.configs.recommended, 13 | ...pluginSvelte.configs["flat/recommended"], 14 | { 15 | rules: { 16 | semi: "error", 17 | "no-prototype-builtins": "off", 18 | "no-unused-vars": [ 19 | "error", 20 | { 21 | argsIgnorePattern: "^_", 22 | varsIgnorePattern: "^_", 23 | }, 24 | ], 25 | 26 | // TODO: The codebase makes extensive use of globals. This rule should be 27 | // enabled and remaining globals explicitly defined. 28 | "no-undef": "off", 29 | }, 30 | }, 31 | ]; 32 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /libraries/flightindicators.css: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery Flight Indicators plugin 3 | * By Sébastien Matton (seb_matton@hotmail.com) 4 | * Published under GPLv3 License. 5 | * 6 | * https://github.com/sebmatton/jQuery-Flight-Indicators 7 | */ 8 | 9 | /* Global block of an indicator*/ 10 | div.instrument { 11 | width: 250px; 12 | height: 250px; 13 | position: relative; 14 | display: inline-block; 15 | overflow: hidden; 16 | } 17 | 18 | /* The box containing any element of an indicator */ 19 | div.instrument .box { 20 | position: absolute; 21 | top: 0; 22 | left: 0; 23 | width: 100%; 24 | height: 100%; 25 | } 26 | 27 | /* Default transformations */ 28 | 29 | div.instrument.attitude div.roll { 30 | transform: rotate(0deg); 31 | } 32 | div.instrument.attitude div.roll div.pitch { 33 | top: 0%; 34 | } 35 | div.instrument.heading div.yaw { 36 | transform: rotate(0deg); 37 | } 38 | div.instrument.vario div.vario { 39 | transform: rotate(0deg); 40 | } 41 | div.instrument.speed div.airspeed { 42 | transform: rotate(90deg); 43 | } 44 | div.instrument.altimeter div.pressure { 45 | transform: rotate(40deg); 46 | } 47 | div.instrument.altimeter div.needle { 48 | transform: rotate(90deg); 49 | } 50 | div.instrument.altimeter div.needleSmall { 51 | transform: rotate(90deg); 52 | } 53 | -------------------------------------------------------------------------------- /libraries/jquery.ba-throttle-debounce.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery throttle / debounce - v1.1 - 3/7/2010 3 | * http://benalman.com/projects/jquery-throttle-debounce-plugin/ 4 | * 5 | * Copyright (c) 2010 "Cowboy" Ben Alman 6 | * Dual licensed under the MIT and GPL licenses. 7 | * http://benalman.com/about/license/ 8 | */ 9 | (function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this); -------------------------------------------------------------------------------- /libraries/openlayers/ol.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["src/ol/ol.css"],"names":[],"mappings":"AAAA,QACE,WAAY,WACZ,cAAe,IACf,OAAQ,IAAI,MAAM,KAGpB,mBACE,IAAK,IACL,MAAO,IACP,SAAU,SAGZ,eACE,WAAY,kBACZ,cAAe,IACf,OAAQ,IACR,KAAM,IACN,QAAS,IACT,SAAU,SAEZ,qBACE,OAAQ,IAAI,MAAM,KAClB,WAAY,KACZ,MAAO,KACP,UAAW,KACX,WAAY,OACZ,OAAQ,IACR,YAAa,QAAQ,CAAE,MAEzB,sBACE,YAAa,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAG9B,gBACE,QAAS,KAEG,iBAAd,aACE,sBAAuB,KACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KACb,4BAA6B,YAE/B,eACE,sBAAuB,QACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAEf,aACE,OAAQ,iBACR,OAAQ,cACR,OAAQ,SAEV,SACE,OAAQ,KACR,OAAQ,aACR,OAAQ,UACR,OAAQ,KAEV,YACE,SAAU,SACV,iBAAkB,qBAClB,cAAe,IACf,QAAS,IAEX,kBACE,iBAAkB,qBAEpB,SACE,IAAK,KACL,KAAM,KAER,WACE,IAAK,KACL,MAAO,KACP,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAEjD,qBACE,QAAS,EACT,WAAY,OACZ,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAAO,KAExD,gBACE,IAAK,QACL,KAAM,KAER,gBACE,MAAO,KACP,IAAK,KAEP,aACE,YACE,QAAS,MAIb,mBACE,QAAS,MACT,OAAQ,IACR,QAAS,EACT,MAAO,KACP,UAAW,OACX,YAAa,IACb,gBAAiB,KACjB,WAAY,OACZ,OAAQ,QACR,MAAO,QACP,YAAa,KACb,iBAAkB,kBAClB,OAAQ,KACR,cAAe,IAEjB,qCACE,OAAQ,KACR,QAAS,EAEX,uBACE,YAAa,MAEf,YACE,QAAS,MACT,YAAa,IACb,UAAW,MACX,YAAa,UAEf,6BACE,UAAW,MAEb,0BACE,IAAK,MAGP,yBADA,yBAEE,gBAAiB,KACjB,iBAAkB,kBAEpB,qBACE,cAAe,IAAI,IAAI,EAAE,EAE3B,sBACE,cAAe,EAAE,EAAE,IAAI,IAIzB,gBACE,WAAY,MACZ,OAAQ,KACR,MAAO,KACP,UAAW,mBAGb,mBACE,OAAQ,EACR,QAAS,EAAE,KACX,UAAW,MACX,YAAa,QACb,MAAO,KACP,YAAa,EAAE,EAAE,IAAI,KAEvB,mBACE,QAAS,OACT,WAAY,KACZ,YAAa,QAEf,0CACE,QAAS,IAEX,oBACE,WAAY,IACZ,UAAW,QACX,eAAgB,OAEE,uBAApB,mBACE,QAAS,aAEX,gCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,iCACE,OAAQ,EACR,MAAO,EACP,cAAe,IAAI,EAAE,EACrB,OAAQ,MACR,YAAa,IAEf,qCACE,WAAY,MACZ,WAAY,MAEd,wCACE,QAAS,KAGX,eACE,IAAK,MACL,KAAM,KACN,OAAQ,MAEV,sBACE,SAAU,SACV,OAAQ,KAGV,yBACE,IAAK,MAGP,gBACE,KAAM,KACN,OAAQ,KAEV,iCACE,OAAQ,EACR,KAAM,EACN,cAAe,EAAE,IAAI,EAAE,EAEzB,oCACA,uBACE,QAAS,aAEX,oCACE,OAAQ,IAAI,MAAM,QAClB,OAAQ,MACR,OAAQ,IACR,MAAO,MAET,0CACE,OAAQ,IACR,KAAM,IACN,SAAU,SAEZ,iDACA,wCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,oBACE,OAAQ,IAAI,OAAO,kBAGrB,0CACE,OAAQ"} -------------------------------------------------------------------------------- /lint-staged.config.mjs: -------------------------------------------------------------------------------- 1 | export default { 2 | "*.{js,mjs,svelte}": ["prettier --write", "eslint"], 3 | "*.scss": "prettier --write", 4 | }; 5 | -------------------------------------------------------------------------------- /prettier.config.mjs: -------------------------------------------------------------------------------- 1 | /** @type {import("prettier").Config} */ 2 | export default { 3 | plugins: ["prettier-plugin-svelte"], 4 | overrides: [{ files: "*.svelte", options: { parser: "svelte" } }], 5 | }; 6 | -------------------------------------------------------------------------------- /public/images: -------------------------------------------------------------------------------- 1 | ../src/images -------------------------------------------------------------------------------- /public/libraries: -------------------------------------------------------------------------------- 1 | ../libraries -------------------------------------------------------------------------------- /public/locales: -------------------------------------------------------------------------------- 1 | ../locales -------------------------------------------------------------------------------- /public/opensans_webfontkit/fonts.css: -------------------------------------------------------------------------------- 1 | /* Reordered to match the order on https://fonts.google.com/specimen/Open+Sans */ 2 | /* Also left a comment for each style not included */ 3 | @font-face { 4 | font-family: 'Open Sans'; 5 | src: url('opensans-light-webfont.woff2') format('woff2'), 6 | url('opensans-light-webfont.woff') format('woff'); 7 | font-weight: 300; 8 | font-style: normal; 9 | } 10 | /* Light Italic? */ 11 | @font-face { 12 | font-family: 'Open Sans'; 13 | src: url('opensans-regular-webfont.woff2') format('woff2'), 14 | url('opensans-regular-webfont.woff') format('woff'); 15 | font-weight: normal; 16 | font-style: normal; 17 | } 18 | @font-face { 19 | font-family: 'Open Sans'; 20 | src: url('opensans-italic-webfont.woff2') format('woff2'), 21 | url('opensans-italic-webfont.woff') format('woff'); 22 | font-weight: normal; 23 | font-style: italic; 24 | } 25 | @font-face { 26 | font-family: 'Open Sans'; 27 | src: url("opensans-semibold-webfont.woff2") format("woff2"), 28 | url("opensans-semibold-webfont.woff") format("woff"); 29 | font-weight: 600; 30 | font-style: normal; 31 | } 32 | /* Semi-Bold Italic */ 33 | @font-face { 34 | font-family: 'Open Sans'; 35 | src: url('opensans-bold-webfont.woff2') format('woff2'), 36 | url('opensans-bold-webfont.woff') format('woff'); 37 | font-weight: bold; 38 | font-style: normal; 39 | } 40 | @font-face { 41 | font-family: 'Open Sans'; 42 | src: url('opensans-bolditalic-webfont.woff2') format('woff2'), 43 | url('opensans-bolditalic-webfont.woff') format('woff'); 44 | font-weight: bold; 45 | font-style: italic; 46 | } 47 | /* Extra-Bold */ 48 | /* Extra-Bold Italic */ 49 | -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bold-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bold-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bold-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bold-webfont.woff2 -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bolditalic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bolditalic-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bolditalic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bolditalic-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-bolditalic-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-bolditalic-webfont.woff2 -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-italic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-italic-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-italic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-italic-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-italic-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-italic-webfont.woff2 -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-light-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-light-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-light-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-light-webfont.woff2 -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-regular-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-regular-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-regular-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-regular-webfont.woff2 -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-semibold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-semibold-webfont.ttf -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-semibold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-semibold-webfont.woff -------------------------------------------------------------------------------- /public/opensans_webfontkit/opensans-semibold-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/public/opensans_webfontkit/opensans-semibold-webfont.woff2 -------------------------------------------------------------------------------- /public/resources: -------------------------------------------------------------------------------- 1 | ../resources -------------------------------------------------------------------------------- /resources/models/bell_ccw.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/resources/models/bell_ccw.bin -------------------------------------------------------------------------------- /resources/models/bell_ccw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/resources/models/bell_ccw.png -------------------------------------------------------------------------------- /resources/models/bell_cw.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/resources/models/bell_cw.bin -------------------------------------------------------------------------------- /resources/models/bell_cw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/resources/models/bell_cw.png -------------------------------------------------------------------------------- /src/components/BatteryLegend.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 | {value} 18 | -------------------------------------------------------------------------------- /src/components/Field.svelte: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | 18 |
19 | {#if tooltip} 20 | 21 | {@render children?.()} 22 | 23 | {:else} 24 | {@render children?.()} 25 | {/if} 26 |
27 |
28 | 29 | 71 | -------------------------------------------------------------------------------- /src/components/HelpIcon.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 | 9 | {#snippet tooltip()} 10 | {@render children?.()} 11 | {/snippet} 12 |
13 |
14 |
15 | 16 | 47 | -------------------------------------------------------------------------------- /src/components/StatusBar.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 | 11 | {$i18n.t("statusbar_port_utilization")} 12 | 13 | {portUsage.down.toFixed()}% 14 | 15 | {portUsage.up.toFixed()}% 16 | 17 | {$i18n.t("statusbar_packet_error")} {MSP.packet_error} 18 | {$i18n.t("statusbar_pid_cycle_time")} {FC.CONFIG.pidCycleTime} 19 | {$i18n.t("statusbar_gyro_cycle_time")} {FC.CONFIG.gyroCycleTime} 20 | {$i18n.t("statusbar_rt_load")} {FC.CONFIG.rtLoad}% 21 | {$i18n.t("statusbar_cpu_load")} {FC.CONFIG.cpuLoad}% 22 | 23 |
24 | 25 | {#if FC.CONFIG.buildVersion && FC.CONFIG.flightControllerIdentifier} 26 | 27 | {$i18n.t("versionLabelFirmware")} 28 | {FC.CONFIG.buildVersion} 29 | {FC.CONFIG.flightControllerIdentifier} 30 | 31 | {/if} 32 | {$i18n.t("versionLabelConfigurator")}: {CONFIGURATOR.version} 33 |
34 | 35 | 71 | -------------------------------------------------------------------------------- /src/components/SubSection.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 | {#if label} 9 |
10 | {$i18n.t(label)} 11 |
12 | {/if} 13 |
{@render children?.()}
14 |
15 | 16 | 38 | -------------------------------------------------------------------------------- /src/components/Switch.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 75 | -------------------------------------------------------------------------------- /src/components/ToggleFieldGroup.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |
9 | 10 |
11 |
12 | {@render children?.()} 13 |
14 |
15 | 16 | 39 | -------------------------------------------------------------------------------- /src/components/Tooltip.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 | 9 | {@html $i18n.t(help)} 10 | {#if attrs} 11 |
12 | {#each attrs as attr} 13 |

{$i18n.t(attr.name)}: {attr.value}

14 | {/each} 15 |
16 | {/if} 17 |
18 | 19 | 29 | -------------------------------------------------------------------------------- /src/components/notes/ErrorNote.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | {$i18n.t("errorTitle")} 10 |
11 |
12 | {#if children} 13 | {@render children()} 14 | {:else if typeof message === "string"} 15 | 16 | {@html $i18n.t(message)} 17 | {/if} 18 |
19 |
20 | 21 | 48 | -------------------------------------------------------------------------------- /src/components/notes/WarningNote.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | {$i18n.t("warningTitle")} 10 |
11 |
12 | {#if children} 13 | {@render children()} 14 | {:else if typeof message === "string"} 15 | 16 | {@html $i18n.t(message)} 17 | {/if} 18 |
19 |
20 | 21 | 47 | -------------------------------------------------------------------------------- /src/css/_global.scss: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | select, 8 | input { 9 | margin: 0; 10 | border-width: 1px; 11 | border-style: solid; 12 | border-radius: 2px; 13 | 14 | &:focus { 15 | outline: none; 16 | } 17 | 18 | :global(html[data-theme="light"]) & { 19 | color: var(--color-neutral-900); 20 | background: var(--color-neutral-50); 21 | border-color: var(--color-neutral-300); 22 | 23 | &:focus { 24 | border-color: var(--color-accent-500); 25 | } 26 | 27 | &:disabled { 28 | color: var(--color-neutral-500); 29 | background: var(--color-neutral-200); 30 | } 31 | } 32 | 33 | :global(html[data-theme="dark"]) & { 34 | color: var(--color-neutral-100); 35 | background: var(--color-neutral-800); 36 | border-color: var(--color-neutral-700); 37 | 38 | &:focus { 39 | border-color: var(--color-accent-400); 40 | } 41 | 42 | &:disabled { 43 | color: var(--color-neutral-500); 44 | background: var(--color-neutral-700); 45 | } 46 | } 47 | } 48 | 49 | input { 50 | line-height: 1.5rem; 51 | 52 | &[type="number"] { 53 | text-align: right; 54 | padding-right: 0; 55 | width: 80px; 56 | } 57 | } 58 | 59 | select { 60 | height: 1.5rem; 61 | min-width: 120px; 62 | padding: 0 4px; 63 | } 64 | 65 | @media only screen and (max-width: 480px) { 66 | select, 67 | input { 68 | height: 2rem; 69 | line-height: 2rem; 70 | } 71 | 72 | input { 73 | font-size: 1rem !important; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/css/dropdown-lists/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2013 Thibaut Courouble 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/css/select2_custom.css: -------------------------------------------------------------------------------- 1 | /* Select 2 replacement styles */ 2 | .select2 { 3 | font-family: Arial, Helvetica, sans-serif; 4 | font-weight: 400; 5 | font-size: 13.3333px; 6 | } 7 | 8 | .select2-selection__rendered { 9 | line-height: 18.5px !important; 10 | padding-left: 4px !important; 11 | color: var(--defaultText) !important; 12 | border-radius: 2px !important; 13 | } 14 | 15 | .select2-container .select2-selection--single { 16 | height: 20px !important; 17 | border-radius: 3px !important; 18 | border: 0.5px solid var(--subtleAccent) !important; 19 | cursor: default !important; 20 | } 21 | 22 | .select2-selection__arrow { 23 | height: 19px !important; 24 | } 25 | .select2-selection__arrow b { 26 | height: 5px !important; 27 | width: 5px !important; 28 | margin-left: -2px !important; 29 | margin-top: -5px !important; 30 | border: none !important; 31 | border-bottom: 1.5px solid black !important; 32 | border-right: 1.5px solid black !important; 33 | transform: rotateZ(45deg); 34 | } 35 | .select2-dropdown { 36 | border: 0.5px solid var(--subtleAccent) !important; 37 | border-top: none !important; 38 | border-radius: 2px !important; 39 | } 40 | -------------------------------------------------------------------------------- /src/css/slider.css: -------------------------------------------------------------------------------- 1 | .noUi-base { 2 | background: var(--alternativeBackground); 3 | border-color: #999; 4 | box-shadow: none; 5 | } 6 | 7 | .noUi-horizontal .noUi-handle { 8 | height: 28px; 9 | width: 28px; 10 | right: -14px; 11 | border-radius: 14px; 12 | 13 | background: var(--sideBackground); 14 | border-color: #999; 15 | box-shadow: none; 16 | } 17 | 18 | .noUi-connect, 19 | .noUi-origin { 20 | -webkit-transition: transform 300ms; 21 | transition: transform 300ms; 22 | } 23 | 24 | .noUi-handle:before, 25 | .noUi-handle:after { 26 | background-color: #999; 27 | height: 10px; 28 | width: 2px; 29 | top: 16px; 30 | left: 12px; 31 | } 32 | 33 | .noUi-connect { 34 | box-shadow: none; 35 | background: var(--accent); 36 | } 37 | 38 | /* Disabled Theme */ 39 | 40 | .noUi-target[disabled] { 41 | border-color: var(--subtleAccent); 42 | } 43 | 44 | .noUi-target[disabled] .noUi-base { 45 | background: var(--subtleAccent); 46 | } 47 | 48 | .noUi-target[disabled] .noUi-connect { 49 | background: var(--subtleAccent); 50 | } 51 | 52 | .noUi-target[disabled] .noUi-handle { 53 | background-color: var(--subtleAccent); 54 | } 55 | 56 | /* Dark Theme */ 57 | 58 | html[data-theme="dark"] .noUi-pips { 59 | color: var(--mutedText); 60 | } 61 | 62 | html[data-theme="dark"] .noUi-target, 63 | html[data-theme="dark"] .noUi-handle { 64 | border-color: var(--subtleAccent); 65 | } 66 | 67 | /* Dark Disabled Theme */ 68 | 69 | html[data-theme="dark"] .noUi-target[disabled] { 70 | border-color: #888; 71 | } 72 | 73 | html[data-theme="dark"] .noUi-target[disabled] .noUi-base { 74 | background: var(--alternativeBackground); 75 | } 76 | 77 | html[data-theme="dark"] .noUi-target[disabled] .noUi-handle { 78 | background-color: #444; 79 | } 80 | 81 | html[data-theme="dark"] .noUi-target[disabled] .noUi-handle:before, 82 | html[data-theme="dark"] .noUi-target[disabled] .noUi-handle:after { 83 | border-color: #888; 84 | background: #888; 85 | } 86 | -------------------------------------------------------------------------------- /src/css/switchery_custom.css: -------------------------------------------------------------------------------- 1 | .switchery { 2 | height: 14px; 3 | width: 45px; 4 | z-index:1000; 5 | opacity:1 !important; 6 | -moz-user-select: none; 7 | -khtml-user-select: none; 8 | -webkit-user-select: none; 9 | -ms-user-select: none; 10 | user-select: none; 11 | box-sizing: content-box; 12 | background-clip: content-box; 13 | } 14 | 15 | .switchery > small { 16 | height: 14px; 17 | width: 14px; 18 | } 19 | 20 | .switcherymid { 21 | background-color: #fff; 22 | border: 1px solid #fff; 23 | border-radius: 20px; 24 | cursor: pointer; 25 | display: inline-block; 26 | height: 14px; 27 | position: relative; 28 | vertical-align: middle; 29 | width: 35px; 30 | -moz-user-select: none; 31 | -khtml-user-select: none; 32 | -webkit-user-select: none; 33 | -ms-user-select: none; 34 | user-select: none; 35 | box-sizing: content-box; 36 | background-clip: content-box; 37 | } 38 | 39 | .switcherymid > small { 40 | background: #fff; 41 | border-radius: 100%; 42 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); 43 | height: 14px; 44 | position: absolute; 45 | top: 0; 46 | width: 14px; 47 | } 48 | 49 | /* Switchery sizes. */ 50 | 51 | .switchery-small { 52 | border: none !important; 53 | height: 10px; 54 | width: 20px; 55 | margin-top:-3px; 56 | margin-right:3px; 57 | } 58 | 59 | .switchery-small > small { 60 | height: 10px; 61 | width: 10px; 62 | } 63 | -------------------------------------------------------------------------------- /src/css/tabs/help.css: -------------------------------------------------------------------------------- 1 | .tab-help .gui_box { 2 | min-height: 500px; 3 | margin-bottom: 0; 4 | } 5 | 6 | .tab-help ul { 7 | margin-bottom:15px; 8 | } 9 | 10 | .tab-help li { 11 | border-top: 1px dotted var(--subtleAccent); 12 | padding-top: 5px; 13 | padding-bottom: 5px; 14 | background-image: url(/images/arrow.svg); 15 | background-repeat: no-repeat; 16 | background-position: 0 8px; 17 | background-size: 12px; 18 | } 19 | 20 | .tab-help li span { 21 | margin-left: 17px; 22 | display:block; 23 | } 24 | 25 | .tab-help li span a { 26 | color: var(--accent); 27 | } 28 | 29 | .tab-help .subline { 30 | margin-bottom: 5px; 31 | } 32 | 33 | /** (phones) **/ 34 | @media all and (max-width: 575px) { 35 | .tab-help .gui_box { 36 | min-height: auto; 37 | margin-bottom: 15px; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/css/tabs/options.css: -------------------------------------------------------------------------------- 1 | .tab-options .freelabel { 2 | margin-left: 10px; 3 | position: relative; 4 | } 5 | .tab-options .switchery { 6 | float: left; 7 | } 8 | .tab-options .margin-bottom { 9 | margin-bottom: 10px; 10 | } 11 | .tab-options select { 12 | background: var(--boxBackground); 13 | color: var(--defaultText); 14 | border: 1px solid var(--subtleAccent); 15 | border-radius: 3px; 16 | width: fit-content; 17 | } 18 | -------------------------------------------------------------------------------- /src/css/tabs/power.css: -------------------------------------------------------------------------------- 1 | #tab-power-templates { 2 | display: none; 3 | } 4 | 5 | .tab-power .ui-grid-col { 6 | margin-bottom: 0; 7 | } 8 | 9 | .tab-power td.configuration { 10 | padding-top: 5px; 11 | text-align: left; 12 | } 13 | 14 | .tab-power .battery-state .configuration { 15 | border-bottom: 0; 16 | } 17 | 18 | .tab-power td.value { 19 | text-align: left; 20 | width: 20%; 21 | } 22 | 23 | .tab-power .label { 24 | width: 25%; 25 | } 26 | 27 | .tab-power .number input { 28 | width: 50px; 29 | padding-left: 3px; 30 | height: 20px; 31 | line-height: 20px; 32 | text-align: left; 33 | border: 1px solid var(--subtleAccent); 34 | border-radius: 3px; 35 | margin-right: 11px; 36 | font-size: 12px; 37 | font-weight: normal; 38 | } 39 | 40 | .tab-power .number, 41 | .tab-power .select { 42 | margin-bottom: 2px; 43 | padding-bottom: 2px; 44 | width: 100%; 45 | float: left; 46 | clear: left; 47 | } 48 | 49 | .tab-power .battery-configuration select { 50 | border: 1px solid var(--subtleAccent); 51 | border-radius: 3px; 52 | margin-right: 5px; 53 | float: left; 54 | width: 150px; 55 | } 56 | 57 | .tab-power .number:last-child, 58 | .tab-power .select:last-child { 59 | border-bottom: none; 60 | padding-bottom: 0; 61 | margin-bottom: 0; 62 | } 63 | 64 | .tab-power .voltage-meter td, 65 | .tab-power .amperage-meter td { 66 | padding: 8px; 67 | } 68 | 69 | .tab-power .voltage-meter .label, 70 | .tab-power .voltage-meter .value, 71 | .tab-power .amperage-meter .label, 72 | .tab-power .amperage-meter .value { 73 | font-size: 12px; 74 | font-weight: 600; 75 | } 76 | -------------------------------------------------------------------------------- /src/css/tabs/privacy_policy.css: -------------------------------------------------------------------------------- 1 | .tab-privacy_policy p, 2 | .tab-privacy_policy h1, 3 | .tab-privacy_policy h2, 4 | .tab-privacy_policy h3, 5 | .tab-privacy_policy h4 { 6 | margin-bottom: 10px; 7 | } 8 | 9 | .tab-privacy_policy li { 10 | margin-bottom: 0px !important; 11 | } 12 | -------------------------------------------------------------------------------- /src/css/tabs/static_tab.css: -------------------------------------------------------------------------------- 1 | #tab-static { 2 | background-color: inherit; 3 | background-image: url(/images/osd-bg-1.jpg); 4 | background-attachment: fixed; 5 | background-size: cover; 6 | background-position: bottom right; 7 | } 8 | 9 | #tab-static span { 10 | display: block; 11 | font-weight: bold; 12 | padding-top: 16px; 13 | padding-bottom: 5px; 14 | border-bottom: 1px solid var(--subtleAccent); 15 | } 16 | 17 | #tab-static .title { 18 | font-size: 16px; 19 | } 20 | 21 | #tab-static ul { 22 | margin: 5px 0 20px 10px; 23 | } 24 | 25 | #tab-static li { 26 | font-weight: normal; 27 | margin-bottom: 5px; 28 | } 29 | 30 | #tab-static-contents { 31 | padding-top: 10px; 32 | padding-left: 16px; 33 | padding-right: 16px; 34 | padding-bottom: 40px; 35 | background-color: inherit; 36 | max-width: 650px; 37 | } 38 | -------------------------------------------------------------------------------- /src/images/arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 11 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/images/arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/arrows.png -------------------------------------------------------------------------------- /src/images/bf_icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/bf_icon.icns -------------------------------------------------------------------------------- /src/images/bf_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/bf_icon.ico -------------------------------------------------------------------------------- /src/images/bf_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/bf_icon_128.png -------------------------------------------------------------------------------- /src/images/bf_icon_128.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/bf_icon_128.psd -------------------------------------------------------------------------------- /src/images/discord_logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/facebook_logo.svg: -------------------------------------------------------------------------------- 1 | flogo_RGB_HEX-1024 -------------------------------------------------------------------------------- /src/images/flightindicators/fi_box.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/images/flightindicators/fi_circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/images/flightindicators/fi_needle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/images/flightindicators/fi_needle_small.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 20 | 21 | 22 | 24 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/images/flightindicators/horizon_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_adjust_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_adjust_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_advanced_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_advanced_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_armed_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_backup_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_backup_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_bat_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_cli_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_cli_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_config_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_config_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_data_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_data_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 9 | 11 | 13 | 15 | 17 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_failsafe_active.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_failsafe_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_failsafe_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_flasher_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_flasher_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_gps_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 12 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_gps_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 12 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_help_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_help_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_info_blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_info_green.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_info_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_info_orange.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_info_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_led_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_led_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_link_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_log_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_log_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_mission_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_mission_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_modes_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_modes_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 10 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_motor_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_motor_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_pid_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_pid_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_pitch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_ports_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_ports_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 12 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/cf_icon_position.png -------------------------------------------------------------------------------- /src/images/icons/cf_icon_position_nofix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/cf_icon_position_nofix.png -------------------------------------------------------------------------------- /src/images/icons/cf_icon_power_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_power_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_roll.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_rx_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_rx_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_search_rf_blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_sensors_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_sensors_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_servo_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_servo_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_settings_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 12 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_setup_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_setup_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_usb1_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_usb2_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_vtx_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 15 | 17 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_vtx_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 15 | 17 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_welcome_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_welcome_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 12 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_wizard_grey.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_wizard_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/cf_icon_yaw.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/images/icons/close1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/images/icons/cross2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/images/icons/icon_bracket.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /src/images/icons/icon_osd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 11 | 13 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/images/icons/icon_osd_white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 9 | 11 | 13 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/images/icons/sensor_acc_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_acc_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_acc_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_acc_on.png -------------------------------------------------------------------------------- /src/images/icons/sensor_baro_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_baro_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_baro_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_baro_on.png -------------------------------------------------------------------------------- /src/images/icons/sensor_gyro_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_gyro_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_gyro_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_gyro_on.png -------------------------------------------------------------------------------- /src/images/icons/sensor_mag_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_mag_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_mag_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_mag_on.png -------------------------------------------------------------------------------- /src/images/icons/sensor_sat_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_sat_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_sat_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_sat_on.png -------------------------------------------------------------------------------- /src/images/icons/sensor_sonar_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_sonar_off.png -------------------------------------------------------------------------------- /src/images/icons/sensor_sonar_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/icons/sensor_sonar_on.png -------------------------------------------------------------------------------- /src/images/icons/star_rf_blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Layer 1 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/icons/star_rf_blue_stroke.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Layer 1 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/icons/star_transparent.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Layer 1 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/images/loading-bars.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/images/loading-spin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/images/osd-bg-1-grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/osd-bg-1-grid.png -------------------------------------------------------------------------------- /src/images/osd-bg-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/osd-bg-1.jpg -------------------------------------------------------------------------------- /src/images/osd-bg-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/osd-bg-2.png -------------------------------------------------------------------------------- /src/images/paper-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/paper-dark.png -------------------------------------------------------------------------------- /src/images/paper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/paper.png -------------------------------------------------------------------------------- /src/images/pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/pattern.png -------------------------------------------------------------------------------- /src/images/rf_icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/rf_icon.icns -------------------------------------------------------------------------------- /src/images/rf_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/rf_icon.ico -------------------------------------------------------------------------------- /src/images/rf_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/images/rf_icon.png -------------------------------------------------------------------------------- /src/js/DarkTheme.js: -------------------------------------------------------------------------------- 1 | import { windowWatcherUtil } from '@/js/utils/window_watchers.js'; 2 | 3 | export const DarkTheme = { 4 | configEnabled: undefined, 5 | }; 6 | 7 | DarkTheme.isDarkThemeEnabled = function (callback) { 8 | if (this.configEnabled === 0) { 9 | callback(true); 10 | } else if (this.configEnabled === 2) { 11 | if (GUI.isCordova()) { 12 | cordova.plugins.ThemeDetection.isDarkModeEnabled(function(success) { 13 | callback(success.value); 14 | }, function(error) { 15 | console.log(`cordova-plugin-theme-detection: ${error}`); 16 | callback(false); 17 | }); 18 | } else { 19 | const isEnabled = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; 20 | callback(isEnabled); 21 | } 22 | } else { 23 | callback(false); 24 | } 25 | }; 26 | 27 | DarkTheme.apply = function() { 28 | const self = this; 29 | this.isDarkThemeEnabled(async function(isEnabled) { 30 | if (isEnabled) { 31 | self.applyDark(); 32 | } else { 33 | self.applyNormal(); 34 | } 35 | 36 | if (GUI.isNWJS()) { 37 | const windows = await new Promise(resolve => GUI.nwGui.Window.getAll(resolve)); 38 | for (const win of windows) { 39 | windowWatcherUtil.passValue(win.window, 'darkTheme', isEnabled); 40 | } 41 | } 42 | }); 43 | }; 44 | 45 | DarkTheme.autoSet = function() { 46 | if (this.configEnabled === 2) { 47 | this.apply(); 48 | } 49 | }; 50 | 51 | DarkTheme.setConfig = function (result) { 52 | if (this.configEnabled !== result) { 53 | this.configEnabled = result; 54 | this.apply(); 55 | } 56 | }; 57 | 58 | DarkTheme.applyDark = function () { 59 | document.documentElement.setAttribute('data-theme', 'dark'); 60 | }; 61 | 62 | DarkTheme.applyNormal = function () { 63 | document.documentElement.setAttribute('data-theme', 'light'); 64 | }; 65 | -------------------------------------------------------------------------------- /src/js/GitHubApi.js: -------------------------------------------------------------------------------- 1 | export const GitHubApi = function () 2 | { 3 | const self = this; 4 | 5 | self.GITHUB_API_URL = "https://api.github.com/"; 6 | }; 7 | 8 | GitHubApi.prototype.getFileLastCommitInfo = function (project, branch, filename, callback) 9 | { 10 | const self = this; 11 | 12 | $.getJSON(`${self.GITHUB_API_URL}repos/${encodeURI(project)}/commits?sha=${encodeURIComponent(branch)}&path=${encodeURIComponent(filename)}`, function (commits) { 13 | const result = {}; 14 | try { 15 | result.commitHash = commits[0].sha.substring(0, 8); 16 | result.date = commits[0].commit.author.date; 17 | } catch (exception) { 18 | console.log(`Error while parsing commit: ${exception}`); 19 | } 20 | 21 | console.log(`Found commit info for file ${filename}:`, result); 22 | 23 | callback(result); 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /src/js/clipboard.js: -------------------------------------------------------------------------------- 1 | /** @type {(text: string) => Promise} */ 2 | export let writeText; 3 | 4 | /** @type {() => Promise} */ 5 | export let readText; 6 | 7 | if (__BACKEND__ === "nwjs") { 8 | writeText = function (text) { 9 | try { 10 | globalThis.nw.Clipboard.get().set(text, "text"); 11 | return Promise.resolve(); 12 | } catch (err) { 13 | return Promise.reject(err); 14 | } 15 | }; 16 | 17 | readText = function () { 18 | try { 19 | return Promise.resolve(globalThis.nw.Clipboard.get().get("text")); 20 | } catch (err) { 21 | return Promise.reject(err); 22 | } 23 | }; 24 | } 25 | 26 | if (__BACKEND__ === "cordova") { 27 | writeText = function (text) { 28 | return new Promise((resolve, reject) => { 29 | cordova.plugins.clipboard.copy(text, resolve, reject); 30 | }); 31 | }; 32 | 33 | readText = function () { 34 | return new Promise((resolve, reject) => { 35 | cordova.plugins.clipboard.paste(resolve, reject); 36 | }); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /src/js/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} key 3 | */ 4 | export function get(key) { 5 | try { 6 | return JSON.parse(globalThis.localStorage.getItem(key))[key]; 7 | } catch { 8 | // 9 | } 10 | } 11 | 12 | /** 13 | * @param {Object} obj key value entries to set 14 | */ 15 | export function set(obj) { 16 | for (const [key, value] of Object.entries(obj)) { 17 | globalThis.localStorage.setItem(key, JSON.stringify({ [key]: value })); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/js/cordova_startup.js: -------------------------------------------------------------------------------- 1 | import * as config from "@/js/config.js"; 2 | 3 | export const cordovaUI = { 4 | uiZoom: 1, 5 | canChangeUI: true, 6 | init: async function() { 7 | const self = this; 8 | const screenWidth = $(window).width(); 9 | const screenHeight = $(window).height(); 10 | let length; 11 | let orientation; 12 | if (screenWidth > screenHeight) { 13 | length = screenWidth; 14 | orientation = 'landscape'; 15 | } else { 16 | length = screenHeight; 17 | orientation = 'portrait'; 18 | } 19 | if (length < 1024) { 20 | self.uiZoom = length/1024; 21 | } 22 | if (screenWidth > 575 && screenHeight > 575) { 23 | self.canChangeUI = false; 24 | } 25 | 26 | if (config.get('cordovaForceComputerUI') === undefined) { 27 | if ((orientation === 'landscape' && screenHeight <= 575) 28 | || (orientation === 'portrait' && screenWidth <= 575)) { 29 | config.set({'cordovaForceComputerUI': false}); 30 | } else { 31 | config.set({'cordovaForceComputerUI': true}); 32 | } 33 | } 34 | self.set(); 35 | }, 36 | set: function() { 37 | if (config.get('cordovaForceComputerUI')) { 38 | window.screen.orientation.lock('landscape'); 39 | $('body').css('zoom', this.uiZoom); 40 | } else { 41 | window.screen.orientation.lock('portrait'); 42 | $('body').css('zoom', 1); 43 | } 44 | }, 45 | }; 46 | 47 | export const cordovaApp = { 48 | initialize: function() { 49 | this.bindEvents(); 50 | }, 51 | bindEvents: function() { 52 | document.addEventListener('deviceready', this.onDeviceReady, false); 53 | }, 54 | onDeviceReady: function() { 55 | $('.open_firmware_flasher, .tab_firmware_flasher').hide(); 56 | cordovaUI.init(); 57 | navigator.splashscreen.hide(); 58 | cordovaChromeapi.init(); 59 | appReady(); 60 | }, 61 | }; 62 | -------------------------------------------------------------------------------- /src/js/data_storage.js: -------------------------------------------------------------------------------- 1 | export const API_VERSION_1_31 = '1.31.0'; 2 | export const API_VERSION_1_32 = '1.32.0'; 3 | export const API_VERSION_1_33 = '1.33.0'; 4 | export const API_VERSION_1_34 = '1.34.0'; 5 | export const API_VERSION_1_35 = '1.35.0'; 6 | export const API_VERSION_1_36 = '1.36.0'; 7 | export const API_VERSION_1_37 = '1.37.0'; 8 | export const API_VERSION_1_38 = '1.38.0'; 9 | export const API_VERSION_1_39 = '1.39.0'; 10 | export const API_VERSION_1_40 = '1.40.0'; 11 | export const API_VERSION_1_41 = '1.41.0'; 12 | export const API_VERSION_1_42 = '1.42.0'; 13 | export const API_VERSION_1_43 = '1.43.0'; 14 | export const API_VERSION_1_44 = '1.44.0'; 15 | 16 | export const API_VERSION_12_6 = '12.6.0'; 17 | export const API_VERSION_12_7 = '12.7.0'; 18 | export const API_VERSION_12_8 = '12.8.0'; 19 | 20 | export const API_VERSION_RTFL_MIN = API_VERSION_12_6; 21 | export const API_VERSION_RTFL_MAX = API_VERSION_12_8; 22 | 23 | export const FW_VERSION_RTFL_MIN = '4.3.0-0'; 24 | export const FW_VERSION_RTFL_MAX = '4.5.99'; 25 | 26 | export const CONFIGURATOR = { 27 | // all versions are specified and compared using semantic versioning http://semver.org/ 28 | API_VERSION_MIN_SUPPORTED: API_VERSION_RTFL_MIN, 29 | API_VERSION_MAX_SUPPORTED: API_VERSION_RTFL_MAX, 30 | API_VERSION_ACCEPTED: API_VERSION_RTFL_MIN, 31 | 32 | FW_VERSION_MIN_SUPPORTED: FW_VERSION_RTFL_MIN, 33 | FW_VERSION_MAX_SUPPORTED: FW_VERSION_RTFL_MAX, 34 | 35 | API_VERSION_MIN_SUPPORTED_BACKUP_RESTORE: API_VERSION_RTFL_MIN, 36 | BACKUP_FILE_VERSION_MIN_SUPPORTED: API_VERSION_RTFL_MIN, 37 | 38 | connectionValid: false, 39 | connectionValidCliOnly: false, 40 | virtualMode: false, 41 | virtualApiVersion: '0.0.1', 42 | cliEngineActive: false, 43 | cliEngineValid: false, 44 | cliTab: '', 45 | gitChangesetId: 'unknown', 46 | version: '0.0.1', 47 | latestVersion: '0.0.1', 48 | latestVersionReleaseUrl: 'https://github.com/rotorflight/rotorflight-configurator/releases', 49 | allReleasesUrl: 'https://github.com/rotorflight/rotorflight-configurator/releases', 50 | }; 51 | -------------------------------------------------------------------------------- /src/js/features.svelte.js: -------------------------------------------------------------------------------- 1 | export class Features { 2 | static FLAGS = { 3 | RX_PPM: 0, 4 | RX_SERIAL: 3, 5 | SOFTSERIAL: 6, 6 | GPS: 7, 7 | SONAR: 9, 8 | TELEMETRY: 10, 9 | RX_PARALLEL_PWM: 13, 10 | RX_MSP: 14, 11 | RSSI_ADC: 15, 12 | LED_STRIP: 16, 13 | DISPLAY: 17, 14 | OSD: 18, 15 | CMS: 19, 16 | RX_SPI: 25, 17 | GOVERNOR: 26, 18 | ESC_SENSOR: 27, 19 | FREQ_SENSOR: 28, 20 | DYN_NOTCH: 29, 21 | RPM_FILTER: 30, 22 | }; 23 | 24 | static GROUPS = { 25 | RX_PROTO: ["RX_PPM", "RX_SERIAL", "RX_PARALLEL_PWM", "RX_MSP", "RX_SPI"], 26 | OTHER: ["GPS", "LED_STRIP", "CMS"], 27 | RSSI: ["RSSI_ADC"], 28 | }; 29 | 30 | bitfield = $state(0); 31 | 32 | constructor() { 33 | // allow each flag in the bitfield to be accessed as a regular property 34 | for (const feature of Object.keys(Features.FLAGS)) { 35 | Object.defineProperty(this, feature, { 36 | get() { 37 | return this.isEnabled(feature); 38 | }, 39 | set(v) { 40 | this.setFeature(feature, v); 41 | }, 42 | }); 43 | } 44 | } 45 | 46 | isEnabled(featureName) { 47 | return bit_check(this.bitfield, Features.FLAGS[featureName]); 48 | } 49 | 50 | setFeature(featureName, enabled) { 51 | this.bitfield = enabled 52 | ? bit_set(this.bitfield, Features.FLAGS[featureName]) 53 | : bit_clear(this.bitfield, Features.FLAGS[featureName]); 54 | } 55 | 56 | setGroup(groupName, enabled) { 57 | for (const featureName of Features.GROUPS[groupName]) { 58 | this.setFeature(featureName, enabled); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/js/huffman.js: -------------------------------------------------------------------------------- 1 | export const HUFFMAN_EOF = -1; 2 | 3 | export function huffmanDecodeBuf(inBuf, inBufCharacterCount, huffmanTree, huffmanLenIndex) { 4 | let code = 0; 5 | let codeLen = 0; 6 | let testBit = 0x80; 7 | let eof = false; 8 | const outBuf = []; 9 | 10 | while (!eof && inBuf.byteLength != 0) { 11 | if (outBuf.length == inBufCharacterCount) { 12 | // we've exhausted the input stream, discard any odd bits on the end 13 | break; 14 | } 15 | 16 | if (inBuf.byteLength == 0) { 17 | throw new Error('unexpected'); 18 | } 19 | 20 | // get the next bit from the input buffer 21 | code <<= 1; 22 | ++codeLen; 23 | if (inBuf[0] & testBit) { 24 | code |= 0x01; 25 | } 26 | testBit >>= 1; 27 | if (testBit == 0) { 28 | testBit = 0x80; 29 | inBuf = inBuf.subarray(1); 30 | } 31 | 32 | // check if the code is a leaf node or an interior node 33 | if (huffmanLenIndex[codeLen] != -1) { 34 | // look for the code in the tree, only leaf nodes are stored in the tree 35 | for (let i = huffmanLenIndex[codeLen]; (i < huffmanTree.length) && (huffmanTree[i].codeLen === codeLen); ++i) { 36 | if (huffmanTree[i].code === code) { 37 | // we've found the code, so it is a leaf node 38 | const value = huffmanTree[i].value; 39 | 40 | if (value == HUFFMAN_EOF) { 41 | eof = true; 42 | } else { 43 | // output the value 44 | outBuf.push(value); 45 | } 46 | 47 | // reset the code to continue decompressing the input buffer 48 | code = 0; 49 | codeLen = 0; 50 | break; 51 | } 52 | } 53 | } 54 | } 55 | 56 | return new Uint8Array(outBuf); 57 | } 58 | -------------------------------------------------------------------------------- /src/js/i18n.js: -------------------------------------------------------------------------------- 1 | import i18next from 'i18next'; 2 | import { createI18nStore } from "svelte-i18next"; 3 | 4 | export const i18n = createI18nStore(i18next); 5 | -------------------------------------------------------------------------------- /src/js/injected_methods.js: -------------------------------------------------------------------------------- 1 | Number.prototype.clamp = function(min, max) { 2 | return Math.min(Math.max(this, min), max); 3 | }; 4 | 5 | Array.prototype.push8 = function(val) { 6 | this.push(0xFF & val); 7 | return this; 8 | }; 9 | 10 | Array.prototype.push16 = function(val) { 11 | // low byte 12 | this.push(0x00FF & val); 13 | // high byte 14 | this.push(val >> 8); 15 | // chainable 16 | return this; 17 | }; 18 | 19 | Array.prototype.push32 = function(val) { 20 | this.push8(val) 21 | .push8(val >> 8) 22 | .push8(val >> 16) 23 | .push8(val >> 24); 24 | return this; 25 | }; 26 | 27 | DataView.prototype.offset = 0; 28 | DataView.prototype.readU8 = function() { 29 | if (this.byteLength >= this.offset+1) { 30 | return this.getUint8(this.offset++); 31 | } else { 32 | return null; 33 | } 34 | }; 35 | 36 | DataView.prototype.readU16 = function() { 37 | if (this.byteLength >= this.offset+2) { 38 | return this.readU8() + this.readU8()*256; 39 | } else { 40 | return null; 41 | } 42 | }; 43 | 44 | DataView.prototype.readU32 = function() { 45 | if (this.byteLength >= this.offset+4) { 46 | return this.readU16() + this.readU16()*65536; 47 | } else { 48 | return null; 49 | } 50 | }; 51 | 52 | DataView.prototype.read8 = function() { 53 | if (this.byteLength >= this.offset+1) { 54 | return this.getInt8(this.offset++, 1); 55 | } else { 56 | return null; 57 | } 58 | }; 59 | 60 | DataView.prototype.read16 = function() { 61 | this.offset += 2; 62 | if (this.byteLength >= this.offset) { 63 | return this.getInt16(this.offset-2, 1); 64 | } else { 65 | return null; 66 | } 67 | }; 68 | 69 | DataView.prototype.read32 = function() { 70 | this.offset += 4; 71 | if (this.byteLength >= this.offset) { 72 | return this.getInt32(this.offset-4, 1); 73 | } else { 74 | return null; 75 | } 76 | }; 77 | 78 | DataView.prototype.remaining = function() { 79 | return this.byteLength - this.offset; 80 | }; 81 | -------------------------------------------------------------------------------- /src/js/port_usage.svelte.js: -------------------------------------------------------------------------------- 1 | import { serial } from "@/js/serial.js"; 2 | 3 | // TODO: Merge into serial driver 4 | class PortUsage { 5 | down = $state(0); 6 | up = $state(0); 7 | 8 | #prevReceived = 0; 9 | #prevSent = 0; 10 | 11 | constructor() { 12 | this.timer = globalThis.setInterval(() => { 13 | this.update(); 14 | }, 1000); 15 | } 16 | 17 | update() { 18 | if (serial.bitrate) { 19 | this.down = 20 | (100 * (serial.bytesReceived - this.#prevReceived)) / 21 | (serial.bitrate / 8); 22 | 23 | this.up = 24 | (100 * (serial.bytesSent - this.#prevSent)) / (serial.bitrate / 8); 25 | 26 | this.#prevReceived = serial.bytesReceived; 27 | this.#prevSent = serial.bytesSent; 28 | } else { 29 | this.down = 0; 30 | this.up = 0; 31 | } 32 | } 33 | 34 | reset() { 35 | this.#prevReceived = 0; 36 | this.#prevSent = 0; 37 | this.down = 0; 38 | this.up = 0; 39 | } 40 | } 41 | 42 | export const portUsage = new PortUsage(); 43 | -------------------------------------------------------------------------------- /src/js/presets/source/github.js: -------------------------------------------------------------------------------- 1 | export default class GithubUtil { 2 | static containsBranchName(url) { 3 | return url.includes("/tree/"); 4 | } 5 | 6 | static isUrlGithubRepo(url) { 7 | return url.trim().toLowerCase().startsWith("https://github.com/"); 8 | } 9 | 10 | static getBranchName(url) { 11 | const pattern = /https:\/\/github\.com\/[^/]+\/[^/]+\/tree\/([^/]+)/; 12 | const match = url.match(pattern); 13 | 14 | return match ? match[1] : null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/js/presets/source/preset_instance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @typedef {import('@/js/presets/source/source.js').Metadata} Metadata 3 | * @typedef {import("@/js/presets/source/retriever.js").PresetData} PresetData 4 | */ 5 | export default class PresetInstance { 6 | /** 7 | * @type {string} 8 | */ 9 | get fullPath() { 10 | return this.presetData.fullPath; 11 | } 12 | /** 13 | * @type {Metadata} 14 | */ 15 | sourceMetadata = null; 16 | /** 17 | * @type {PresetData} 18 | */ 19 | presetData = null; 20 | /** 21 | * @type {string[]} 22 | */ 23 | cliStringsArr = []; 24 | /** 25 | * @type {string[]} 26 | */ 27 | renderedCliArr = []; 28 | 29 | /** 30 | * @type {any[]} 31 | */ 32 | optionsValues = null; 33 | 34 | completeWarning = ""; 35 | 36 | /** 37 | * 38 | * @param {string} presetFullPath 39 | * @param {SourceMetadata} sourceMetadata 40 | */ 41 | constructor(sourceMetadata, presetData) { 42 | this.sourceMetadata = sourceMetadata; 43 | this.presetData = presetData; 44 | } 45 | 46 | /** 47 | * @returns {string} 48 | */ 49 | get viewLink() { 50 | return this.sourceMetadata.viewUrl + this.presetData.fullPath; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/js/tabs/gyro.js: -------------------------------------------------------------------------------- 1 | import { mount, unmount } from "svelte"; 2 | 3 | import Gyro from "@/tabs/gyro/Gyro.svelte"; 4 | 5 | const tab = { 6 | tabName: "gyro", 7 | svelteComponent: null, 8 | 9 | get isDirty() { 10 | return this.svelteComponent?.isDirty(); 11 | }, 12 | 13 | initialize(callback) { 14 | const target = document.querySelector("#content"); 15 | target.innerHTML = ""; 16 | this.svelteComponent = mount(Gyro, { target }); 17 | 18 | GUI.content_ready(callback); 19 | }, 20 | 21 | cleanup(callback) { 22 | if (this.svelteComponent) { 23 | unmount(this.svelteComponent); 24 | this.svelteComponent = null; 25 | } 26 | 27 | callback?.(); 28 | }, 29 | 30 | save(callback) { 31 | if (this.svelteComponent) { 32 | this.svelteComponent.onSave().finally(callback); 33 | } else { 34 | callback?.(); 35 | } 36 | }, 37 | 38 | revert(callback) { 39 | this.svelteComponent?.onRevert(); 40 | callback?.(); 41 | }, 42 | }; 43 | 44 | TABS[tab.tabName] = tab; 45 | 46 | if (import.meta.hot) { 47 | import.meta.hot.accept((newModule) => { 48 | if (newModule && GUI.active_tab === tab.tabName) { 49 | TABS[tab.tabName].initialize(); 50 | } 51 | }); 52 | 53 | import.meta.hot.dispose(() => { 54 | tab.cleanup(); 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /src/js/tabs/help.js: -------------------------------------------------------------------------------- 1 | const tab = { 2 | tabName: 'help', 3 | }; 4 | tab.initialize = function (callback) { 5 | $('#content').load("/src/tabs/help.html", function () { 6 | i18n.localizePage(); 7 | GUI.content_ready(callback); 8 | }); 9 | }; 10 | 11 | tab.cleanup = function (callback) { 12 | callback?.(); 13 | }; 14 | 15 | TABS[tab.tabName] = tab; 16 | 17 | if (import.meta.hot) { 18 | import.meta.hot.accept((newModule) => { 19 | if (newModule && GUI.active_tab === tab.tabName) { 20 | TABS[tab.tabName].initialize(); 21 | } 22 | }); 23 | 24 | import.meta.hot.dispose(() => { 25 | tab.cleanup(); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /src/js/tabs/index.js: -------------------------------------------------------------------------------- 1 | import "./adjustments.js"; 2 | import "./auxiliary.js"; 3 | import "./beepers.js"; 4 | import "./blackbox.js"; 5 | import "./cli.js"; 6 | import "./configuration.js"; 7 | import "./failsafe.js"; 8 | import "./firmware_flasher.js"; 9 | import "./gps.js"; 10 | import "./gyro.js"; 11 | import "./help.js"; 12 | import "./landing.js"; 13 | import "./led_strip.js"; 14 | import "./mixer.js"; 15 | import "./motors.js"; 16 | import "./options.js"; 17 | import "./presets.js"; 18 | import "./power.js"; 19 | import "./privacy_policy.js"; 20 | import "./profiles.js"; 21 | import "./rates.js"; 22 | import "./receiver.js"; 23 | import "./sensors.js"; 24 | import "./servos.js"; 25 | import "./setup.js"; 26 | import "./status.js"; 27 | -------------------------------------------------------------------------------- /src/js/tabs/privacy_policy.js: -------------------------------------------------------------------------------- 1 | const tab = { 2 | tabName: 'privacy_policy', 3 | }; 4 | 5 | tab.initialize = function (callback) { 6 | const tabFile = `/src/tabs/privacy_policy.html`; 7 | 8 | $('#content').html('
'); 9 | 10 | $('#tab-static-contents').load(tabFile, function () { 11 | i18n.localizePage(); 12 | GUI.content_ready(callback); 13 | }); 14 | 15 | }; 16 | 17 | tab.cleanup = function (callback) { 18 | callback?.(); 19 | }; 20 | 21 | TABS[tab.tabName] = tab; 22 | 23 | if (import.meta.hot) { 24 | import.meta.hot.accept((newModule) => { 25 | if (newModule && GUI.active_tab === tab.tabName) { 26 | TABS[tab.tabName].initialize(); 27 | } 28 | }); 29 | 30 | import.meta.hot.dispose(() => { 31 | tab.cleanup(); 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /src/js/utils/CommonUtils.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rotorflight/rotorflight-configurator/d6f7c9e40ef414bff112d6a9326ab6c3072aef5a/src/js/utils/CommonUtils.js -------------------------------------------------------------------------------- /src/js/utils/window_watchers.js: -------------------------------------------------------------------------------- 1 | /* 2 | This utility is intended to communicate between chrome windows. 3 | One window could watch passed values from another window and react to them. 4 | */ 5 | 6 | export const windowWatcherUtil = {}; 7 | 8 | windowWatcherUtil.invokeWatcher = function(bindingKey, bindingVal, watchersObject) { 9 | if (watchersObject[bindingKey]) { 10 | watchersObject[bindingKey](bindingVal); 11 | } 12 | }; 13 | 14 | windowWatcherUtil.iterateOverBindings = function(bindings, watchersObject) { 15 | let entries = Object.entries(bindings); 16 | for (const [key, val] of entries) { 17 | this.invokeWatcher(key, val, watchersObject); 18 | } 19 | }; 20 | 21 | windowWatcherUtil.bindWatchers = function(windowObject, watchersObject) { 22 | if (!windowObject.bindings) { 23 | windowObject.bindings = {}; 24 | } else { 25 | this.iterateOverBindings(windowObject.bindings, watchersObject); 26 | } 27 | 28 | windowObject.bindings = new Proxy(windowObject.bindings, { 29 | set(target, prop, val, receiver) { 30 | windowWatcherUtil.invokeWatcher(prop, val, watchersObject); 31 | return Reflect.set(target, prop, val, receiver); 32 | } 33 | }); 34 | }; 35 | 36 | // 'Windows' here could be array or single window reference 37 | windowWatcherUtil.passValue = function(windows, key, val) { 38 | let applyBinding = function(win, key, val) { 39 | if (!win) { 40 | return; 41 | } 42 | 43 | if (win.bindings) { 44 | win.bindings[key] = val; 45 | } else { 46 | win.bindings = { 47 | [key]: val 48 | }; 49 | } 50 | }; 51 | 52 | if (Array.isArray(windows)) { 53 | windows.forEach((el) => applyBinding(el, key, val)); 54 | } else { 55 | applyBinding(windows, key, val); 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /src/main_cordova.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Rotorflight configurator 7 | 8 | 9 | 10 | 11 |
12 | 13 |
14 |
15 | 16 |

17 |
18 |
19 |
20 |
21 | 22 |
23 |
24 |

25 |

26 |
27 |

28 | 29 | 30 |
31 |
32 |
33 |
34 | 35 |
36 |
37 |
    38 |
    39 |
    40 |
    41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/tabs/blank.html: -------------------------------------------------------------------------------- 1 |
    2 | -------------------------------------------------------------------------------- /src/tabs/cli.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |

    5 |
    6 | 7 |
    8 |
    9 |
    10 |
    11 |
    12 | 13 |
    14 | 15 |
    16 |
    17 | 18 |
    19 |
    20 | 21 |
    22 |
    23 | 24 |
    25 |
    26 | 27 |
    28 |
    29 | 30 |
    31 | 32 |
    33 | 34 | 35 | 44 | 45 | 46 |

    47 |
    48 |
    49 |
    50 |
    51 | 52 |
    53 |
    54 | 55 |
    56 | -------------------------------------------------------------------------------- /src/tabs/help.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 |
    6 |
    7 |
    8 |
    9 |

    10 |
      11 |
    • 12 |
    • 13 |
    • 14 |
    15 |
    16 |
    17 |
    18 |
    19 |
    20 |
    21 |
    22 |
    23 |
    24 |

    25 |
    26 |
      27 |
    • 28 |
    • 29 |
    • 30 |
    31 | 32 |
    33 |
      34 |
    • 35 |
    • 36 |
    37 | 38 |
    39 |
    40 |
    41 |
    42 |
    43 | -------------------------------------------------------------------------------- /src/tabs/map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Asynchronous Loading 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
    22 | 23 | 24 | -------------------------------------------------------------------------------- /src/tabs/presets/preset_panel.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 4 | 5 |
    6 |
    7 | 8 | 9 | 10 | 13 | 16 | 17 | 18 | 21 | 24 | 25 | 26 | 29 | 32 | 33 | 34 | 37 | 40 | 41 | 42 | 45 | 48 | 49 | 50 | 53 | 57 | 58 | 59 | 60 |
    61 |
    62 | -------------------------------------------------------------------------------- /src/tabs/presets/selected_preset_panel.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |
    13 |
    14 |
    15 | {presetInstance.presetData.title} 16 | 21 | 26 |
    27 |
    28 | {$i18n.t("presetAuthor")} 29 | {presetInstance.presetData.author} 30 |
    31 |
    32 | {$i18n.t("presetCategory")} 33 | {presetInstance.presetData.category} 34 |
    35 |
    36 | {$i18n.t("presetSelectedOptions")}
    {presetInstance.optionsValues} 38 |
    39 |
    40 |
    41 | 42 | 77 | -------------------------------------------------------------------------------- /src/tabs/presets/sources_dialog.html: -------------------------------------------------------------------------------- 1 |
    2 |
    6 |
    7 |
    8 |
    9 |
    10 | 11 |
    12 |
    13 | 20 | 27 |
    28 |
    29 |
    30 | -------------------------------------------------------------------------------- /src/tabs/receiver/TelemetrySensors/SensorsBitfield.svelte: -------------------------------------------------------------------------------- 1 | 41 | 42 | {#each sensors as sensor} 43 | {#if bit_check(mask, sensor.id)} 44 | 48 | bit_check(value, sensor.id), 52 | (v) => { 53 | value = (v ? bit_set : bit_clear)(value, sensor.id); 54 | } 55 | } 56 | /> 57 | 58 | {/if} 59 | {/each} 60 | 61 | 63 | -------------------------------------------------------------------------------- /src/tabs/receiver/TelemetrySensors/SensorsOrderedList/Details.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
    10 | 11 |
    (open = !open)}> 12 | {@render summary()} 13 |
    14 | {#if open} 15 |
    16 | {@render children?.()} 17 |
    18 | {/if} 19 |
    20 | 21 | 57 | -------------------------------------------------------------------------------- /src/tabs/receiver/TelemetrySensors/SensorsOrderedList/SensorsOrderedList.svelte: -------------------------------------------------------------------------------- 1 | 29 | 30 |
    31 | {#if totalCount > MAX_SENSORS} 32 | 33 | {$i18n.t("receiverTelemetrySensorsExceededWarning")} 34 |
    35 | {totalCount} / {MAX_SENSORS} 36 |
    37 | {/if} 38 | 39 | {#if view === 0} 40 | 41 | {:else if view === 1} 42 | 44 | 45 | """ 46 | 47 | old_file = args[1] 48 | new_file = args[2] 49 | 50 | select = args[3] 51 | insert = args[4] 52 | 53 | print(f'Old locale: {old_file}') 54 | print(f'New locale: {new_file}') 55 | 56 | locale = pick_locale(old_file, new_file, select, insert) 57 | 58 | save_locale(new_file, locale) 59 | 60 | 61 | main(sys.argv) 62 | -------------------------------------------------------------------------------- /tools/locale-delete-status: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import re 4 | import os 5 | import sys 6 | import json 7 | 8 | 9 | def load_locale(file): 10 | with open(file) as data: 11 | locale = json.load(data) 12 | return locale 13 | 14 | def save_locale(file, data): 15 | with open(file, 'w', encoding='utf8') as out: 16 | json.dump(data, out, indent=4, ensure_ascii=False) 17 | 18 | 19 | def remove_status(loc): 20 | 21 | for key in list(loc): 22 | 23 | ## Remove status 24 | if 'status' in loc[key]: 25 | del loc[key]['status'] 26 | 27 | ## Remove previous 28 | if 'previous' in loc[key]: 29 | del loc[key]['previous'] 30 | 31 | return loc 32 | 33 | 34 | def main(args): 35 | """ 36 | Delete status entries in locale file. 37 | 38 | Args: 39 | 40 | """ 41 | 42 | i18n_files = args[1:] 43 | 44 | for file in i18n_files: 45 | print(f'Processing locale: {file}') 46 | locale = load_locale(file) 47 | locale = remove_status(locale) 48 | save_locale(file, locale) 49 | 50 | 51 | main(sys.argv) 52 | -------------------------------------------------------------------------------- /tools/locale-update-all: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | EN='locales/en/messages.json' 4 | 5 | ARGS=$EN 6 | 7 | for L in locales/*/messages.json 8 | do 9 | if [ "$L" != "$EN" ] 10 | then 11 | ARGS="${ARGS} $L" 12 | fi 13 | done 14 | 15 | ./tools/locale-update ${ARGS} 16 | 17 | --------------------------------------------------------------------------------