From b79220c1aeae8c6048b45503265e8f5fbb8b7276 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 4 Jan 2026 11:42:27 -0600 Subject: [PATCH] initial commit --- .gitignore | 131 + LICENSE | 339 + README.md | 25 + plugins/README.txt | 31 + plugins/autopairs/__init__.py | 3 + plugins/autopairs/__main__.py | 3 + plugins/autopairs/manifest.json | 10 + plugins/autopairs/plugin.py | 140 + plugins/colorize/__init__.py | 3 + plugins/colorize/__main__.py | 3 + plugins/colorize/color_converter_mixin.py | 107 + plugins/colorize/manifest.json | 9 + plugins/colorize/plugin.py | 228 + plugins/commentzar/__init__.py | 3 + plugins/commentzar/__main__.py | 3 + plugins/commentzar/add_comment_mixin.py | 66 + plugins/commentzar/codecomment_tags.py | 30 + plugins/commentzar/manifest.json | 11 + plugins/commentzar/plugin.py | 118 + plugins/commentzar/remove_comment_mixin.py | 49 + plugins/lsp_client/__init__.py | 3 + plugins/lsp_client/__main__.py | 3 + plugins/lsp_client/client_ipc.py | 182 + plugins/lsp_client/config.json | 7 + plugins/lsp_client/lsp_message_structs.py | 54 + plugins/lsp_client/manifest.json | 16 + plugins/lsp_client/plugin.py | 270 + plugins/markdown_preview/__init__.py | 3 + plugins/markdown_preview/__main__.py | 3 + plugins/markdown_preview/manifest.json | 11 + plugins/markdown_preview/markdown/__init__.py | 48 + plugins/markdown_preview/markdown/__main__.py | 151 + plugins/markdown_preview/markdown/__meta__.py | 51 + .../markdown_preview/markdown/blockparser.py | 160 + .../markdown/blockprocessors.py | 636 ++ plugins/markdown_preview/markdown/core.py | 510 ++ .../markdown/extensions/__init__.py | 145 + .../markdown/extensions/abbr.py | 105 + .../markdown/extensions/admonition.py | 179 + .../markdown/extensions/attr_list.py | 179 + .../markdown/extensions/codehilite.py | 338 + .../markdown/extensions/def_list.py | 119 + .../markdown/extensions/extra.py | 66 + .../markdown/extensions/fenced_code.py | 182 + .../markdown/extensions/footnotes.py | 416 + .../markdown/extensions/legacy_attrs.py | 67 + .../markdown/extensions/legacy_em.py | 52 + .../markdown/extensions/md_in_html.py | 372 + .../markdown/extensions/meta.py | 85 + .../markdown/extensions/nl2br.py | 41 + .../markdown/extensions/sane_lists.py | 65 + .../markdown/extensions/smarty.py | 265 + .../markdown/extensions/tables.py | 243 + .../markdown/extensions/toc.py | 408 + .../markdown/extensions/wikilinks.py | 96 + .../markdown_preview/markdown/htmlparser.py | 334 + .../markdown/inlinepatterns.py | 992 +++ .../markdown/postprocessors.py | 143 + .../markdown/preprocessors.py | 91 + .../markdown_preview/markdown/serializers.py | 193 + .../markdown_preview/markdown/test_tools.py | 224 + .../markdown/treeprocessors.py | 476 ++ plugins/markdown_preview/markdown/util.py | 399 + .../markdown_preview/markdown_preview.glade | 121 + .../markdown_template_mixin.py | 42 + plugins/markdown_preview/plugin.py | 114 + plugins/search_replace/__init__.py | 3 + plugins/search_replace/__main__.py | 3 + plugins/search_replace/manifest.json | 12 + plugins/search_replace/plugin.py | 221 + plugins/search_replace/replace_mixin.py | 94 + plugins/search_replace/search_replace.glade | 299 + plugins/search_replace/styling_mixin.py | 66 + plugins/template/__init__.py | 3 + plugins/template/__main__.py | 3 + plugins/template/manifest.json | 11 + plugins/template/plugin.py | 51 + pyrightconfig.json | 13 + requirements.txt | 7 + src/__builtins__.py | 79 + src/__init__.py | 3 + src/__main__.py | 58 + src/app.py | 72 + src/core/__init__.py | 3 + src/core/builder_wrapper.py | 33 + src/core/containers/base_container.py | 49 + src/core/containers/body_container.py | 42 + src/core/containers/center_container.py | 48 + src/core/containers/code/__init__.py | 3 + src/core/containers/code/code_container.py | 38 + src/core/containers/code/editors_container.py | 38 + .../code/paned_editors_container.py | 69 + src/core/containers/footer_container.py | 43 + src/core/containers/header_container.py | 40 + src/core/containers/left_container.py | 39 + src/core/containers/right_container.py | 38 + src/core/controllers/__init__.py | 3 + src/core/controllers/base_controller.py | 71 + src/core/controllers/base_controller_data.py | 107 + src/core/controllers/bridge_controller.py | 41 + src/core/widgets/__init__.py | 3 + src/core/widgets/code/__init__.py | 3 + src/core/widgets/code/command_system.py | 34 + src/core/widgets/code/commands/__init__.py | 16 + src/core/widgets/code/commands/buffer_redo.py | 23 + src/core/widgets/code/commands/buffer_undo.py | 23 + src/core/widgets/code/commands/close_file.py | 26 + .../code/commands/cut_to_temp_buffer.py | 36 + .../code/commands/dnd_load_file_to_buffer.py | 35 + .../widgets/code/commands/dnd_load_files.py | 27 + .../widgets/code/commands/duplicate_line.py | 53 + .../code/commands/focus_left_sibling.py | 19 + .../code/commands/focus_right_sibling.py | 19 + .../widgets/code/commands/get_current_file.py | 20 + .../widgets/code/commands/get_filetype.py | 21 + src/core/widgets/code/commands/get_text.py | 21 + src/core/widgets/code/commands/go_to.py | 31 + src/core/widgets/code/commands/has_focus.py | 19 + src/core/widgets/code/commands/line_down.py | 18 + src/core/widgets/code/commands/line_up.py | 18 + src/core/widgets/code/commands/load_file.py | 32 + .../widgets/code/commands/load_start_files.py | 42 + .../code/commands/move_to_left_sibling.py | 32 + .../code/commands/move_to_right_sibling.py | 32 + src/core/widgets/code/commands/new_file.py | 33 + src/core/widgets/code/commands/open_files.py | 33 + .../code/commands/paste_temp_buffer.py | 28 + src/core/widgets/code/commands/save_file.py | 30 + .../widgets/code/commands/save_file_as.py | 28 + src/core/widgets/code/commands/set_buffer.py | 36 + .../code/commands/set_buffer_language.py | 23 + .../widgets/code/commands/set_buffer_style.py | 23 + .../widgets/code/commands/set_focus_border.py | 26 + .../widgets/code/commands/set_miniview.py | 27 + .../widgets/code/commands/show_completion.py | 18 + .../widgets/code/commands/update_info_bar.py | 33 + src/core/widgets/code/commands/zoom_in.py | 23 + src/core/widgets/code/commands/zoom_out.py | 23 + src/core/widgets/code/completion_manager.py | 66 + .../code/completion_providers/__init__.py | 3 + .../example_completion_provider.py | 84 + .../lsp_completion_provider.py | 137 + .../python_completion_provider.py | 107 + src/core/widgets/code/general_info_widget.py | 103 + src/core/widgets/code/key_mapper.py | 127 + src/core/widgets/code/miniview_widget.py | 38 + src/core/widgets/code/mixins/__init__.py | 3 + .../code/mixins/source_view_dnd_mixin.py | 40 + .../code/mixins/source_view_events_mixin.py | 63 + src/core/widgets/code/source_buffer.py | 40 + src/core/widgets/code/source_file.py | 137 + src/core/widgets/code/source_files_manager.py | 106 + src/core/widgets/code/tab_widget.py | 61 + src/core/widgets/code/tabs_widget.py | 107 + src/core/widgets/code/view.py | 130 + src/core/widgets/controls/__init__.py | 3 + .../widgets/controls/open_files_button.py | 83 + src/core/widgets/controls/save_as_button.py | 72 + .../widgets/controls/transparency_scale.py | 48 + src/core/widgets/save_file_dialog.py | 66 + src/core/widgets/separator_widget.py | 37 + src/core/widgets/vte_widget.py | 128 + src/core/widgets/webkit/__init__.py | 3 + src/core/widgets/webkit/webkit_ui.py | 69 + src/core/window.py | 200 + src/libs/__init__.py | 3 + src/libs/db/__init__.py | 6 + src/libs/db/db.py | 42 + src/libs/db/models.py | 15 + src/libs/debugging.py | 60 + src/libs/dto/__init__.py | 5 + src/libs/dto/code_event.py | 18 + src/libs/dto/event.py | 14 + src/libs/dto/observable_event.py | 10 + src/libs/endpoint_registry.py | 22 + src/libs/event_system.py | 73 + src/libs/ipc_server.py | 148 + src/libs/keybindings.py | 138 + src/libs/logger.py | 61 + src/libs/mixins/__init__.py | 3 + src/libs/mixins/dnd_mixin.py | 70 + src/libs/mixins/ipc_signals_mixin.py | 31 + src/libs/mixins/keyboard_signals_mixin.py | 96 + src/libs/mixins/observable_mixin.py | 26 + src/libs/settings/__init__.py | 4 + src/libs/settings/manager.py | 126 + src/libs/settings/options/__init__.py | 8 + src/libs/settings/options/config.py | 39 + src/libs/settings/options/debugging.py | 12 + src/libs/settings/options/filters.py | 90 + src/libs/settings/options/settings.py | 31 + src/libs/settings/options/theming.py | 16 + src/libs/settings/other/__init__.py | 3 + src/libs/settings/other/webkit_ui_settings.py | 42 + src/libs/settings/path_manager.py | 123 + src/libs/settings/start_check_mixin.py | 65 + src/libs/singleton.py | 29 + src/libs/singleton_raised.py | 26 + src/libs/status_icon.py | 67 + src/plugins/__init__.py | 3 + src/plugins/dto/__init__.py | 3 + src/plugins/dto/manifest.py | 27 + src/plugins/dto/manifest_meta.py | 19 + src/plugins/dto/requests.py | 15 + src/plugins/manifest_manager.py | 68 + src/plugins/plugin_base.py | 92 + src/plugins/plugin_reload_mixin.py | 36 + src/plugins/plugins_controller.py | 134 + user_config/bin/ | 39 + user_config/usr/applications/newton.desktop | 11 + .../usr/share/newton/Main_Window.glade | 28 + .../usr/share/newton/code-key-bindings.json | 64 + .../newton/code_styles/catppuccin-frappe.xml | 100 + .../newton/code_styles/catppuccin-latte.xml | 100 + .../code_styles/catppuccin-macchiato.xml | 100 + .../newton/code_styles/catppuccin-mocha.xml | 100 + .../newton/code_styles/peacocks-in-space.xml | 124 + .../newton/code_styles/penguins-in-space.xml | 120 + .../usr/share/newton/contexct_menu.json | 16 + .../usr/share/newton/context_path/index.html | 47 + .../resources/css/context-menu.css | 50 + .../css/libs/bootstrap-icons/123.svg | 3 + .../css/libs/bootstrap-icons/activity.svg | 3 + .../css/libs/bootstrap-icons/alarm-fill.svg | 3 + .../css/libs/bootstrap-icons/alarm.svg | 4 + .../css/libs/bootstrap-icons/align-bottom.svg | 4 + .../css/libs/bootstrap-icons/align-center.svg | 3 + .../css/libs/bootstrap-icons/align-end.svg | 4 + .../css/libs/bootstrap-icons/align-middle.svg | 3 + .../css/libs/bootstrap-icons/align-start.svg | 4 + .../css/libs/bootstrap-icons/align-top.svg | 4 + .../css/libs/bootstrap-icons/alt.svg | 3 + .../libs/bootstrap-icons/app-indicator.svg | 4 + .../css/libs/bootstrap-icons/app.svg | 3 + .../css/libs/bootstrap-icons/apple.svg | 4 + .../css/libs/bootstrap-icons/archive-fill.svg | 3 + .../css/libs/bootstrap-icons/archive.svg | 3 + .../libs/bootstrap-icons/arrow-90deg-down.svg | 3 + .../libs/bootstrap-icons/arrow-90deg-left.svg | 3 + .../bootstrap-icons/arrow-90deg-right.svg | 3 + .../libs/bootstrap-icons/arrow-90deg-up.svg | 3 + .../libs/bootstrap-icons/arrow-bar-down.svg | 3 + .../libs/bootstrap-icons/arrow-bar-left.svg | 3 + .../libs/bootstrap-icons/arrow-bar-right.svg | 3 + .../css/libs/bootstrap-icons/arrow-bar-up.svg | 3 + .../libs/bootstrap-icons/arrow-clockwise.svg | 4 + .../arrow-counterclockwise.svg | 4 + .../arrow-down-circle-fill.svg | 3 + .../bootstrap-icons/arrow-down-circle.svg | 3 + .../arrow-down-left-circle-fill.svg | 3 + .../arrow-down-left-circle.svg | 3 + .../arrow-down-left-square-fill.svg | 3 + .../arrow-down-left-square.svg | 3 + .../libs/bootstrap-icons/arrow-down-left.svg | 3 + .../arrow-down-right-circle-fill.svg | 3 + .../arrow-down-right-circle.svg | 3 + .../arrow-down-right-square-fill.svg | 3 + .../arrow-down-right-square.svg | 3 + .../libs/bootstrap-icons/arrow-down-right.svg | 3 + .../libs/bootstrap-icons/arrow-down-short.svg | 3 + .../arrow-down-square-fill.svg | 3 + .../bootstrap-icons/arrow-down-square.svg | 3 + .../libs/bootstrap-icons/arrow-down-up.svg | 3 + .../css/libs/bootstrap-icons/arrow-down.svg | 3 + .../arrow-left-circle-fill.svg | 3 + .../bootstrap-icons/arrow-left-circle.svg | 3 + .../libs/bootstrap-icons/arrow-left-right.svg | 3 + .../libs/bootstrap-icons/arrow-left-short.svg | 3 + .../arrow-left-square-fill.svg | 3 + .../bootstrap-icons/arrow-left-square.svg | 3 + .../css/libs/bootstrap-icons/arrow-left.svg | 3 + .../css/libs/bootstrap-icons/arrow-repeat.svg | 4 + .../bootstrap-icons/arrow-return-left.svg | 3 + .../bootstrap-icons/arrow-return-right.svg | 3 + .../arrow-right-circle-fill.svg | 3 + .../bootstrap-icons/arrow-right-circle.svg | 3 + .../bootstrap-icons/arrow-right-short.svg | 3 + .../arrow-right-square-fill.svg | 3 + .../bootstrap-icons/arrow-right-square.svg | 3 + .../css/libs/bootstrap-icons/arrow-right.svg | 3 + .../arrow-through-heart-fill.svg | 3 + .../bootstrap-icons/arrow-through-heart.svg | 3 + .../bootstrap-icons/arrow-up-circle-fill.svg | 3 + .../libs/bootstrap-icons/arrow-up-circle.svg | 3 + .../arrow-up-left-circle-fill.svg | 3 + .../bootstrap-icons/arrow-up-left-circle.svg | 3 + .../arrow-up-left-square-fill.svg | 3 + .../bootstrap-icons/arrow-up-left-square.svg | 3 + .../libs/bootstrap-icons/arrow-up-left.svg | 3 + .../arrow-up-right-circle-fill.svg | 3 + .../bootstrap-icons/arrow-up-right-circle.svg | 3 + .../arrow-up-right-square-fill.svg | 3 + .../bootstrap-icons/arrow-up-right-square.svg | 3 + .../libs/bootstrap-icons/arrow-up-right.svg | 3 + .../libs/bootstrap-icons/arrow-up-short.svg | 3 + .../bootstrap-icons/arrow-up-square-fill.svg | 3 + .../libs/bootstrap-icons/arrow-up-square.svg | 3 + .../css/libs/bootstrap-icons/arrow-up.svg | 3 + .../bootstrap-icons/arrows-angle-contract.svg | 3 + .../bootstrap-icons/arrows-angle-expand.svg | 3 + .../libs/bootstrap-icons/arrows-collapse.svg | 3 + .../libs/bootstrap-icons/arrows-expand.svg | 3 + .../bootstrap-icons/arrows-fullscreen.svg | 3 + .../css/libs/bootstrap-icons/arrows-move.svg | 3 + .../bootstrap-icons/aspect-ratio-fill.svg | 3 + .../css/libs/bootstrap-icons/aspect-ratio.svg | 4 + .../css/libs/bootstrap-icons/asterisk.svg | 3 + .../resources/css/libs/bootstrap-icons/at.svg | 3 + .../css/libs/bootstrap-icons/award-fill.svg | 4 + .../css/libs/bootstrap-icons/award.svg | 4 + .../css/libs/bootstrap-icons/back.svg | 3 + .../libs/bootstrap-icons/backspace-fill.svg | 3 + .../backspace-reverse-fill.svg | 3 + .../bootstrap-icons/backspace-reverse.svg | 4 + .../css/libs/bootstrap-icons/backspace.svg | 4 + .../libs/bootstrap-icons/badge-3d-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-3d.svg | 4 + .../libs/bootstrap-icons/badge-4k-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-4k.svg | 4 + .../libs/bootstrap-icons/badge-8k-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-8k.svg | 4 + .../libs/bootstrap-icons/badge-ad-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-ad.svg | 4 + .../libs/bootstrap-icons/badge-ar-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-ar.svg | 4 + .../libs/bootstrap-icons/badge-cc-fill.svg | 3 + .../css/libs/bootstrap-icons/badge-cc.svg | 4 + .../libs/bootstrap-icons/badge-hd-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-hd.svg | 4 + .../libs/bootstrap-icons/badge-sd-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-sd.svg | 3 + .../libs/bootstrap-icons/badge-tm-fill.svg | 3 + .../css/libs/bootstrap-icons/badge-tm.svg | 4 + .../libs/bootstrap-icons/badge-vo-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-vo.svg | 4 + .../libs/bootstrap-icons/badge-vr-fill.svg | 4 + .../css/libs/bootstrap-icons/badge-vr.svg | 4 + .../libs/bootstrap-icons/badge-wc-fill.svg | 3 + .../css/libs/bootstrap-icons/badge-wc.svg | 4 + .../libs/bootstrap-icons/bag-check-fill.svg | 3 + .../css/libs/bootstrap-icons/bag-check.svg | 4 + .../libs/bootstrap-icons/bag-dash-fill.svg | 3 + .../css/libs/bootstrap-icons/bag-dash.svg | 4 + .../css/libs/bootstrap-icons/bag-fill.svg | 3 + .../libs/bootstrap-icons/bag-heart-fill.svg | 3 + .../css/libs/bootstrap-icons/bag-heart.svg | 3 + .../libs/bootstrap-icons/bag-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/bag-plus.svg | 4 + .../css/libs/bootstrap-icons/bag-x-fill.svg | 3 + .../css/libs/bootstrap-icons/bag-x.svg | 4 + .../css/libs/bootstrap-icons/bag.svg | 3 + .../css/libs/bootstrap-icons/balloon-fill.svg | 3 + .../bootstrap-icons/balloon-heart-fill.svg | 3 + .../libs/bootstrap-icons/balloon-heart.svg | 3 + .../css/libs/bootstrap-icons/balloon.svg | 3 + .../css/libs/bootstrap-icons/bandaid-fill.svg | 3 + .../css/libs/bootstrap-icons/bandaid.svg | 4 + .../css/libs/bootstrap-icons/bank.svg | 3 + .../css/libs/bootstrap-icons/bank2.svg | 3 + .../libs/bootstrap-icons/bar-chart-fill.svg | 3 + .../bootstrap-icons/bar-chart-line-fill.svg | 3 + .../libs/bootstrap-icons/bar-chart-line.svg | 3 + .../libs/bootstrap-icons/bar-chart-steps.svg | 3 + .../css/libs/bootstrap-icons/bar-chart.svg | 3 + .../css/libs/bootstrap-icons/basket-fill.svg | 3 + .../css/libs/bootstrap-icons/basket.svg | 3 + .../css/libs/bootstrap-icons/basket2-fill.svg | 3 + .../css/libs/bootstrap-icons/basket2.svg | 4 + .../css/libs/bootstrap-icons/basket3-fill.svg | 3 + .../css/libs/bootstrap-icons/basket3.svg | 3 + .../libs/bootstrap-icons/battery-charging.svg | 6 + .../css/libs/bootstrap-icons/battery-full.svg | 4 + .../css/libs/bootstrap-icons/battery-half.svg | 4 + .../css/libs/bootstrap-icons/battery.svg | 3 + .../css/libs/bootstrap-icons/behance.svg | 3 + .../css/libs/bootstrap-icons/bell-fill.svg | 3 + .../libs/bootstrap-icons/bell-slash-fill.svg | 3 + .../css/libs/bootstrap-icons/bell-slash.svg | 3 + .../css/libs/bootstrap-icons/bell.svg | 3 + .../css/libs/bootstrap-icons/bezier.svg | 4 + .../css/libs/bootstrap-icons/bezier2.svg | 3 + .../css/libs/bootstrap-icons/bicycle.svg | 3 + .../libs/bootstrap-icons/binoculars-fill.svg | 3 + .../css/libs/bootstrap-icons/binoculars.svg | 3 + .../libs/bootstrap-icons/blockquote-left.svg | 3 + .../libs/bootstrap-icons/blockquote-right.svg | 3 + .../css/libs/bootstrap-icons/bluetooth.svg | 3 + .../css/libs/bootstrap-icons/body-text.svg | 3 + .../css/libs/bootstrap-icons/book-fill.svg | 3 + .../css/libs/bootstrap-icons/book-half.svg | 3 + .../css/libs/bootstrap-icons/book.svg | 3 + .../bootstrap-icons/bookmark-check-fill.svg | 3 + .../libs/bootstrap-icons/bookmark-check.svg | 4 + .../bootstrap-icons/bookmark-dash-fill.svg | 3 + .../libs/bootstrap-icons/bookmark-dash.svg | 4 + .../libs/bootstrap-icons/bookmark-fill.svg | 3 + .../bootstrap-icons/bookmark-heart-fill.svg | 3 + .../libs/bootstrap-icons/bookmark-heart.svg | 4 + .../bootstrap-icons/bookmark-plus-fill.svg | 3 + .../libs/bootstrap-icons/bookmark-plus.svg | 4 + .../bootstrap-icons/bookmark-star-fill.svg | 3 + .../libs/bootstrap-icons/bookmark-star.svg | 4 + .../libs/bootstrap-icons/bookmark-x-fill.svg | 3 + .../css/libs/bootstrap-icons/bookmark-x.svg | 4 + .../css/libs/bootstrap-icons/bookmark.svg | 3 + .../libs/bootstrap-icons/bookmarks-fill.svg | 4 + .../css/libs/bootstrap-icons/bookmarks.svg | 4 + .../css/libs/bootstrap-icons/bookshelf.svg | 3 + .../css/libs/bootstrap-icons/boombox-fill.svg | 4 + .../css/libs/bootstrap-icons/boombox.svg | 6 + .../libs/bootstrap-icons/bootstrap-fill.svg | 4 + .../libs/bootstrap-icons/bootstrap-icons.css | 1705 +++++ .../libs/bootstrap-icons/bootstrap-icons.json | 1685 +++++ .../libs/bootstrap-icons/bootstrap-icons.scss | 3393 +++++++++ .../libs/bootstrap-icons/bootstrap-icons.svg | 1 + .../libs/bootstrap-icons/bootstrap-reboot.svg | 4 + .../css/libs/bootstrap-icons/bootstrap.svg | 4 + .../css/libs/bootstrap-icons/border-all.svg | 3 + .../libs/bootstrap-icons/border-bottom.svg | 3 + .../libs/bootstrap-icons/border-center.svg | 3 + .../css/libs/bootstrap-icons/border-inner.svg | 5 + .../css/libs/bootstrap-icons/border-left.svg | 3 + .../libs/bootstrap-icons/border-middle.svg | 3 + .../css/libs/bootstrap-icons/border-outer.svg | 4 + .../css/libs/bootstrap-icons/border-right.svg | 3 + .../css/libs/bootstrap-icons/border-style.svg | 3 + .../css/libs/bootstrap-icons/border-top.svg | 3 + .../css/libs/bootstrap-icons/border-width.svg | 3 + .../css/libs/bootstrap-icons/border.svg | 3 + .../bootstrap-icons/bounding-box-circles.svg | 3 + .../css/libs/bootstrap-icons/bounding-box.svg | 3 + .../bootstrap-icons/box-arrow-down-left.svg | 4 + .../bootstrap-icons/box-arrow-down-right.svg | 4 + .../libs/bootstrap-icons/box-arrow-down.svg | 4 + .../box-arrow-in-down-left.svg | 4 + .../box-arrow-in-down-right.svg | 4 + .../bootstrap-icons/box-arrow-in-down.svg | 4 + .../bootstrap-icons/box-arrow-in-left.svg | 4 + .../bootstrap-icons/box-arrow-in-right.svg | 4 + .../bootstrap-icons/box-arrow-in-up-left.svg | 4 + .../bootstrap-icons/box-arrow-in-up-right.svg | 4 + .../libs/bootstrap-icons/box-arrow-in-up.svg | 4 + .../libs/bootstrap-icons/box-arrow-left.svg | 4 + .../libs/bootstrap-icons/box-arrow-right.svg | 4 + .../bootstrap-icons/box-arrow-up-left.svg | 4 + .../bootstrap-icons/box-arrow-up-right.svg | 4 + .../css/libs/bootstrap-icons/box-arrow-up.svg | 4 + .../css/libs/bootstrap-icons/box-seam.svg | 3 + .../css/libs/bootstrap-icons/box.svg | 3 + .../css/libs/bootstrap-icons/box2-fill.svg | 3 + .../libs/bootstrap-icons/box2-heart-fill.svg | 3 + .../css/libs/bootstrap-icons/box2-heart.svg | 4 + .../css/libs/bootstrap-icons/box2.svg | 3 + .../css/libs/bootstrap-icons/boxes.svg | 3 + .../libs/bootstrap-icons/braces-asterisk.svg | 3 + .../css/libs/bootstrap-icons/braces.svg | 3 + .../css/libs/bootstrap-icons/bricks.svg | 3 + .../libs/bootstrap-icons/briefcase-fill.svg | 4 + .../css/libs/bootstrap-icons/briefcase.svg | 3 + .../brightness-alt-high-fill.svg | 3 + .../bootstrap-icons/brightness-alt-high.svg | 3 + .../brightness-alt-low-fill.svg | 3 + .../bootstrap-icons/brightness-alt-low.svg | 3 + .../bootstrap-icons/brightness-high-fill.svg | 3 + .../libs/bootstrap-icons/brightness-high.svg | 3 + .../bootstrap-icons/brightness-low-fill.svg | 3 + .../libs/bootstrap-icons/brightness-low.svg | 3 + .../libs/bootstrap-icons/broadcast-pin.svg | 3 + .../css/libs/bootstrap-icons/broadcast.svg | 3 + .../css/libs/bootstrap-icons/brush-fill.svg | 3 + .../css/libs/bootstrap-icons/brush.svg | 3 + .../css/libs/bootstrap-icons/bucket-fill.svg | 3 + .../css/libs/bootstrap-icons/bucket.svg | 3 + .../css/libs/bootstrap-icons/bug-fill.svg | 4 + .../css/libs/bootstrap-icons/bug.svg | 3 + .../css/libs/bootstrap-icons/building.svg | 4 + .../css/libs/bootstrap-icons/bullseye.svg | 6 + .../libs/bootstrap-icons/calculator-fill.svg | 3 + .../css/libs/bootstrap-icons/calculator.svg | 4 + .../bootstrap-icons/calendar-check-fill.svg | 3 + .../libs/bootstrap-icons/calendar-check.svg | 4 + .../bootstrap-icons/calendar-date-fill.svg | 4 + .../libs/bootstrap-icons/calendar-date.svg | 4 + .../bootstrap-icons/calendar-day-fill.svg | 3 + .../css/libs/bootstrap-icons/calendar-day.svg | 4 + .../bootstrap-icons/calendar-event-fill.svg | 3 + .../libs/bootstrap-icons/calendar-event.svg | 4 + .../libs/bootstrap-icons/calendar-fill.svg | 3 + .../bootstrap-icons/calendar-heart-fill.svg | 3 + .../libs/bootstrap-icons/calendar-heart.svg | 3 + .../bootstrap-icons/calendar-minus-fill.svg | 3 + .../libs/bootstrap-icons/calendar-minus.svg | 4 + .../bootstrap-icons/calendar-month-fill.svg | 4 + .../libs/bootstrap-icons/calendar-month.svg | 4 + .../bootstrap-icons/calendar-plus-fill.svg | 3 + .../libs/bootstrap-icons/calendar-plus.svg | 4 + .../bootstrap-icons/calendar-range-fill.svg | 3 + .../libs/bootstrap-icons/calendar-range.svg | 4 + .../bootstrap-icons/calendar-week-fill.svg | 3 + .../libs/bootstrap-icons/calendar-week.svg | 4 + .../libs/bootstrap-icons/calendar-x-fill.svg | 3 + .../css/libs/bootstrap-icons/calendar-x.svg | 4 + .../css/libs/bootstrap-icons/calendar.svg | 3 + .../bootstrap-icons/calendar2-check-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-check.svg | 5 + .../bootstrap-icons/calendar2-date-fill.svg | 4 + .../libs/bootstrap-icons/calendar2-date.svg | 5 + .../bootstrap-icons/calendar2-day-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-day.svg | 5 + .../bootstrap-icons/calendar2-event-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-event.svg | 5 + .../libs/bootstrap-icons/calendar2-fill.svg | 3 + .../bootstrap-icons/calendar2-heart-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-heart.svg | 3 + .../bootstrap-icons/calendar2-minus-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-minus.svg | 5 + .../bootstrap-icons/calendar2-month-fill.svg | 4 + .../libs/bootstrap-icons/calendar2-month.svg | 5 + .../bootstrap-icons/calendar2-plus-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-plus.svg | 4 + .../bootstrap-icons/calendar2-range-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-range.svg | 4 + .../bootstrap-icons/calendar2-week-fill.svg | 3 + .../libs/bootstrap-icons/calendar2-week.svg | 4 + .../libs/bootstrap-icons/calendar2-x-fill.svg | 3 + .../css/libs/bootstrap-icons/calendar2-x.svg | 5 + .../css/libs/bootstrap-icons/calendar2.svg | 4 + .../bootstrap-icons/calendar3-event-fill.svg | 3 + .../libs/bootstrap-icons/calendar3-event.svg | 4 + .../libs/bootstrap-icons/calendar3-fill.svg | 3 + .../bootstrap-icons/calendar3-range-fill.svg | 3 + .../libs/bootstrap-icons/calendar3-range.svg | 4 + .../bootstrap-icons/calendar3-week-fill.svg | 3 + .../libs/bootstrap-icons/calendar3-week.svg | 4 + .../css/libs/bootstrap-icons/calendar3.svg | 4 + .../libs/bootstrap-icons/calendar4-event.svg | 4 + .../libs/bootstrap-icons/calendar4-range.svg | 4 + .../libs/bootstrap-icons/calendar4-week.svg | 4 + .../css/libs/bootstrap-icons/calendar4.svg | 3 + .../css/libs/bootstrap-icons/camera-fill.svg | 4 + .../bootstrap-icons/camera-reels-fill.svg | 5 + .../css/libs/bootstrap-icons/camera-reels.svg | 5 + .../bootstrap-icons/camera-video-fill.svg | 3 + .../bootstrap-icons/camera-video-off-fill.svg | 3 + .../libs/bootstrap-icons/camera-video-off.svg | 3 + .../css/libs/bootstrap-icons/camera-video.svg | 3 + .../css/libs/bootstrap-icons/camera.svg | 4 + .../css/libs/bootstrap-icons/camera2.svg | 4 + .../libs/bootstrap-icons/capslock-fill.svg | 3 + .../css/libs/bootstrap-icons/capslock.svg | 3 + .../libs/bootstrap-icons/card-checklist.svg | 4 + .../css/libs/bootstrap-icons/card-heading.svg | 4 + .../css/libs/bootstrap-icons/card-image.svg | 4 + .../css/libs/bootstrap-icons/card-list.svg | 4 + .../css/libs/bootstrap-icons/card-text.svg | 4 + .../libs/bootstrap-icons/caret-down-fill.svg | 3 + .../caret-down-square-fill.svg | 3 + .../bootstrap-icons/caret-down-square.svg | 4 + .../css/libs/bootstrap-icons/caret-down.svg | 3 + .../libs/bootstrap-icons/caret-left-fill.svg | 3 + .../caret-left-square-fill.svg | 3 + .../bootstrap-icons/caret-left-square.svg | 4 + .../css/libs/bootstrap-icons/caret-left.svg | 3 + .../libs/bootstrap-icons/caret-right-fill.svg | 3 + .../caret-right-square-fill.svg | 3 + .../bootstrap-icons/caret-right-square.svg | 4 + .../css/libs/bootstrap-icons/caret-right.svg | 3 + .../libs/bootstrap-icons/caret-up-fill.svg | 3 + .../bootstrap-icons/caret-up-square-fill.svg | 3 + .../libs/bootstrap-icons/caret-up-square.svg | 4 + .../css/libs/bootstrap-icons/caret-up.svg | 3 + .../libs/bootstrap-icons/cart-check-fill.svg | 3 + .../css/libs/bootstrap-icons/cart-check.svg | 4 + .../libs/bootstrap-icons/cart-dash-fill.svg | 3 + .../css/libs/bootstrap-icons/cart-dash.svg | 4 + .../css/libs/bootstrap-icons/cart-fill.svg | 3 + .../libs/bootstrap-icons/cart-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/cart-plus.svg | 4 + .../css/libs/bootstrap-icons/cart-x-fill.svg | 3 + .../css/libs/bootstrap-icons/cart-x.svg | 4 + .../css/libs/bootstrap-icons/cart.svg | 3 + .../css/libs/bootstrap-icons/cart2.svg | 3 + .../css/libs/bootstrap-icons/cart3.svg | 3 + .../css/libs/bootstrap-icons/cart4.svg | 3 + .../css/libs/bootstrap-icons/cash-coin.svg | 6 + .../css/libs/bootstrap-icons/cash-stack.svg | 4 + .../css/libs/bootstrap-icons/cash.svg | 4 + .../css/libs/bootstrap-icons/cast.svg | 4 + .../libs/bootstrap-icons/chat-dots-fill.svg | 3 + .../css/libs/bootstrap-icons/chat-dots.svg | 4 + .../css/libs/bootstrap-icons/chat-fill.svg | 3 + .../libs/bootstrap-icons/chat-heart-fill.svg | 3 + .../css/libs/bootstrap-icons/chat-heart.svg | 3 + .../bootstrap-icons/chat-left-dots-fill.svg | 3 + .../libs/bootstrap-icons/chat-left-dots.svg | 4 + .../libs/bootstrap-icons/chat-left-fill.svg | 3 + .../bootstrap-icons/chat-left-heart-fill.svg | 3 + .../libs/bootstrap-icons/chat-left-heart.svg | 4 + .../bootstrap-icons/chat-left-quote-fill.svg | 3 + .../libs/bootstrap-icons/chat-left-quote.svg | 4 + .../bootstrap-icons/chat-left-text-fill.svg | 3 + .../libs/bootstrap-icons/chat-left-text.svg | 4 + .../css/libs/bootstrap-icons/chat-left.svg | 3 + .../libs/bootstrap-icons/chat-quote-fill.svg | 3 + .../css/libs/bootstrap-icons/chat-quote.svg | 4 + .../bootstrap-icons/chat-right-dots-fill.svg | 3 + .../libs/bootstrap-icons/chat-right-dots.svg | 4 + .../libs/bootstrap-icons/chat-right-fill.svg | 3 + .../bootstrap-icons/chat-right-heart-fill.svg | 3 + .../libs/bootstrap-icons/chat-right-heart.svg | 4 + .../bootstrap-icons/chat-right-quote-fill.svg | 3 + .../libs/bootstrap-icons/chat-right-quote.svg | 4 + .../bootstrap-icons/chat-right-text-fill.svg | 3 + .../libs/bootstrap-icons/chat-right-text.svg | 4 + .../css/libs/bootstrap-icons/chat-right.svg | 3 + .../bootstrap-icons/chat-square-dots-fill.svg | 3 + .../libs/bootstrap-icons/chat-square-dots.svg | 4 + .../libs/bootstrap-icons/chat-square-fill.svg | 3 + .../chat-square-heart-fill.svg | 3 + .../bootstrap-icons/chat-square-heart.svg | 4 + .../chat-square-quote-fill.svg | 3 + .../bootstrap-icons/chat-square-quote.svg | 4 + .../bootstrap-icons/chat-square-text-fill.svg | 3 + .../libs/bootstrap-icons/chat-square-text.svg | 4 + .../css/libs/bootstrap-icons/chat-square.svg | 3 + .../libs/bootstrap-icons/chat-text-fill.svg | 3 + .../css/libs/bootstrap-icons/chat-text.svg | 4 + .../css/libs/bootstrap-icons/chat.svg | 3 + .../css/libs/bootstrap-icons/check-all.svg | 3 + .../bootstrap-icons/check-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/check-circle.svg | 4 + .../css/libs/bootstrap-icons/check-lg.svg | 3 + .../bootstrap-icons/check-square-fill.svg | 3 + .../css/libs/bootstrap-icons/check-square.svg | 4 + .../css/libs/bootstrap-icons/check.svg | 3 + .../css/libs/bootstrap-icons/check2-all.svg | 4 + .../libs/bootstrap-icons/check2-circle.svg | 4 + .../libs/bootstrap-icons/check2-square.svg | 4 + .../css/libs/bootstrap-icons/check2.svg | 3 + .../bootstrap-icons/chevron-bar-contract.svg | 3 + .../libs/bootstrap-icons/chevron-bar-down.svg | 3 + .../bootstrap-icons/chevron-bar-expand.svg | 3 + .../libs/bootstrap-icons/chevron-bar-left.svg | 3 + .../bootstrap-icons/chevron-bar-right.svg | 3 + .../libs/bootstrap-icons/chevron-bar-up.svg | 3 + .../bootstrap-icons/chevron-compact-down.svg | 3 + .../bootstrap-icons/chevron-compact-left.svg | 3 + .../bootstrap-icons/chevron-compact-right.svg | 3 + .../bootstrap-icons/chevron-compact-up.svg | 3 + .../libs/bootstrap-icons/chevron-contract.svg | 3 + .../bootstrap-icons/chevron-double-down.svg | 4 + .../bootstrap-icons/chevron-double-left.svg | 4 + .../bootstrap-icons/chevron-double-right.svg | 4 + .../bootstrap-icons/chevron-double-up.svg | 4 + .../css/libs/bootstrap-icons/chevron-down.svg | 3 + .../libs/bootstrap-icons/chevron-expand.svg | 3 + .../css/libs/bootstrap-icons/chevron-left.svg | 3 + .../libs/bootstrap-icons/chevron-right.svg | 3 + .../css/libs/bootstrap-icons/chevron-up.svg | 3 + .../css/libs/bootstrap-icons/circle-fill.svg | 3 + .../css/libs/bootstrap-icons/circle-half.svg | 3 + .../libs/bootstrap-icons/circle-square.svg | 4 + .../css/libs/bootstrap-icons/circle.svg | 3 + .../bootstrap-icons/clipboard-check-fill.svg | 4 + .../libs/bootstrap-icons/clipboard-check.svg | 5 + .../bootstrap-icons/clipboard-data-fill.svg | 4 + .../libs/bootstrap-icons/clipboard-data.svg | 5 + .../libs/bootstrap-icons/clipboard-fill.svg | 3 + .../bootstrap-icons/clipboard-heart-fill.svg | 4 + .../libs/bootstrap-icons/clipboard-heart.svg | 5 + .../bootstrap-icons/clipboard-minus-fill.svg | 4 + .../libs/bootstrap-icons/clipboard-minus.svg | 5 + .../bootstrap-icons/clipboard-plus-fill.svg | 4 + .../libs/bootstrap-icons/clipboard-plus.svg | 5 + .../libs/bootstrap-icons/clipboard-pulse.svg | 3 + .../libs/bootstrap-icons/clipboard-x-fill.svg | 4 + .../css/libs/bootstrap-icons/clipboard-x.svg | 5 + .../css/libs/bootstrap-icons/clipboard.svg | 4 + .../bootstrap-icons/clipboard2-check-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-check.svg | 5 + .../bootstrap-icons/clipboard2-data-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-data.svg | 5 + .../libs/bootstrap-icons/clipboard2-fill.svg | 4 + .../bootstrap-icons/clipboard2-heart-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-heart.svg | 5 + .../bootstrap-icons/clipboard2-minus-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-minus.svg | 5 + .../bootstrap-icons/clipboard2-plus-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-plus.svg | 5 + .../bootstrap-icons/clipboard2-pulse-fill.svg | 4 + .../libs/bootstrap-icons/clipboard2-pulse.svg | 5 + .../bootstrap-icons/clipboard2-x-fill.svg | 4 + .../css/libs/bootstrap-icons/clipboard2-x.svg | 5 + .../css/libs/bootstrap-icons/clipboard2.svg | 4 + .../css/libs/bootstrap-icons/clock-fill.svg | 3 + .../libs/bootstrap-icons/clock-history.svg | 5 + .../css/libs/bootstrap-icons/clock.svg | 4 + .../bootstrap-icons/cloud-arrow-down-fill.svg | 3 + .../libs/bootstrap-icons/cloud-arrow-down.svg | 4 + .../bootstrap-icons/cloud-arrow-up-fill.svg | 3 + .../libs/bootstrap-icons/cloud-arrow-up.svg | 4 + .../libs/bootstrap-icons/cloud-check-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-check.svg | 4 + .../bootstrap-icons/cloud-download-fill.svg | 3 + .../libs/bootstrap-icons/cloud-download.svg | 4 + .../bootstrap-icons/cloud-drizzle-fill.svg | 3 + .../libs/bootstrap-icons/cloud-drizzle.svg | 3 + .../css/libs/bootstrap-icons/cloud-fill.svg | 3 + .../libs/bootstrap-icons/cloud-fog-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-fog.svg | 3 + .../libs/bootstrap-icons/cloud-fog2-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-fog2.svg | 3 + .../libs/bootstrap-icons/cloud-hail-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-hail.svg | 3 + .../libs/bootstrap-icons/cloud-haze-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-haze.svg | 3 + .../libs/bootstrap-icons/cloud-haze2-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-haze2.svg | 3 + .../bootstrap-icons/cloud-lightning-fill.svg | 3 + .../cloud-lightning-rain-fill.svg | 3 + .../bootstrap-icons/cloud-lightning-rain.svg | 3 + .../libs/bootstrap-icons/cloud-lightning.svg | 3 + .../libs/bootstrap-icons/cloud-minus-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-minus.svg | 4 + .../libs/bootstrap-icons/cloud-moon-fill.svg | 4 + .../css/libs/bootstrap-icons/cloud-moon.svg | 4 + .../libs/bootstrap-icons/cloud-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-plus.svg | 4 + .../libs/bootstrap-icons/cloud-rain-fill.svg | 3 + .../bootstrap-icons/cloud-rain-heavy-fill.svg | 3 + .../libs/bootstrap-icons/cloud-rain-heavy.svg | 3 + .../css/libs/bootstrap-icons/cloud-rain.svg | 3 + .../libs/bootstrap-icons/cloud-slash-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-slash.svg | 4 + .../libs/bootstrap-icons/cloud-sleet-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-sleet.svg | 3 + .../libs/bootstrap-icons/cloud-snow-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-snow.svg | 3 + .../libs/bootstrap-icons/cloud-sun-fill.svg | 4 + .../css/libs/bootstrap-icons/cloud-sun.svg | 4 + .../bootstrap-icons/cloud-upload-fill.svg | 3 + .../css/libs/bootstrap-icons/cloud-upload.svg | 4 + .../css/libs/bootstrap-icons/cloud.svg | 3 + .../css/libs/bootstrap-icons/clouds-fill.svg | 4 + .../css/libs/bootstrap-icons/clouds.svg | 4 + .../css/libs/bootstrap-icons/cloudy-fill.svg | 3 + .../css/libs/bootstrap-icons/cloudy.svg | 3 + .../css/libs/bootstrap-icons/code-slash.svg | 3 + .../css/libs/bootstrap-icons/code-square.svg | 4 + .../css/libs/bootstrap-icons/code.svg | 3 + .../css/libs/bootstrap-icons/coin.svg | 5 + .../libs/bootstrap-icons/collection-fill.svg | 3 + .../bootstrap-icons/collection-play-fill.svg | 3 + .../libs/bootstrap-icons/collection-play.svg | 4 + .../css/libs/bootstrap-icons/collection.svg | 3 + .../css/libs/bootstrap-icons/columns-gap.svg | 3 + .../css/libs/bootstrap-icons/columns.svg | 3 + .../css/libs/bootstrap-icons/command.svg | 3 + .../css/libs/bootstrap-icons/compass-fill.svg | 3 + .../css/libs/bootstrap-icons/compass.svg | 4 + .../css/libs/bootstrap-icons/cone-striped.svg | 3 + .../css/libs/bootstrap-icons/cone.svg | 3 + .../css/libs/bootstrap-icons/controller.svg | 4 + .../css/libs/bootstrap-icons/cpu-fill.svg | 4 + .../css/libs/bootstrap-icons/cpu.svg | 3 + .../credit-card-2-back-fill.svg | 3 + .../bootstrap-icons/credit-card-2-back.svg | 4 + .../credit-card-2-front-fill.svg | 3 + .../bootstrap-icons/credit-card-2-front.svg | 4 + .../libs/bootstrap-icons/credit-card-fill.svg | 3 + .../css/libs/bootstrap-icons/credit-card.svg | 4 + .../css/libs/bootstrap-icons/crop.svg | 3 + .../css/libs/bootstrap-icons/cup-fill.svg | 3 + .../css/libs/bootstrap-icons/cup-straw.svg | 3 + .../css/libs/bootstrap-icons/cup.svg | 3 + .../libs/bootstrap-icons/currency-bitcoin.svg | 3 + .../libs/bootstrap-icons/currency-dollar.svg | 3 + .../libs/bootstrap-icons/currency-euro.svg | 3 + .../bootstrap-icons/currency-exchange.svg | 3 + .../libs/bootstrap-icons/currency-pound.svg | 3 + .../css/libs/bootstrap-icons/currency-yen.svg | 3 + .../css/libs/bootstrap-icons/cursor-fill.svg | 3 + .../css/libs/bootstrap-icons/cursor-text.svg | 3 + .../css/libs/bootstrap-icons/cursor.svg | 3 + .../bootstrap-icons/dash-circle-dotted.svg | 3 + .../libs/bootstrap-icons/dash-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/dash-circle.svg | 4 + .../css/libs/bootstrap-icons/dash-lg.svg | 3 + .../bootstrap-icons/dash-square-dotted.svg | 3 + .../libs/bootstrap-icons/dash-square-fill.svg | 3 + .../css/libs/bootstrap-icons/dash-square.svg | 4 + .../css/libs/bootstrap-icons/dash.svg | 3 + .../libs/bootstrap-icons/device-hdd-fill.svg | 4 + .../css/libs/bootstrap-icons/device-hdd.svg | 5 + .../libs/bootstrap-icons/device-ssd-fill.svg | 4 + .../css/libs/bootstrap-icons/device-ssd.svg | 4 + .../libs/bootstrap-icons/diagram-2-fill.svg | 3 + .../css/libs/bootstrap-icons/diagram-2.svg | 3 + .../libs/bootstrap-icons/diagram-3-fill.svg | 3 + .../css/libs/bootstrap-icons/diagram-3.svg | 3 + .../css/libs/bootstrap-icons/diamond-fill.svg | 3 + .../css/libs/bootstrap-icons/diamond-half.svg | 3 + .../css/libs/bootstrap-icons/diamond.svg | 3 + .../css/libs/bootstrap-icons/dice-1-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-1.svg | 4 + .../css/libs/bootstrap-icons/dice-2-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-2.svg | 4 + .../css/libs/bootstrap-icons/dice-3-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-3.svg | 4 + .../css/libs/bootstrap-icons/dice-4-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-4.svg | 4 + .../css/libs/bootstrap-icons/dice-5-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-5.svg | 4 + .../css/libs/bootstrap-icons/dice-6-fill.svg | 3 + .../css/libs/bootstrap-icons/dice-6.svg | 4 + .../css/libs/bootstrap-icons/disc-fill.svg | 3 + .../css/libs/bootstrap-icons/disc.svg | 4 + .../css/libs/bootstrap-icons/discord.svg | 3 + .../css/libs/bootstrap-icons/display-fill.svg | 3 + .../css/libs/bootstrap-icons/display.svg | 3 + .../libs/bootstrap-icons/displayport-fill.svg | 3 + .../css/libs/bootstrap-icons/displayport.svg | 4 + .../bootstrap-icons/distribute-horizontal.svg | 4 + .../bootstrap-icons/distribute-vertical.svg | 4 + .../libs/bootstrap-icons/door-closed-fill.svg | 3 + .../css/libs/bootstrap-icons/door-closed.svg | 4 + .../libs/bootstrap-icons/door-open-fill.svg | 3 + .../css/libs/bootstrap-icons/door-open.svg | 4 + .../css/libs/bootstrap-icons/dot.svg | 3 + .../css/libs/bootstrap-icons/download.svg | 4 + .../css/libs/bootstrap-icons/dpad-fill.svg | 3 + .../css/libs/bootstrap-icons/dpad.svg | 4 + .../css/libs/bootstrap-icons/dribbble.svg | 3 + .../css/libs/bootstrap-icons/droplet-fill.svg | 3 + .../css/libs/bootstrap-icons/droplet-half.svg | 4 + .../css/libs/bootstrap-icons/droplet.svg | 4 + .../css/libs/bootstrap-icons/ear-fill.svg | 3 + .../css/libs/bootstrap-icons/ear.svg | 3 + .../css/libs/bootstrap-icons/earbuds.svg | 3 + .../css/libs/bootstrap-icons/easel-fill.svg | 3 + .../css/libs/bootstrap-icons/easel.svg | 3 + .../css/libs/bootstrap-icons/easel2-fill.svg | 4 + .../css/libs/bootstrap-icons/easel2.svg | 3 + .../css/libs/bootstrap-icons/easel3-fill.svg | 3 + .../css/libs/bootstrap-icons/easel3.svg | 3 + .../css/libs/bootstrap-icons/egg-fill.svg | 3 + .../css/libs/bootstrap-icons/egg-fried.svg | 4 + .../css/libs/bootstrap-icons/egg.svg | 3 + .../css/libs/bootstrap-icons/eject-fill.svg | 3 + .../css/libs/bootstrap-icons/eject.svg | 3 + .../libs/bootstrap-icons/emoji-angry-fill.svg | 3 + .../css/libs/bootstrap-icons/emoji-angry.svg | 4 + .../libs/bootstrap-icons/emoji-dizzy-fill.svg | 3 + .../css/libs/bootstrap-icons/emoji-dizzy.svg | 4 + .../emoji-expressionless-fill.svg | 3 + .../bootstrap-icons/emoji-expressionless.svg | 4 + .../libs/bootstrap-icons/emoji-frown-fill.svg | 3 + .../css/libs/bootstrap-icons/emoji-frown.svg | 4 + .../bootstrap-icons/emoji-heart-eyes-fill.svg | 3 + .../libs/bootstrap-icons/emoji-heart-eyes.svg | 4 + .../libs/bootstrap-icons/emoji-kiss-fill.svg | 3 + .../css/libs/bootstrap-icons/emoji-kiss.svg | 3 + .../bootstrap-icons/emoji-laughing-fill.svg | 3 + .../libs/bootstrap-icons/emoji-laughing.svg | 4 + .../bootstrap-icons/emoji-neutral-fill.svg | 3 + .../libs/bootstrap-icons/emoji-neutral.svg | 4 + .../libs/bootstrap-icons/emoji-smile-fill.svg | 3 + .../emoji-smile-upside-down-fill.svg | 3 + .../emoji-smile-upside-down.svg | 4 + .../css/libs/bootstrap-icons/emoji-smile.svg | 4 + .../bootstrap-icons/emoji-sunglasses-fill.svg | 3 + .../libs/bootstrap-icons/emoji-sunglasses.svg | 4 + .../libs/bootstrap-icons/emoji-wink-fill.svg | 3 + .../css/libs/bootstrap-icons/emoji-wink.svg | 4 + .../bootstrap-icons/envelope-check-fill.svg | 4 + .../libs/bootstrap-icons/envelope-check.svg | 4 + .../bootstrap-icons/envelope-dash-fill.svg | 4 + .../libs/bootstrap-icons/envelope-dash.svg | 4 + .../envelope-exclamation-fill.svg | 4 + .../bootstrap-icons/envelope-exclamation.svg | 4 + .../libs/bootstrap-icons/envelope-fill.svg | 3 + .../bootstrap-icons/envelope-heart-fill.svg | 4 + .../libs/bootstrap-icons/envelope-heart.svg | 3 + .../bootstrap-icons/envelope-open-fill.svg | 3 + .../envelope-open-heart-fill.svg | 4 + .../bootstrap-icons/envelope-open-heart.svg | 3 + .../libs/bootstrap-icons/envelope-open.svg | 3 + .../bootstrap-icons/envelope-paper-fill.svg | 3 + .../envelope-paper-heart-fill.svg | 3 + .../bootstrap-icons/envelope-paper-heart.svg | 3 + .../libs/bootstrap-icons/envelope-paper.svg | 3 + .../bootstrap-icons/envelope-plus-fill.svg | 4 + .../libs/bootstrap-icons/envelope-plus.svg | 4 + .../bootstrap-icons/envelope-slash-fill.svg | 4 + .../libs/bootstrap-icons/envelope-slash.svg | 4 + .../libs/bootstrap-icons/envelope-x-fill.svg | 4 + .../css/libs/bootstrap-icons/envelope-x.svg | 4 + .../css/libs/bootstrap-icons/envelope.svg | 3 + .../css/libs/bootstrap-icons/eraser-fill.svg | 3 + .../css/libs/bootstrap-icons/eraser.svg | 3 + .../css/libs/bootstrap-icons/ethernet.svg | 4 + .../exclamation-circle-fill.svg | 3 + .../bootstrap-icons/exclamation-circle.svg | 4 + .../exclamation-diamond-fill.svg | 3 + .../bootstrap-icons/exclamation-diamond.svg | 4 + .../libs/bootstrap-icons/exclamation-lg.svg | 3 + .../exclamation-octagon-fill.svg | 3 + .../bootstrap-icons/exclamation-octagon.svg | 4 + .../exclamation-square-fill.svg | 3 + .../bootstrap-icons/exclamation-square.svg | 4 + .../exclamation-triangle-fill.svg | 3 + .../bootstrap-icons/exclamation-triangle.svg | 4 + .../css/libs/bootstrap-icons/exclamation.svg | 3 + .../css/libs/bootstrap-icons/exclude.svg | 3 + .../libs/bootstrap-icons/explicit-fill.svg | 3 + .../css/libs/bootstrap-icons/explicit.svg | 4 + .../css/libs/bootstrap-icons/eye-fill.svg | 4 + .../libs/bootstrap-icons/eye-slash-fill.svg | 4 + .../css/libs/bootstrap-icons/eye-slash.svg | 5 + .../css/libs/bootstrap-icons/eye.svg | 4 + .../css/libs/bootstrap-icons/eyedropper.svg | 3 + .../css/libs/bootstrap-icons/eyeglasses.svg | 3 + .../css/libs/bootstrap-icons/facebook.svg | 3 + .../css/libs/bootstrap-icons/fan.svg | 4 + .../bootstrap-icons/file-arrow-down-fill.svg | 3 + .../libs/bootstrap-icons/file-arrow-down.svg | 4 + .../bootstrap-icons/file-arrow-up-fill.svg | 3 + .../libs/bootstrap-icons/file-arrow-up.svg | 4 + .../bootstrap-icons/file-bar-graph-fill.svg | 3 + .../libs/bootstrap-icons/file-bar-graph.svg | 4 + .../libs/bootstrap-icons/file-binary-fill.svg | 4 + .../css/libs/bootstrap-icons/file-binary.svg | 4 + .../libs/bootstrap-icons/file-break-fill.svg | 3 + .../css/libs/bootstrap-icons/file-break.svg | 3 + .../libs/bootstrap-icons/file-check-fill.svg | 3 + .../css/libs/bootstrap-icons/file-check.svg | 4 + .../libs/bootstrap-icons/file-code-fill.svg | 3 + .../css/libs/bootstrap-icons/file-code.svg | 4 + .../libs/bootstrap-icons/file-diff-fill.svg | 3 + .../css/libs/bootstrap-icons/file-diff.svg | 4 + .../file-earmark-arrow-down-fill.svg | 3 + .../file-earmark-arrow-down.svg | 4 + .../file-earmark-arrow-up-fill.svg | 3 + .../bootstrap-icons/file-earmark-arrow-up.svg | 4 + .../file-earmark-bar-graph-fill.svg | 3 + .../file-earmark-bar-graph.svg | 4 + .../file-earmark-binary-fill.svg | 4 + .../bootstrap-icons/file-earmark-binary.svg | 4 + .../file-earmark-break-fill.svg | 3 + .../bootstrap-icons/file-earmark-break.svg | 3 + .../file-earmark-check-fill.svg | 3 + .../bootstrap-icons/file-earmark-check.svg | 4 + .../file-earmark-code-fill.svg | 3 + .../bootstrap-icons/file-earmark-code.svg | 4 + .../file-earmark-diff-fill.svg | 3 + .../bootstrap-icons/file-earmark-diff.svg | 4 + .../file-earmark-easel-fill.svg | 4 + .../bootstrap-icons/file-earmark-easel.svg | 4 + .../file-earmark-excel-fill.svg | 3 + .../bootstrap-icons/file-earmark-excel.svg | 4 + .../bootstrap-icons/file-earmark-fill.svg | 3 + .../file-earmark-font-fill.svg | 3 + .../bootstrap-icons/file-earmark-font.svg | 4 + .../file-earmark-image-fill.svg | 4 + .../bootstrap-icons/file-earmark-image.svg | 4 + .../file-earmark-lock-fill.svg | 4 + .../bootstrap-icons/file-earmark-lock.svg | 4 + .../file-earmark-lock2-fill.svg | 4 + .../bootstrap-icons/file-earmark-lock2.svg | 4 + .../file-earmark-medical-fill.svg | 3 + .../bootstrap-icons/file-earmark-medical.svg | 4 + .../file-earmark-minus-fill.svg | 3 + .../bootstrap-icons/file-earmark-minus.svg | 4 + .../file-earmark-music-fill.svg | 3 + .../bootstrap-icons/file-earmark-music.svg | 4 + .../bootstrap-icons/file-earmark-pdf-fill.svg | 4 + .../libs/bootstrap-icons/file-earmark-pdf.svg | 4 + .../file-earmark-person-fill.svg | 3 + .../bootstrap-icons/file-earmark-person.svg | 4 + .../file-earmark-play-fill.svg | 3 + .../bootstrap-icons/file-earmark-play.svg | 4 + .../file-earmark-plus-fill.svg | 3 + .../bootstrap-icons/file-earmark-plus.svg | 4 + .../file-earmark-post-fill.svg | 3 + .../bootstrap-icons/file-earmark-post.svg | 4 + .../bootstrap-icons/file-earmark-ppt-fill.svg | 4 + .../libs/bootstrap-icons/file-earmark-ppt.svg | 4 + .../file-earmark-richtext-fill.svg | 3 + .../bootstrap-icons/file-earmark-richtext.svg | 4 + .../file-earmark-ruled-fill.svg | 3 + .../bootstrap-icons/file-earmark-ruled.svg | 3 + .../file-earmark-slides-fill.svg | 4 + .../bootstrap-icons/file-earmark-slides.svg | 4 + .../file-earmark-spreadsheet-fill.svg | 4 + .../file-earmark-spreadsheet.svg | 3 + .../file-earmark-text-fill.svg | 3 + .../bootstrap-icons/file-earmark-text.svg | 4 + .../file-earmark-word-fill.svg | 3 + .../bootstrap-icons/file-earmark-word.svg | 4 + .../bootstrap-icons/file-earmark-x-fill.svg | 3 + .../libs/bootstrap-icons/file-earmark-x.svg | 4 + .../bootstrap-icons/file-earmark-zip-fill.svg | 4 + .../libs/bootstrap-icons/file-earmark-zip.svg | 4 + .../css/libs/bootstrap-icons/file-earmark.svg | 3 + .../libs/bootstrap-icons/file-easel-fill.svg | 4 + .../css/libs/bootstrap-icons/file-easel.svg | 4 + .../libs/bootstrap-icons/file-excel-fill.svg | 3 + .../css/libs/bootstrap-icons/file-excel.svg | 4 + .../css/libs/bootstrap-icons/file-fill.svg | 3 + .../libs/bootstrap-icons/file-font-fill.svg | 3 + .../css/libs/bootstrap-icons/file-font.svg | 4 + .../libs/bootstrap-icons/file-image-fill.svg | 4 + .../css/libs/bootstrap-icons/file-image.svg | 4 + .../libs/bootstrap-icons/file-lock-fill.svg | 4 + .../css/libs/bootstrap-icons/file-lock.svg | 4 + .../libs/bootstrap-icons/file-lock2-fill.svg | 4 + .../css/libs/bootstrap-icons/file-lock2.svg | 4 + .../bootstrap-icons/file-medical-fill.svg | 3 + .../css/libs/bootstrap-icons/file-medical.svg | 4 + .../libs/bootstrap-icons/file-minus-fill.svg | 3 + .../css/libs/bootstrap-icons/file-minus.svg | 4 + .../libs/bootstrap-icons/file-music-fill.svg | 3 + .../css/libs/bootstrap-icons/file-music.svg | 4 + .../libs/bootstrap-icons/file-pdf-fill.svg | 4 + .../css/libs/bootstrap-icons/file-pdf.svg | 4 + .../libs/bootstrap-icons/file-person-fill.svg | 3 + .../css/libs/bootstrap-icons/file-person.svg | 4 + .../libs/bootstrap-icons/file-play-fill.svg | 3 + .../css/libs/bootstrap-icons/file-play.svg | 4 + .../libs/bootstrap-icons/file-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/file-plus.svg | 4 + .../libs/bootstrap-icons/file-post-fill.svg | 3 + .../css/libs/bootstrap-icons/file-post.svg | 4 + .../libs/bootstrap-icons/file-ppt-fill.svg | 4 + .../css/libs/bootstrap-icons/file-ppt.svg | 4 + .../bootstrap-icons/file-richtext-fill.svg | 3 + .../libs/bootstrap-icons/file-richtext.svg | 4 + .../libs/bootstrap-icons/file-ruled-fill.svg | 3 + .../css/libs/bootstrap-icons/file-ruled.svg | 3 + .../libs/bootstrap-icons/file-slides-fill.svg | 4 + .../css/libs/bootstrap-icons/file-slides.svg | 4 + .../bootstrap-icons/file-spreadsheet-fill.svg | 3 + .../libs/bootstrap-icons/file-spreadsheet.svg | 3 + .../libs/bootstrap-icons/file-text-fill.svg | 3 + .../css/libs/bootstrap-icons/file-text.svg | 4 + .../libs/bootstrap-icons/file-word-fill.svg | 3 + .../css/libs/bootstrap-icons/file-word.svg | 4 + .../css/libs/bootstrap-icons/file-x-fill.svg | 3 + .../css/libs/bootstrap-icons/file-x.svg | 4 + .../libs/bootstrap-icons/file-zip-fill.svg | 4 + .../css/libs/bootstrap-icons/file-zip.svg | 4 + .../css/libs/bootstrap-icons/file.svg | 3 + .../css/libs/bootstrap-icons/files-alt.svg | 3 + .../css/libs/bootstrap-icons/files.svg | 3 + .../css/libs/bootstrap-icons/filetype-aac.svg | 3 + .../css/libs/bootstrap-icons/filetype-ai.svg | 3 + .../css/libs/bootstrap-icons/filetype-bmp.svg | 3 + .../css/libs/bootstrap-icons/filetype-cs.svg | 3 + .../css/libs/bootstrap-icons/filetype-css.svg | 3 + .../css/libs/bootstrap-icons/filetype-csv.svg | 3 + .../css/libs/bootstrap-icons/filetype-doc.svg | 3 + .../libs/bootstrap-icons/filetype-docx.svg | 3 + .../css/libs/bootstrap-icons/filetype-exe.svg | 3 + .../css/libs/bootstrap-icons/filetype-gif.svg | 3 + .../libs/bootstrap-icons/filetype-heic.svg | 3 + .../libs/bootstrap-icons/filetype-html.svg | 3 + .../libs/bootstrap-icons/filetype-java.svg | 3 + .../css/libs/bootstrap-icons/filetype-jpg.svg | 3 + .../css/libs/bootstrap-icons/filetype-js.svg | 3 + .../libs/bootstrap-icons/filetype-json.svg | 3 + .../css/libs/bootstrap-icons/filetype-jsx.svg | 3 + .../css/libs/bootstrap-icons/filetype-key.svg | 3 + .../css/libs/bootstrap-icons/filetype-m4p.svg | 3 + .../css/libs/bootstrap-icons/filetype-md.svg | 3 + .../css/libs/bootstrap-icons/filetype-mdx.svg | 3 + .../css/libs/bootstrap-icons/filetype-mov.svg | 3 + .../css/libs/bootstrap-icons/filetype-mp3.svg | 3 + .../css/libs/bootstrap-icons/filetype-mp4.svg | 3 + .../css/libs/bootstrap-icons/filetype-otf.svg | 3 + .../css/libs/bootstrap-icons/filetype-pdf.svg | 3 + .../css/libs/bootstrap-icons/filetype-php.svg | 3 + .../css/libs/bootstrap-icons/filetype-png.svg | 3 + .../css/libs/bootstrap-icons/filetype-ppt.svg | 3 + .../libs/bootstrap-icons/filetype-pptx.svg | 3 + .../css/libs/bootstrap-icons/filetype-psd.svg | 3 + .../css/libs/bootstrap-icons/filetype-py.svg | 3 + .../css/libs/bootstrap-icons/filetype-raw.svg | 3 + .../css/libs/bootstrap-icons/filetype-rb.svg | 3 + .../libs/bootstrap-icons/filetype-sass.svg | 3 + .../libs/bootstrap-icons/filetype-scss.svg | 3 + .../css/libs/bootstrap-icons/filetype-sh.svg | 3 + .../css/libs/bootstrap-icons/filetype-svg.svg | 3 + .../libs/bootstrap-icons/filetype-tiff.svg | 3 + .../css/libs/bootstrap-icons/filetype-tsx.svg | 3 + .../css/libs/bootstrap-icons/filetype-ttf.svg | 3 + .../css/libs/bootstrap-icons/filetype-txt.svg | 3 + .../css/libs/bootstrap-icons/filetype-wav.svg | 3 + .../libs/bootstrap-icons/filetype-woff.svg | 3 + .../css/libs/bootstrap-icons/filetype-xls.svg | 3 + .../libs/bootstrap-icons/filetype-xlsx.svg | 3 + .../css/libs/bootstrap-icons/filetype-xml.svg | 3 + .../css/libs/bootstrap-icons/filetype-yml.svg | 3 + .../css/libs/bootstrap-icons/film.svg | 3 + .../bootstrap-icons/filter-circle-fill.svg | 3 + .../libs/bootstrap-icons/filter-circle.svg | 4 + .../css/libs/bootstrap-icons/filter-left.svg | 3 + .../css/libs/bootstrap-icons/filter-right.svg | 3 + .../bootstrap-icons/filter-square-fill.svg | 3 + .../libs/bootstrap-icons/filter-square.svg | 4 + .../css/libs/bootstrap-icons/filter.svg | 3 + .../css/libs/bootstrap-icons/fingerprint.svg | 7 + .../css/libs/bootstrap-icons/flag-fill.svg | 3 + .../css/libs/bootstrap-icons/flag.svg | 3 + .../css/libs/bootstrap-icons/flower1.svg | 3 + .../css/libs/bootstrap-icons/flower2.svg | 3 + .../css/libs/bootstrap-icons/flower3.svg | 3 + .../css/libs/bootstrap-icons/folder-check.svg | 4 + .../css/libs/bootstrap-icons/folder-fill.svg | 3 + .../css/libs/bootstrap-icons/folder-minus.svg | 4 + .../css/libs/bootstrap-icons/folder-plus.svg | 4 + .../bootstrap-icons/folder-symlink-fill.svg | 3 + .../libs/bootstrap-icons/folder-symlink.svg | 4 + .../css/libs/bootstrap-icons/folder-x.svg | 4 + .../css/libs/bootstrap-icons/folder.svg | 3 + .../css/libs/bootstrap-icons/folder2-open.svg | 3 + .../css/libs/bootstrap-icons/folder2.svg | 3 + .../css/libs/bootstrap-icons/fonts.svg | 3 + .../fonts/bootstrap-icons.woff | Bin 0 -> 137216 bytes .../fonts/bootstrap-icons.woff2 | Bin 0 -> 102380 bytes .../css/libs/bootstrap-icons/forward-fill.svg | 3 + .../css/libs/bootstrap-icons/forward.svg | 3 + .../css/libs/bootstrap-icons/front.svg | 3 + .../libs/bootstrap-icons/fullscreen-exit.svg | 3 + .../css/libs/bootstrap-icons/fullscreen.svg | 3 + .../css/libs/bootstrap-icons/funnel-fill.svg | 3 + .../css/libs/bootstrap-icons/funnel.svg | 3 + .../css/libs/bootstrap-icons/gear-fill.svg | 3 + .../bootstrap-icons/gear-wide-connected.svg | 3 + .../css/libs/bootstrap-icons/gear-wide.svg | 3 + .../css/libs/bootstrap-icons/gear.svg | 4 + .../css/libs/bootstrap-icons/gem.svg | 3 + .../libs/bootstrap-icons/gender-ambiguous.svg | 3 + .../libs/bootstrap-icons/gender-female.svg | 3 + .../css/libs/bootstrap-icons/gender-male.svg | 3 + .../css/libs/bootstrap-icons/gender-trans.svg | 3 + .../css/libs/bootstrap-icons/geo-alt-fill.svg | 3 + .../css/libs/bootstrap-icons/geo-alt.svg | 4 + .../css/libs/bootstrap-icons/geo-fill.svg | 3 + .../css/libs/bootstrap-icons/geo.svg | 3 + .../css/libs/bootstrap-icons/gift-fill.svg | 3 + .../css/libs/bootstrap-icons/gift.svg | 3 + .../css/libs/bootstrap-icons/git.svg | 3 + .../css/libs/bootstrap-icons/github.svg | 3 + .../css/libs/bootstrap-icons/globe.svg | 3 + .../css/libs/bootstrap-icons/globe2.svg | 3 + .../css/libs/bootstrap-icons/google.svg | 3 + .../css/libs/bootstrap-icons/gpu-card.svg | 5 + .../libs/bootstrap-icons/graph-down-arrow.svg | 3 + .../css/libs/bootstrap-icons/graph-down.svg | 3 + .../libs/bootstrap-icons/graph-up-arrow.svg | 3 + .../css/libs/bootstrap-icons/graph-up.svg | 3 + .../libs/bootstrap-icons/grid-1x2-fill.svg | 3 + .../css/libs/bootstrap-icons/grid-1x2.svg | 3 + .../bootstrap-icons/grid-3x2-gap-fill.svg | 3 + .../css/libs/bootstrap-icons/grid-3x2-gap.svg | 3 + .../css/libs/bootstrap-icons/grid-3x2.svg | 3 + .../bootstrap-icons/grid-3x3-gap-fill.svg | 3 + .../css/libs/bootstrap-icons/grid-3x3-gap.svg | 3 + .../css/libs/bootstrap-icons/grid-3x3.svg | 3 + .../css/libs/bootstrap-icons/grid-fill.svg | 3 + .../css/libs/bootstrap-icons/grid.svg | 3 + .../libs/bootstrap-icons/grip-horizontal.svg | 3 + .../libs/bootstrap-icons/grip-vertical.svg | 3 + .../css/libs/bootstrap-icons/hammer.svg | 3 + .../libs/bootstrap-icons/hand-index-fill.svg | 3 + .../bootstrap-icons/hand-index-thumb-fill.svg | 3 + .../libs/bootstrap-icons/hand-index-thumb.svg | 3 + .../css/libs/bootstrap-icons/hand-index.svg | 3 + .../bootstrap-icons/hand-thumbs-down-fill.svg | 3 + .../libs/bootstrap-icons/hand-thumbs-down.svg | 3 + .../bootstrap-icons/hand-thumbs-up-fill.svg | 3 + .../libs/bootstrap-icons/hand-thumbs-up.svg | 3 + .../css/libs/bootstrap-icons/handbag-fill.svg | 3 + .../css/libs/bootstrap-icons/handbag.svg | 3 + .../css/libs/bootstrap-icons/hash.svg | 3 + .../css/libs/bootstrap-icons/hdd-fill.svg | 3 + .../libs/bootstrap-icons/hdd-network-fill.svg | 3 + .../css/libs/bootstrap-icons/hdd-network.svg | 4 + .../libs/bootstrap-icons/hdd-rack-fill.svg | 3 + .../css/libs/bootstrap-icons/hdd-rack.svg | 4 + .../libs/bootstrap-icons/hdd-stack-fill.svg | 3 + .../css/libs/bootstrap-icons/hdd-stack.svg | 5 + .../css/libs/bootstrap-icons/hdd.svg | 4 + .../css/libs/bootstrap-icons/hdmi-fill.svg | 3 + .../css/libs/bootstrap-icons/hdmi.svg | 4 + .../css/libs/bootstrap-icons/headphones.svg | 3 + .../css/libs/bootstrap-icons/headset-vr.svg | 4 + .../css/libs/bootstrap-icons/headset.svg | 3 + .../css/libs/bootstrap-icons/heart-arrow.svg | 3 + .../css/libs/bootstrap-icons/heart-fill.svg | 3 + .../css/libs/bootstrap-icons/heart-half.svg | 3 + .../libs/bootstrap-icons/heart-pulse-fill.svg | 3 + .../css/libs/bootstrap-icons/heart-pulse.svg | 3 + .../css/libs/bootstrap-icons/heart.svg | 3 + .../libs/bootstrap-icons/heartbreak-fill.svg | 3 + .../css/libs/bootstrap-icons/heartbreak.svg | 3 + .../css/libs/bootstrap-icons/hearts.svg | 3 + .../libs/bootstrap-icons/heptagon-fill.svg | 3 + .../libs/bootstrap-icons/heptagon-half.svg | 3 + .../css/libs/bootstrap-icons/heptagon.svg | 3 + .../css/libs/bootstrap-icons/hexagon-fill.svg | 3 + .../css/libs/bootstrap-icons/hexagon-half.svg | 3 + .../css/libs/bootstrap-icons/hexagon.svg | 3 + .../libs/bootstrap-icons/hospital-fill.svg | 3 + .../css/libs/bootstrap-icons/hospital.svg | 4 + .../libs/bootstrap-icons/hourglass-bottom.svg | 3 + .../libs/bootstrap-icons/hourglass-split.svg | 3 + .../libs/bootstrap-icons/hourglass-top.svg | 3 + .../css/libs/bootstrap-icons/hourglass.svg | 3 + .../libs/bootstrap-icons/house-door-fill.svg | 3 + .../css/libs/bootstrap-icons/house-door.svg | 3 + .../css/libs/bootstrap-icons/house-fill.svg | 4 + .../libs/bootstrap-icons/house-heart-fill.svg | 4 + .../css/libs/bootstrap-icons/house-heart.svg | 4 + .../css/libs/bootstrap-icons/house.svg | 4 + .../resources/css/libs/bootstrap-icons/hr.svg | 3 + .../css/libs/bootstrap-icons/hurricane.svg | 3 + .../css/libs/bootstrap-icons/hypnotize.svg | 4 + .../css/libs/bootstrap-icons/image-alt.svg | 3 + .../css/libs/bootstrap-icons/image-fill.svg | 3 + .../css/libs/bootstrap-icons/image.svg | 4 + .../css/libs/bootstrap-icons/images.svg | 4 + .../css/libs/bootstrap-icons/inbox-fill.svg | 3 + .../css/libs/bootstrap-icons/inbox.svg | 3 + .../css/libs/bootstrap-icons/inboxes-fill.svg | 3 + .../css/libs/bootstrap-icons/inboxes.svg | 3 + .../css/libs/bootstrap-icons/incognito.svg | 3 + .../css/libs/bootstrap-icons/index.html | 6719 +++++++++++++++++ .../css/libs/bootstrap-icons/infinity.svg | 3 + .../libs/bootstrap-icons/info-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/info-circle.svg | 4 + .../css/libs/bootstrap-icons/info-lg.svg | 3 + .../libs/bootstrap-icons/info-square-fill.svg | 3 + .../css/libs/bootstrap-icons/info-square.svg | 4 + .../css/libs/bootstrap-icons/info.svg | 3 + .../bootstrap-icons/input-cursor-text.svg | 4 + .../css/libs/bootstrap-icons/input-cursor.svg | 4 + .../css/libs/bootstrap-icons/instagram.svg | 3 + .../css/libs/bootstrap-icons/intersect.svg | 3 + .../libs/bootstrap-icons/journal-album.svg | 5 + .../bootstrap-icons/journal-arrow-down.svg | 5 + .../libs/bootstrap-icons/journal-arrow-up.svg | 5 + .../bootstrap-icons/journal-bookmark-fill.svg | 5 + .../libs/bootstrap-icons/journal-bookmark.svg | 5 + .../libs/bootstrap-icons/journal-check.svg | 5 + .../css/libs/bootstrap-icons/journal-code.svg | 5 + .../libs/bootstrap-icons/journal-medical.svg | 5 + .../libs/bootstrap-icons/journal-minus.svg | 5 + .../css/libs/bootstrap-icons/journal-plus.svg | 5 + .../libs/bootstrap-icons/journal-richtext.svg | 5 + .../css/libs/bootstrap-icons/journal-text.svg | 5 + .../css/libs/bootstrap-icons/journal-x.svg | 5 + .../css/libs/bootstrap-icons/journal.svg | 4 + .../css/libs/bootstrap-icons/journals.svg | 4 + .../css/libs/bootstrap-icons/joystick.svg | 4 + .../css/libs/bootstrap-icons/justify-left.svg | 3 + .../libs/bootstrap-icons/justify-right.svg | 3 + .../css/libs/bootstrap-icons/justify.svg | 3 + .../css/libs/bootstrap-icons/kanban-fill.svg | 3 + .../css/libs/bootstrap-icons/kanban.svg | 4 + .../css/libs/bootstrap-icons/key-fill.svg | 3 + .../css/libs/bootstrap-icons/key.svg | 4 + .../libs/bootstrap-icons/keyboard-fill.svg | 3 + .../css/libs/bootstrap-icons/keyboard.svg | 4 + .../css/libs/bootstrap-icons/ladder.svg | 3 + .../css/libs/bootstrap-icons/lamp-fill.svg | 4 + .../css/libs/bootstrap-icons/lamp.svg | 4 + .../css/libs/bootstrap-icons/laptop-fill.svg | 3 + .../css/libs/bootstrap-icons/laptop.svg | 3 + .../libs/bootstrap-icons/layer-backward.svg | 4 + .../libs/bootstrap-icons/layer-forward.svg | 4 + .../css/libs/bootstrap-icons/layers-fill.svg | 4 + .../css/libs/bootstrap-icons/layers-half.svg | 3 + .../css/libs/bootstrap-icons/layers.svg | 3 + .../layout-sidebar-inset-reverse.svg | 4 + .../bootstrap-icons/layout-sidebar-inset.svg | 4 + .../layout-sidebar-reverse.svg | 3 + .../libs/bootstrap-icons/layout-sidebar.svg | 3 + .../css/libs/bootstrap-icons/layout-split.svg | 3 + .../layout-text-sidebar-reverse.svg | 4 + .../bootstrap-icons/layout-text-sidebar.svg | 4 + .../layout-text-window-reverse.svg | 4 + .../bootstrap-icons/layout-text-window.svg | 4 + .../bootstrap-icons/layout-three-columns.svg | 3 + .../css/libs/bootstrap-icons/layout-wtf.svg | 3 + .../libs/bootstrap-icons/life-preserver.svg | 3 + .../libs/bootstrap-icons/lightbulb-fill.svg | 3 + .../bootstrap-icons/lightbulb-off-fill.svg | 3 + .../libs/bootstrap-icons/lightbulb-off.svg | 3 + .../css/libs/bootstrap-icons/lightbulb.svg | 3 + .../bootstrap-icons/lightning-charge-fill.svg | 3 + .../libs/bootstrap-icons/lightning-charge.svg | 3 + .../libs/bootstrap-icons/lightning-fill.svg | 3 + .../css/libs/bootstrap-icons/lightning.svg | 3 + .../css/libs/bootstrap-icons/line.svg | 3 + .../css/libs/bootstrap-icons/link-45deg.svg | 4 + .../css/libs/bootstrap-icons/link.svg | 4 + .../css/libs/bootstrap-icons/linkedin.svg | 3 + .../css/libs/bootstrap-icons/list-check.svg | 3 + .../bootstrap-icons/list-columns-reverse.svg | 3 + .../css/libs/bootstrap-icons/list-columns.svg | 3 + .../css/libs/bootstrap-icons/list-nested.svg | 3 + .../css/libs/bootstrap-icons/list-ol.svg | 4 + .../css/libs/bootstrap-icons/list-stars.svg | 4 + .../css/libs/bootstrap-icons/list-task.svg | 5 + .../css/libs/bootstrap-icons/list-ul.svg | 3 + .../css/libs/bootstrap-icons/list.svg | 3 + .../css/libs/bootstrap-icons/lock-fill.svg | 3 + .../css/libs/bootstrap-icons/lock.svg | 3 + .../css/libs/bootstrap-icons/magic.svg | 3 + .../css/libs/bootstrap-icons/magnet-fill.svg | 3 + .../css/libs/bootstrap-icons/magnet.svg | 3 + .../css/libs/bootstrap-icons/mailbox.svg | 4 + .../css/libs/bootstrap-icons/mailbox2.svg | 4 + .../css/libs/bootstrap-icons/map-fill.svg | 3 + .../css/libs/bootstrap-icons/map.svg | 3 + .../libs/bootstrap-icons/markdown-fill.svg | 3 + .../css/libs/bootstrap-icons/markdown.svg | 6 + .../css/libs/bootstrap-icons/mask.svg | 3 + .../css/libs/bootstrap-icons/mastodon.svg | 3 + .../css/libs/bootstrap-icons/medium.svg | 3 + .../libs/bootstrap-icons/megaphone-fill.svg | 3 + .../css/libs/bootstrap-icons/megaphone.svg | 3 + .../css/libs/bootstrap-icons/memory.svg | 3 + .../libs/bootstrap-icons/menu-app-fill.svg | 3 + .../css/libs/bootstrap-icons/menu-app.svg | 3 + .../libs/bootstrap-icons/menu-button-fill.svg | 3 + .../bootstrap-icons/menu-button-wide-fill.svg | 3 + .../libs/bootstrap-icons/menu-button-wide.svg | 4 + .../css/libs/bootstrap-icons/menu-button.svg | 4 + .../css/libs/bootstrap-icons/menu-down.svg | 3 + .../css/libs/bootstrap-icons/menu-up.svg | 3 + .../css/libs/bootstrap-icons/messenger.svg | 3 + .../css/libs/bootstrap-icons/meta.svg | 3 + .../css/libs/bootstrap-icons/mic-fill.svg | 4 + .../libs/bootstrap-icons/mic-mute-fill.svg | 4 + .../css/libs/bootstrap-icons/mic-mute.svg | 4 + .../css/libs/bootstrap-icons/mic.svg | 4 + .../css/libs/bootstrap-icons/microsoft.svg | 3 + .../libs/bootstrap-icons/minecart-loaded.svg | 4 + .../css/libs/bootstrap-icons/minecart.svg | 3 + .../css/libs/bootstrap-icons/modem-fill.svg | 3 + .../css/libs/bootstrap-icons/modem.svg | 4 + .../css/libs/bootstrap-icons/moisture.svg | 3 + .../css/libs/bootstrap-icons/moon-fill.svg | 3 + .../libs/bootstrap-icons/moon-stars-fill.svg | 4 + .../css/libs/bootstrap-icons/moon-stars.svg | 4 + .../css/libs/bootstrap-icons/moon.svg | 3 + .../libs/bootstrap-icons/mortarboard-fill.svg | 4 + .../css/libs/bootstrap-icons/mortarboard.svg | 4 + .../libs/bootstrap-icons/motherboard-fill.svg | 4 + .../css/libs/bootstrap-icons/motherboard.svg | 4 + .../css/libs/bootstrap-icons/mouse-fill.svg | 3 + .../css/libs/bootstrap-icons/mouse.svg | 3 + .../css/libs/bootstrap-icons/mouse2-fill.svg | 3 + .../css/libs/bootstrap-icons/mouse2.svg | 3 + .../css/libs/bootstrap-icons/mouse3-fill.svg | 3 + .../css/libs/bootstrap-icons/mouse3.svg | 3 + .../bootstrap-icons/music-note-beamed.svg | 5 + .../libs/bootstrap-icons/music-note-list.svg | 6 + .../css/libs/bootstrap-icons/music-note.svg | 5 + .../bootstrap-icons/music-player-fill.svg | 4 + .../css/libs/bootstrap-icons/music-player.svg | 5 + .../css/libs/bootstrap-icons/newspaper.svg | 4 + .../libs/bootstrap-icons/nintendo-switch.svg | 4 + .../libs/bootstrap-icons/node-minus-fill.svg | 3 + .../css/libs/bootstrap-icons/node-minus.svg | 3 + .../libs/bootstrap-icons/node-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/node-plus.svg | 3 + .../css/libs/bootstrap-icons/nut-fill.svg | 3 + .../css/libs/bootstrap-icons/nut.svg | 4 + .../css/libs/bootstrap-icons/octagon-fill.svg | 3 + .../css/libs/bootstrap-icons/octagon-half.svg | 3 + .../css/libs/bootstrap-icons/octagon.svg | 3 + .../bootstrap-icons/optical-audio-fill.svg | 4 + .../libs/bootstrap-icons/optical-audio.svg | 5 + .../css/libs/bootstrap-icons/option.svg | 3 + .../css/libs/bootstrap-icons/outlet.svg | 4 + .../css/libs/bootstrap-icons/paint-bucket.svg | 3 + .../css/libs/bootstrap-icons/palette-fill.svg | 3 + .../css/libs/bootstrap-icons/palette.svg | 4 + .../css/libs/bootstrap-icons/palette2.svg | 4 + .../css/libs/bootstrap-icons/paperclip.svg | 3 + .../css/libs/bootstrap-icons/paragraph.svg | 3 + .../libs/bootstrap-icons/patch-check-fill.svg | 3 + .../css/libs/bootstrap-icons/patch-check.svg | 4 + .../patch-exclamation-fill.svg | 3 + .../bootstrap-icons/patch-exclamation.svg | 4 + .../libs/bootstrap-icons/patch-minus-fill.svg | 3 + .../css/libs/bootstrap-icons/patch-minus.svg | 4 + .../libs/bootstrap-icons/patch-plus-fill.svg | 3 + .../css/libs/bootstrap-icons/patch-plus.svg | 4 + .../bootstrap-icons/patch-question-fill.svg | 3 + .../libs/bootstrap-icons/patch-question.svg | 5 + .../libs/bootstrap-icons/pause-btn-fill.svg | 3 + .../css/libs/bootstrap-icons/pause-btn.svg | 4 + .../bootstrap-icons/pause-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/pause-circle.svg | 4 + .../css/libs/bootstrap-icons/pause-fill.svg | 3 + .../css/libs/bootstrap-icons/pause.svg | 3 + .../css/libs/bootstrap-icons/paypal.svg | 3 + .../bootstrap-icons/pc-display-horizontal.svg | 3 + .../css/libs/bootstrap-icons/pc-display.svg | 3 + .../libs/bootstrap-icons/pc-horizontal.svg | 3 + .../resources/css/libs/bootstrap-icons/pc.svg | 3 + .../css/libs/bootstrap-icons/pci-card.svg | 4 + .../css/libs/bootstrap-icons/peace-fill.svg | 3 + .../css/libs/bootstrap-icons/peace.svg | 3 + .../css/libs/bootstrap-icons/pen-fill.svg | 3 + .../css/libs/bootstrap-icons/pen.svg | 3 + .../css/libs/bootstrap-icons/pencil-fill.svg | 3 + .../libs/bootstrap-icons/pencil-square.svg | 4 + .../css/libs/bootstrap-icons/pencil.svg | 3 + .../libs/bootstrap-icons/pentagon-fill.svg | 3 + .../libs/bootstrap-icons/pentagon-half.svg | 3 + .../css/libs/bootstrap-icons/pentagon.svg | 3 + .../css/libs/bootstrap-icons/people-fill.svg | 5 + .../css/libs/bootstrap-icons/people.svg | 3 + .../css/libs/bootstrap-icons/percent.svg | 3 + .../bootstrap-icons/person-badge-fill.svg | 3 + .../css/libs/bootstrap-icons/person-badge.svg | 4 + .../bootstrap-icons/person-bounding-box.svg | 4 + .../bootstrap-icons/person-check-fill.svg | 4 + .../css/libs/bootstrap-icons/person-check.svg | 4 + .../libs/bootstrap-icons/person-circle.svg | 4 + .../libs/bootstrap-icons/person-dash-fill.svg | 4 + .../css/libs/bootstrap-icons/person-dash.svg | 4 + .../css/libs/bootstrap-icons/person-fill.svg | 3 + .../css/libs/bootstrap-icons/person-heart.svg | 3 + .../libs/bootstrap-icons/person-hearts.svg | 3 + .../bootstrap-icons/person-lines-fill.svg | 3 + .../libs/bootstrap-icons/person-plus-fill.svg | 4 + .../css/libs/bootstrap-icons/person-plus.svg | 4 + .../libs/bootstrap-icons/person-rolodex.svg | 4 + .../libs/bootstrap-icons/person-square.svg | 4 + .../css/libs/bootstrap-icons/person-video.svg | 4 + .../libs/bootstrap-icons/person-video2.svg | 4 + .../libs/bootstrap-icons/person-video3.svg | 4 + .../libs/bootstrap-icons/person-workspace.svg | 4 + .../libs/bootstrap-icons/person-x-fill.svg | 3 + .../css/libs/bootstrap-icons/person-x.svg | 4 + .../css/libs/bootstrap-icons/person.svg | 3 + .../css/libs/bootstrap-icons/phone-fill.svg | 3 + .../css/libs/bootstrap-icons/phone-flip.svg | 3 + .../bootstrap-icons/phone-landscape-fill.svg | 3 + .../libs/bootstrap-icons/phone-landscape.svg | 4 + .../bootstrap-icons/phone-vibrate-fill.svg | 3 + .../libs/bootstrap-icons/phone-vibrate.svg | 4 + .../css/libs/bootstrap-icons/phone.svg | 4 + .../libs/bootstrap-icons/pie-chart-fill.svg | 3 + .../css/libs/bootstrap-icons/pie-chart.svg | 3 + .../libs/bootstrap-icons/piggy-bank-fill.svg | 3 + .../css/libs/bootstrap-icons/piggy-bank.svg | 4 + .../libs/bootstrap-icons/pin-angle-fill.svg | 3 + .../css/libs/bootstrap-icons/pin-angle.svg | 3 + .../css/libs/bootstrap-icons/pin-fill.svg | 3 + .../css/libs/bootstrap-icons/pin-map-fill.svg | 4 + .../css/libs/bootstrap-icons/pin-map.svg | 4 + .../css/libs/bootstrap-icons/pin.svg | 3 + .../css/libs/bootstrap-icons/pinterest.svg | 3 + .../css/libs/bootstrap-icons/pip-fill.svg | 3 + .../css/libs/bootstrap-icons/pip.svg | 4 + .../libs/bootstrap-icons/play-btn-fill.svg | 3 + .../css/libs/bootstrap-icons/play-btn.svg | 4 + .../libs/bootstrap-icons/play-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/play-circle.svg | 4 + .../css/libs/bootstrap-icons/play-fill.svg | 3 + .../css/libs/bootstrap-icons/play.svg | 3 + .../css/libs/bootstrap-icons/playstation.svg | 3 + .../css/libs/bootstrap-icons/plug-fill.svg | 3 + .../css/libs/bootstrap-icons/plug.svg | 3 + .../css/libs/bootstrap-icons/plugin.svg | 3 + .../bootstrap-icons/plus-circle-dotted.svg | 3 + .../libs/bootstrap-icons/plus-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/plus-circle.svg | 4 + .../css/libs/bootstrap-icons/plus-lg.svg | 3 + .../libs/bootstrap-icons/plus-slash-minus.svg | 3 + .../bootstrap-icons/plus-square-dotted.svg | 3 + .../libs/bootstrap-icons/plus-square-fill.svg | 3 + .../css/libs/bootstrap-icons/plus-square.svg | 4 + .../css/libs/bootstrap-icons/plus.svg | 3 + .../css/libs/bootstrap-icons/postage-fill.svg | 4 + .../bootstrap-icons/postage-heart-fill.svg | 4 + .../libs/bootstrap-icons/postage-heart.svg | 4 + .../css/libs/bootstrap-icons/postage.svg | 4 + .../libs/bootstrap-icons/postcard-fill.svg | 4 + .../bootstrap-icons/postcard-heart-fill.svg | 3 + .../libs/bootstrap-icons/postcard-heart.svg | 4 + .../css/libs/bootstrap-icons/postcard.svg | 3 + .../css/libs/bootstrap-icons/power.svg | 4 + .../css/libs/bootstrap-icons/printer-fill.svg | 4 + .../css/libs/bootstrap-icons/printer.svg | 4 + .../libs/bootstrap-icons/projector-fill.svg | 3 + .../css/libs/bootstrap-icons/projector.svg | 4 + .../css/libs/bootstrap-icons/puzzle-fill.svg | 3 + .../css/libs/bootstrap-icons/puzzle.svg | 3 + .../css/libs/bootstrap-icons/qr-code-scan.svg | 7 + .../css/libs/bootstrap-icons/qr-code.svg | 7 + .../bootstrap-icons/question-circle-fill.svg | 3 + .../libs/bootstrap-icons/question-circle.svg | 4 + .../bootstrap-icons/question-diamond-fill.svg | 3 + .../libs/bootstrap-icons/question-diamond.svg | 4 + .../css/libs/bootstrap-icons/question-lg.svg | 3 + .../bootstrap-icons/question-octagon-fill.svg | 3 + .../libs/bootstrap-icons/question-octagon.svg | 4 + .../bootstrap-icons/question-square-fill.svg | 3 + .../libs/bootstrap-icons/question-square.svg | 4 + .../css/libs/bootstrap-icons/question.svg | 3 + .../css/libs/bootstrap-icons/quora.svg | 3 + .../css/libs/bootstrap-icons/quote.svg | 3 + .../css/libs/bootstrap-icons/radioactive.svg | 4 + .../css/libs/bootstrap-icons/rainbow.svg | 3 + .../libs/bootstrap-icons/receipt-cutoff.svg | 4 + .../css/libs/bootstrap-icons/receipt.svg | 4 + .../css/libs/bootstrap-icons/reception-0.svg | 3 + .../css/libs/bootstrap-icons/reception-1.svg | 3 + .../css/libs/bootstrap-icons/reception-2.svg | 3 + .../css/libs/bootstrap-icons/reception-3.svg | 3 + .../css/libs/bootstrap-icons/reception-4.svg | 3 + .../libs/bootstrap-icons/record-btn-fill.svg | 3 + .../css/libs/bootstrap-icons/record-btn.svg | 4 + .../bootstrap-icons/record-circle-fill.svg | 3 + .../libs/bootstrap-icons/record-circle.svg | 4 + .../css/libs/bootstrap-icons/record-fill.svg | 3 + .../css/libs/bootstrap-icons/record.svg | 3 + .../css/libs/bootstrap-icons/record2-fill.svg | 4 + .../css/libs/bootstrap-icons/record2.svg | 4 + .../css/libs/bootstrap-icons/recycle.svg | 3 + .../css/libs/bootstrap-icons/reddit.svg | 4 + .../libs/bootstrap-icons/reply-all-fill.svg | 4 + .../css/libs/bootstrap-icons/reply-all.svg | 4 + .../css/libs/bootstrap-icons/reply-fill.svg | 3 + .../css/libs/bootstrap-icons/reply.svg | 3 + .../css/libs/bootstrap-icons/robot.svg | 4 + .../css/libs/bootstrap-icons/router-fill.svg | 6 + .../css/libs/bootstrap-icons/router.svg | 6 + .../css/libs/bootstrap-icons/rss-fill.svg | 3 + .../css/libs/bootstrap-icons/rss.svg | 4 + .../css/libs/bootstrap-icons/rulers.svg | 3 + .../css/libs/bootstrap-icons/safe-fill.svg | 4 + .../css/libs/bootstrap-icons/safe.svg | 4 + .../css/libs/bootstrap-icons/safe2-fill.svg | 4 + .../css/libs/bootstrap-icons/safe2.svg | 4 + .../css/libs/bootstrap-icons/save-fill.svg | 3 + .../css/libs/bootstrap-icons/save.svg | 3 + .../css/libs/bootstrap-icons/save2-fill.svg | 3 + .../css/libs/bootstrap-icons/save2.svg | 3 + .../css/libs/bootstrap-icons/scissors.svg | 3 + .../css/libs/bootstrap-icons/screwdriver.svg | 3 + .../css/libs/bootstrap-icons/sd-card-fill.svg | 3 + .../css/libs/bootstrap-icons/sd-card.svg | 4 + .../bootstrap-icons/search-heart-fill.svg | 3 + .../css/libs/bootstrap-icons/search-heart.svg | 4 + .../css/libs/bootstrap-icons/search.svg | 3 + .../libs/bootstrap-icons/segmented-nav.svg | 3 + .../libs/bootstrap-icons/send-check-fill.svg | 4 + .../css/libs/bootstrap-icons/send-check.svg | 4 + .../libs/bootstrap-icons/send-dash-fill.svg | 4 + .../css/libs/bootstrap-icons/send-dash.svg | 4 + .../bootstrap-icons/send-exclamation-fill.svg | 4 + .../libs/bootstrap-icons/send-exclamation.svg | 4 + .../css/libs/bootstrap-icons/send-fill.svg | 3 + .../libs/bootstrap-icons/send-plus-fill.svg | 4 + .../css/libs/bootstrap-icons/send-plus.svg | 4 + .../libs/bootstrap-icons/send-slash-fill.svg | 4 + .../css/libs/bootstrap-icons/send-slash.svg | 4 + .../css/libs/bootstrap-icons/send-x-fill.svg | 4 + .../css/libs/bootstrap-icons/send-x.svg | 4 + .../css/libs/bootstrap-icons/send.svg | 3 + .../css/libs/bootstrap-icons/server.svg | 5 + .../css/libs/bootstrap-icons/share-fill.svg | 3 + .../css/libs/bootstrap-icons/share.svg | 3 + .../css/libs/bootstrap-icons/shield-check.svg | 4 + .../bootstrap-icons/shield-exclamation.svg | 4 + .../bootstrap-icons/shield-fill-check.svg | 3 + .../shield-fill-exclamation.svg | 3 + .../bootstrap-icons/shield-fill-minus.svg | 3 + .../libs/bootstrap-icons/shield-fill-plus.svg | 3 + .../libs/bootstrap-icons/shield-fill-x.svg | 3 + .../css/libs/bootstrap-icons/shield-fill.svg | 3 + .../libs/bootstrap-icons/shield-lock-fill.svg | 3 + .../css/libs/bootstrap-icons/shield-lock.svg | 4 + .../css/libs/bootstrap-icons/shield-minus.svg | 4 + .../css/libs/bootstrap-icons/shield-plus.svg | 4 + .../libs/bootstrap-icons/shield-shaded.svg | 3 + .../bootstrap-icons/shield-slash-fill.svg | 3 + .../css/libs/bootstrap-icons/shield-slash.svg | 3 + .../css/libs/bootstrap-icons/shield-x.svg | 4 + .../css/libs/bootstrap-icons/shield.svg | 3 + .../css/libs/bootstrap-icons/shift-fill.svg | 3 + .../css/libs/bootstrap-icons/shift.svg | 3 + .../css/libs/bootstrap-icons/shop-window.svg | 3 + .../css/libs/bootstrap-icons/shop.svg | 3 + .../css/libs/bootstrap-icons/shuffle.svg | 4 + .../css/libs/bootstrap-icons/signal.svg | 3 + .../libs/bootstrap-icons/signpost-2-fill.svg | 3 + .../css/libs/bootstrap-icons/signpost-2.svg | 3 + .../libs/bootstrap-icons/signpost-fill.svg | 3 + .../bootstrap-icons/signpost-split-fill.svg | 3 + .../libs/bootstrap-icons/signpost-split.svg | 3 + .../css/libs/bootstrap-icons/signpost.svg | 3 + .../css/libs/bootstrap-icons/sim-fill.svg | 4 + .../css/libs/bootstrap-icons/sim.svg | 4 + .../skip-backward-btn-fill.svg | 3 + .../bootstrap-icons/skip-backward-btn.svg | 4 + .../skip-backward-circle-fill.svg | 3 + .../bootstrap-icons/skip-backward-circle.svg | 4 + .../bootstrap-icons/skip-backward-fill.svg | 3 + .../libs/bootstrap-icons/skip-backward.svg | 3 + .../bootstrap-icons/skip-end-btn-fill.svg | 3 + .../css/libs/bootstrap-icons/skip-end-btn.svg | 4 + .../bootstrap-icons/skip-end-circle-fill.svg | 3 + .../libs/bootstrap-icons/skip-end-circle.svg | 4 + .../libs/bootstrap-icons/skip-end-fill.svg | 3 + .../css/libs/bootstrap-icons/skip-end.svg | 3 + .../bootstrap-icons/skip-forward-btn-fill.svg | 3 + .../libs/bootstrap-icons/skip-forward-btn.svg | 4 + .../skip-forward-circle-fill.svg | 3 + .../bootstrap-icons/skip-forward-circle.svg | 4 + .../bootstrap-icons/skip-forward-fill.svg | 3 + .../css/libs/bootstrap-icons/skip-forward.svg | 3 + .../bootstrap-icons/skip-start-btn-fill.svg | 3 + .../libs/bootstrap-icons/skip-start-btn.svg | 4 + .../skip-start-circle-fill.svg | 3 + .../bootstrap-icons/skip-start-circle.svg | 4 + .../libs/bootstrap-icons/skip-start-fill.svg | 3 + .../css/libs/bootstrap-icons/skip-start.svg | 3 + .../css/libs/bootstrap-icons/skype.svg | 3 + .../css/libs/bootstrap-icons/slack.svg | 3 + .../bootstrap-icons/slash-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/slash-circle.svg | 4 + .../css/libs/bootstrap-icons/slash-lg.svg | 3 + .../bootstrap-icons/slash-square-fill.svg | 3 + .../css/libs/bootstrap-icons/slash-square.svg | 4 + .../css/libs/bootstrap-icons/slash.svg | 3 + .../css/libs/bootstrap-icons/sliders.svg | 3 + .../bootstrap-icons/sliders2-vertical.svg | 3 + .../css/libs/bootstrap-icons/sliders2.svg | 3 + .../css/libs/bootstrap-icons/smartwatch.svg | 4 + .../css/libs/bootstrap-icons/snapchat.svg | 3 + .../css/libs/bootstrap-icons/snow.svg | 3 + .../css/libs/bootstrap-icons/snow2.svg | 3 + .../css/libs/bootstrap-icons/snow3.svg | 4 + .../bootstrap-icons/sort-alpha-down-alt.svg | 5 + .../libs/bootstrap-icons/sort-alpha-down.svg | 4 + .../bootstrap-icons/sort-alpha-up-alt.svg | 5 + .../libs/bootstrap-icons/sort-alpha-up.svg | 4 + .../libs/bootstrap-icons/sort-down-alt.svg | 3 + .../css/libs/bootstrap-icons/sort-down.svg | 3 + .../bootstrap-icons/sort-numeric-down-alt.svg | 4 + .../bootstrap-icons/sort-numeric-down.svg | 5 + .../bootstrap-icons/sort-numeric-up-alt.svg | 4 + .../libs/bootstrap-icons/sort-numeric-up.svg | 5 + .../css/libs/bootstrap-icons/sort-up-alt.svg | 3 + .../css/libs/bootstrap-icons/sort-up.svg | 3 + .../css/libs/bootstrap-icons/soundwave.svg | 3 + .../css/libs/bootstrap-icons/speaker-fill.svg | 4 + .../css/libs/bootstrap-icons/speaker.svg | 4 + .../css/libs/bootstrap-icons/speedometer.svg | 4 + .../css/libs/bootstrap-icons/speedometer2.svg | 4 + .../css/libs/bootstrap-icons/spellcheck.svg | 4 + .../css/libs/bootstrap-icons/spotify.svg | 3 + .../css/libs/bootstrap-icons/square-fill.svg | 3 + .../css/libs/bootstrap-icons/square-half.svg | 3 + .../css/libs/bootstrap-icons/square.svg | 3 + .../libs/bootstrap-icons/stack-overflow.svg | 4 + .../css/libs/bootstrap-icons/stack.svg | 4 + .../css/libs/bootstrap-icons/star-fill.svg | 3 + .../css/libs/bootstrap-icons/star-half.svg | 3 + .../css/libs/bootstrap-icons/star.svg | 3 + .../css/libs/bootstrap-icons/stars.svg | 3 + .../css/libs/bootstrap-icons/steam.svg | 4 + .../libs/bootstrap-icons/stickies-fill.svg | 4 + .../css/libs/bootstrap-icons/stickies.svg | 4 + .../css/libs/bootstrap-icons/sticky-fill.svg | 3 + .../css/libs/bootstrap-icons/sticky.svg | 3 + .../libs/bootstrap-icons/stop-btn-fill.svg | 3 + .../css/libs/bootstrap-icons/stop-btn.svg | 4 + .../libs/bootstrap-icons/stop-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/stop-circle.svg | 4 + .../css/libs/bootstrap-icons/stop-fill.svg | 3 + .../css/libs/bootstrap-icons/stop.svg | 3 + .../libs/bootstrap-icons/stoplights-fill.svg | 3 + .../css/libs/bootstrap-icons/stoplights.svg | 4 + .../libs/bootstrap-icons/stopwatch-fill.svg | 3 + .../css/libs/bootstrap-icons/stopwatch.svg | 4 + .../css/libs/bootstrap-icons/strava.svg | 3 + .../css/libs/bootstrap-icons/subtract.svg | 3 + .../libs/bootstrap-icons/suit-club-fill.svg | 3 + .../css/libs/bootstrap-icons/suit-club.svg | 3 + .../bootstrap-icons/suit-diamond-fill.svg | 3 + .../css/libs/bootstrap-icons/suit-diamond.svg | 3 + .../libs/bootstrap-icons/suit-heart-fill.svg | 3 + .../css/libs/bootstrap-icons/suit-heart.svg | 3 + .../libs/bootstrap-icons/suit-spade-fill.svg | 3 + .../css/libs/bootstrap-icons/suit-spade.svg | 3 + .../css/libs/bootstrap-icons/sun-fill.svg | 3 + .../css/libs/bootstrap-icons/sun.svg | 3 + .../css/libs/bootstrap-icons/sunglasses.svg | 3 + .../css/libs/bootstrap-icons/sunrise-fill.svg | 3 + .../css/libs/bootstrap-icons/sunrise.svg | 3 + .../css/libs/bootstrap-icons/sunset-fill.svg | 3 + .../css/libs/bootstrap-icons/sunset.svg | 3 + .../bootstrap-icons/symmetry-horizontal.svg | 3 + .../bootstrap-icons/symmetry-vertical.svg | 3 + .../css/libs/bootstrap-icons/table.svg | 3 + .../css/libs/bootstrap-icons/tablet-fill.svg | 3 + .../bootstrap-icons/tablet-landscape-fill.svg | 3 + .../libs/bootstrap-icons/tablet-landscape.svg | 4 + .../css/libs/bootstrap-icons/tablet.svg | 4 + .../css/libs/bootstrap-icons/tag-fill.svg | 3 + .../css/libs/bootstrap-icons/tag.svg | 4 + .../css/libs/bootstrap-icons/tags-fill.svg | 4 + .../css/libs/bootstrap-icons/tags.svg | 4 + .../css/libs/bootstrap-icons/telegram.svg | 3 + .../libs/bootstrap-icons/telephone-fill.svg | 3 + .../telephone-forward-fill.svg | 3 + .../bootstrap-icons/telephone-forward.svg | 3 + .../telephone-inbound-fill.svg | 3 + .../bootstrap-icons/telephone-inbound.svg | 3 + .../bootstrap-icons/telephone-minus-fill.svg | 3 + .../libs/bootstrap-icons/telephone-minus.svg | 4 + .../telephone-outbound-fill.svg | 3 + .../bootstrap-icons/telephone-outbound.svg | 3 + .../bootstrap-icons/telephone-plus-fill.svg | 3 + .../libs/bootstrap-icons/telephone-plus.svg | 4 + .../libs/bootstrap-icons/telephone-x-fill.svg | 3 + .../css/libs/bootstrap-icons/telephone-x.svg | 4 + .../css/libs/bootstrap-icons/telephone.svg | 3 + .../libs/bootstrap-icons/terminal-dash.svg | 4 + .../libs/bootstrap-icons/terminal-fill.svg | 3 + .../libs/bootstrap-icons/terminal-plus.svg | 4 + .../libs/bootstrap-icons/terminal-split.svg | 4 + .../css/libs/bootstrap-icons/terminal-x.svg | 4 + .../css/libs/bootstrap-icons/terminal.svg | 4 + .../css/libs/bootstrap-icons/text-center.svg | 3 + .../libs/bootstrap-icons/text-indent-left.svg | 3 + .../bootstrap-icons/text-indent-right.svg | 3 + .../css/libs/bootstrap-icons/text-left.svg | 3 + .../libs/bootstrap-icons/text-paragraph.svg | 3 + .../css/libs/bootstrap-icons/text-right.svg | 3 + .../libs/bootstrap-icons/textarea-resize.svg | 3 + .../css/libs/bootstrap-icons/textarea-t.svg | 4 + .../css/libs/bootstrap-icons/textarea.svg | 3 + .../libs/bootstrap-icons/thermometer-half.svg | 4 + .../libs/bootstrap-icons/thermometer-high.svg | 4 + .../libs/bootstrap-icons/thermometer-low.svg | 4 + .../libs/bootstrap-icons/thermometer-snow.svg | 4 + .../libs/bootstrap-icons/thermometer-sun.svg | 4 + .../css/libs/bootstrap-icons/thermometer.svg | 4 + .../bootstrap-icons/three-dots-vertical.svg | 3 + .../css/libs/bootstrap-icons/three-dots.svg | 3 + .../libs/bootstrap-icons/thunderbolt-fill.svg | 3 + .../css/libs/bootstrap-icons/thunderbolt.svg | 4 + .../bootstrap-icons/ticket-detailed-fill.svg | 3 + .../libs/bootstrap-icons/ticket-detailed.svg | 4 + .../css/libs/bootstrap-icons/ticket-fill.svg | 3 + .../ticket-perforated-fill.svg | 3 + .../bootstrap-icons/ticket-perforated.svg | 4 + .../css/libs/bootstrap-icons/ticket.svg | 3 + .../css/libs/bootstrap-icons/tiktok.svg | 3 + .../css/libs/bootstrap-icons/toggle-off.svg | 3 + .../css/libs/bootstrap-icons/toggle-on.svg | 3 + .../css/libs/bootstrap-icons/toggle2-off.svg | 4 + .../css/libs/bootstrap-icons/toggle2-on.svg | 4 + .../css/libs/bootstrap-icons/toggles.svg | 3 + .../css/libs/bootstrap-icons/toggles2.svg | 5 + .../css/libs/bootstrap-icons/tools.svg | 3 + .../css/libs/bootstrap-icons/tornado.svg | 3 + .../css/libs/bootstrap-icons/translate.svg | 4 + .../css/libs/bootstrap-icons/trash-fill.svg | 3 + .../css/libs/bootstrap-icons/trash.svg | 4 + .../css/libs/bootstrap-icons/trash2-fill.svg | 3 + .../css/libs/bootstrap-icons/trash2.svg | 3 + .../css/libs/bootstrap-icons/trash3-fill.svg | 3 + .../css/libs/bootstrap-icons/trash3.svg | 3 + .../css/libs/bootstrap-icons/tree-fill.svg | 3 + .../css/libs/bootstrap-icons/tree.svg | 3 + .../libs/bootstrap-icons/triangle-fill.svg | 3 + .../libs/bootstrap-icons/triangle-half.svg | 3 + .../css/libs/bootstrap-icons/triangle.svg | 3 + .../css/libs/bootstrap-icons/trophy-fill.svg | 3 + .../css/libs/bootstrap-icons/trophy.svg | 3 + .../libs/bootstrap-icons/tropical-storm.svg | 4 + .../libs/bootstrap-icons/truck-flatbed.svg | 3 + .../css/libs/bootstrap-icons/truck.svg | 3 + .../css/libs/bootstrap-icons/tsunami.svg | 3 + .../css/libs/bootstrap-icons/tv-fill.svg | 3 + .../resources/css/libs/bootstrap-icons/tv.svg | 3 + .../css/libs/bootstrap-icons/twitch.svg | 4 + .../css/libs/bootstrap-icons/twitter.svg | 3 + .../css/libs/bootstrap-icons/type-bold.svg | 3 + .../css/libs/bootstrap-icons/type-h1.svg | 3 + .../css/libs/bootstrap-icons/type-h2.svg | 3 + .../css/libs/bootstrap-icons/type-h3.svg | 3 + .../css/libs/bootstrap-icons/type-italic.svg | 3 + .../bootstrap-icons/type-strikethrough.svg | 3 + .../libs/bootstrap-icons/type-underline.svg | 3 + .../css/libs/bootstrap-icons/type.svg | 3 + .../libs/bootstrap-icons/ui-checks-grid.svg | 3 + .../css/libs/bootstrap-icons/ui-checks.svg | 3 + .../libs/bootstrap-icons/ui-radios-grid.svg | 3 + .../css/libs/bootstrap-icons/ui-radios.svg | 3 + .../libs/bootstrap-icons/umbrella-fill.svg | 3 + .../css/libs/bootstrap-icons/umbrella.svg | 3 + .../css/libs/bootstrap-icons/union.svg | 3 + .../css/libs/bootstrap-icons/unlock-fill.svg | 3 + .../css/libs/bootstrap-icons/unlock.svg | 3 + .../css/libs/bootstrap-icons/upc-scan.svg | 3 + .../css/libs/bootstrap-icons/upc.svg | 3 + .../css/libs/bootstrap-icons/upload.svg | 4 + .../css/libs/bootstrap-icons/usb-c-fill.svg | 3 + .../css/libs/bootstrap-icons/usb-c.svg | 4 + .../libs/bootstrap-icons/usb-drive-fill.svg | 3 + .../css/libs/bootstrap-icons/usb-drive.svg | 3 + .../css/libs/bootstrap-icons/usb-fill.svg | 3 + .../libs/bootstrap-icons/usb-micro-fill.svg | 3 + .../css/libs/bootstrap-icons/usb-micro.svg | 4 + .../libs/bootstrap-icons/usb-mini-fill.svg | 3 + .../css/libs/bootstrap-icons/usb-mini.svg | 4 + .../libs/bootstrap-icons/usb-plug-fill.svg | 3 + .../css/libs/bootstrap-icons/usb-plug.svg | 3 + .../css/libs/bootstrap-icons/usb-symbol.svg | 3 + .../css/libs/bootstrap-icons/usb.svg | 4 + .../css/libs/bootstrap-icons/valentine.svg | 4 + .../css/libs/bootstrap-icons/valentine2.svg | 4 + .../css/libs/bootstrap-icons/vector-pen.svg | 4 + .../css/libs/bootstrap-icons/view-list.svg | 3 + .../css/libs/bootstrap-icons/view-stacked.svg | 3 + .../css/libs/bootstrap-icons/vimeo.svg | 3 + .../css/libs/bootstrap-icons/vinyl-fill.svg | 4 + .../css/libs/bootstrap-icons/vinyl.svg | 5 + .../css/libs/bootstrap-icons/voicemail.svg | 3 + .../libs/bootstrap-icons/volume-down-fill.svg | 3 + .../css/libs/bootstrap-icons/volume-down.svg | 3 + .../libs/bootstrap-icons/volume-mute-fill.svg | 3 + .../css/libs/bootstrap-icons/volume-mute.svg | 3 + .../libs/bootstrap-icons/volume-off-fill.svg | 3 + .../css/libs/bootstrap-icons/volume-off.svg | 3 + .../libs/bootstrap-icons/volume-up-fill.svg | 5 + .../css/libs/bootstrap-icons/volume-up.svg | 5 + .../resources/css/libs/bootstrap-icons/vr.svg | 3 + .../css/libs/bootstrap-icons/wallet-fill.svg | 4 + .../css/libs/bootstrap-icons/wallet.svg | 3 + .../css/libs/bootstrap-icons/wallet2.svg | 3 + .../css/libs/bootstrap-icons/watch.svg | 4 + .../css/libs/bootstrap-icons/water.svg | 3 + .../css/libs/bootstrap-icons/webcam-fill.svg | 4 + .../css/libs/bootstrap-icons/webcam.svg | 4 + .../css/libs/bootstrap-icons/whatsapp.svg | 3 + .../css/libs/bootstrap-icons/wifi-1.svg | 3 + .../css/libs/bootstrap-icons/wifi-2.svg | 3 + .../css/libs/bootstrap-icons/wifi-off.svg | 3 + .../css/libs/bootstrap-icons/wifi.svg | 4 + .../css/libs/bootstrap-icons/wind.svg | 3 + .../css/libs/bootstrap-icons/window-dash.svg | 5 + .../libs/bootstrap-icons/window-desktop.svg | 4 + .../css/libs/bootstrap-icons/window-dock.svg | 4 + .../bootstrap-icons/window-fullscreen.svg | 4 + .../css/libs/bootstrap-icons/window-plus.svg | 5 + .../libs/bootstrap-icons/window-sidebar.svg | 4 + .../css/libs/bootstrap-icons/window-split.svg | 4 + .../css/libs/bootstrap-icons/window-stack.svg | 4 + .../css/libs/bootstrap-icons/window-x.svg | 5 + .../css/libs/bootstrap-icons/window.svg | 4 + .../css/libs/bootstrap-icons/windows.svg | 3 + .../css/libs/bootstrap-icons/wordpress.svg | 5 + .../wrench-adjustable-circle-fill.svg | 4 + .../wrench-adjustable-circle.svg | 4 + .../bootstrap-icons/wrench-adjustable.svg | 4 + .../css/libs/bootstrap-icons/wrench.svg | 3 + .../libs/bootstrap-icons/x-circle-fill.svg | 3 + .../css/libs/bootstrap-icons/x-circle.svg | 4 + .../libs/bootstrap-icons/x-diamond-fill.svg | 3 + .../css/libs/bootstrap-icons/x-diamond.svg | 3 + .../css/libs/bootstrap-icons/x-lg.svg | 3 + .../libs/bootstrap-icons/x-octagon-fill.svg | 3 + .../css/libs/bootstrap-icons/x-octagon.svg | 4 + .../libs/bootstrap-icons/x-square-fill.svg | 3 + .../css/libs/bootstrap-icons/x-square.svg | 4 + .../resources/css/libs/bootstrap-icons/x.svg | 3 + .../css/libs/bootstrap-icons/xbox.svg | 3 + .../css/libs/bootstrap-icons/yin-yang.svg | 4 + .../css/libs/bootstrap-icons/youtube.svg | 3 + .../css/libs/bootstrap-icons/zoom-in.svg | 5 + .../css/libs/bootstrap-icons/zoom-out.svg | 5 + .../css/libs/bootstrap5/bootstrap.min.css | 6 + .../css/libs/bootstrap5/bootstrap.min.css.map | 1 + .../context_path/resources/css/main.css | 48 + .../context_path/resources/css/overrides.css | 29 + .../newton/context_path/resources/js/ajax.js | 43 + .../context_path/resources/js/context-menu.js | 28 + .../context_path/resources/js/events.js | 21 + .../context_path/resources/js/globals.js | 4 + .../libs/bootstrap5/bootstrap.bundle.min.js | 7 + .../bootstrap5/bootstrap.bundle.min.js.map | 1 + .../resources/js/libs/jquery-3.7.1.min.js | 2 + .../context_path/resources/js/post-ajax.js | 11 + .../context_path/resources/js/ui-logic.js | 6 + .../newton/context_path/resources/js/utils.js | 102 + .../usr/share/newton/icons/archive.png | Bin 0 -> 1670 bytes user_config/usr/share/newton/icons/audio.png | Bin 0 -> 1544 bytes user_config/usr/share/newton/icons/bin.png | Bin 0 -> 858 bytes user_config/usr/share/newton/icons/brain.png | Bin 0 -> 26603 bytes user_config/usr/share/newton/icons/dir.png | Bin 0 -> 850 bytes user_config/usr/share/newton/icons/doc.png | Bin 0 -> 702 bytes user_config/usr/share/newton/icons/image.png | Bin 0 -> 6591 bytes .../usr/share/newton/icons/newton-64x64.png | Bin 0 -> 18327 bytes user_config/usr/share/newton/icons/newton.png | Bin 0 -> 8966 bytes .../share/newton/icons/only-in-selection.png | Bin 0 -> 6270 bytes user_config/usr/share/newton/icons/pdf.png | Bin 0 -> 925 bytes .../usr/share/newton/icons/presentation.png | Bin 0 -> 882 bytes .../usr/share/newton/icons/spreadsheet.png | Bin 0 -> 707 bytes user_config/usr/share/newton/icons/text.png | Bin 0 -> 798 bytes user_config/usr/share/newton/icons/trash.png | Bin 0 -> 989 bytes user_config/usr/share/newton/icons/video.png | Bin 0 -> 1313 bytes user_config/usr/share/newton/icons/web.png | Bin 0 -> 1845 bytes .../usr/share/newton/icons/whole-word.png | Bin 0 -> 6651 bytes .../usr/share/newton/key-bindings.json | 12 + user_config/usr/share/newton/stylesheet.css | 448 ++ 1930 files changed, 37547 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 plugins/README.txt create mode 100644 plugins/autopairs/__init__.py create mode 100644 plugins/autopairs/__main__.py create mode 100644 plugins/autopairs/manifest.json create mode 100644 plugins/autopairs/plugin.py create mode 100644 plugins/colorize/__init__.py create mode 100644 plugins/colorize/__main__.py create mode 100644 plugins/colorize/color_converter_mixin.py create mode 100644 plugins/colorize/manifest.json create mode 100644 plugins/colorize/plugin.py create mode 100644 plugins/commentzar/__init__.py create mode 100644 plugins/commentzar/__main__.py create mode 100755 plugins/commentzar/add_comment_mixin.py create mode 100755 plugins/commentzar/codecomment_tags.py create mode 100644 plugins/commentzar/manifest.json create mode 100644 plugins/commentzar/plugin.py create mode 100755 plugins/commentzar/remove_comment_mixin.py create mode 100644 plugins/lsp_client/__init__.py create mode 100644 plugins/lsp_client/__main__.py create mode 100644 plugins/lsp_client/client_ipc.py create mode 100644 plugins/lsp_client/config.json create mode 100644 plugins/lsp_client/lsp_message_structs.py create mode 100644 plugins/lsp_client/manifest.json create mode 100644 plugins/lsp_client/plugin.py create mode 100644 plugins/markdown_preview/__init__.py create mode 100644 plugins/markdown_preview/__main__.py create mode 100644 plugins/markdown_preview/manifest.json create mode 100644 plugins/markdown_preview/markdown/__init__.py create mode 100644 plugins/markdown_preview/markdown/__main__.py create mode 100644 plugins/markdown_preview/markdown/__meta__.py create mode 100644 plugins/markdown_preview/markdown/blockparser.py create mode 100644 plugins/markdown_preview/markdown/blockprocessors.py create mode 100644 plugins/markdown_preview/markdown/core.py create mode 100644 plugins/markdown_preview/markdown/extensions/__init__.py create mode 100644 plugins/markdown_preview/markdown/extensions/abbr.py create mode 100644 plugins/markdown_preview/markdown/extensions/admonition.py create mode 100644 plugins/markdown_preview/markdown/extensions/attr_list.py create mode 100644 plugins/markdown_preview/markdown/extensions/codehilite.py create mode 100644 plugins/markdown_preview/markdown/extensions/def_list.py create mode 100644 plugins/markdown_preview/markdown/extensions/extra.py create mode 100644 plugins/markdown_preview/markdown/extensions/fenced_code.py create mode 100644 plugins/markdown_preview/markdown/extensions/footnotes.py create mode 100644 plugins/markdown_preview/markdown/extensions/legacy_attrs.py create mode 100644 plugins/markdown_preview/markdown/extensions/legacy_em.py create mode 100644 plugins/markdown_preview/markdown/extensions/md_in_html.py create mode 100644 plugins/markdown_preview/markdown/extensions/meta.py create mode 100644 plugins/markdown_preview/markdown/extensions/nl2br.py create mode 100644 plugins/markdown_preview/markdown/extensions/sane_lists.py create mode 100644 plugins/markdown_preview/markdown/extensions/smarty.py create mode 100644 plugins/markdown_preview/markdown/extensions/tables.py create mode 100644 plugins/markdown_preview/markdown/extensions/toc.py create mode 100644 plugins/markdown_preview/markdown/extensions/wikilinks.py create mode 100644 plugins/markdown_preview/markdown/htmlparser.py create mode 100644 plugins/markdown_preview/markdown/inlinepatterns.py create mode 100644 plugins/markdown_preview/markdown/postprocessors.py create mode 100644 plugins/markdown_preview/markdown/preprocessors.py create mode 100644 plugins/markdown_preview/markdown/serializers.py create mode 100644 plugins/markdown_preview/markdown/test_tools.py create mode 100644 plugins/markdown_preview/markdown/treeprocessors.py create mode 100644 plugins/markdown_preview/markdown/util.py create mode 100644 plugins/markdown_preview/markdown_preview.glade create mode 100644 plugins/markdown_preview/markdown_template_mixin.py create mode 100644 plugins/markdown_preview/plugin.py create mode 100644 plugins/search_replace/__init__.py create mode 100644 plugins/search_replace/__main__.py create mode 100644 plugins/search_replace/manifest.json create mode 100644 plugins/search_replace/plugin.py create mode 100644 plugins/search_replace/replace_mixin.py create mode 100644 plugins/search_replace/search_replace.glade create mode 100644 plugins/search_replace/styling_mixin.py create mode 100644 plugins/template/__init__.py create mode 100644 plugins/template/__main__.py create mode 100644 plugins/template/manifest.json create mode 100644 plugins/template/plugin.py create mode 100644 pyrightconfig.json create mode 100644 requirements.txt create mode 100644 src/__builtins__.py create mode 100644 src/__init__.py create mode 100644 src/__main__.py create mode 100644 src/app.py create mode 100644 src/core/__init__.py create mode 100644 src/core/builder_wrapper.py create mode 100644 src/core/containers/base_container.py create mode 100644 src/core/containers/body_container.py create mode 100644 src/core/containers/center_container.py create mode 100644 src/core/containers/code/__init__.py create mode 100644 src/core/containers/code/code_container.py create mode 100644 src/core/containers/code/editors_container.py create mode 100644 src/core/containers/code/paned_editors_container.py create mode 100644 src/core/containers/footer_container.py create mode 100644 src/core/containers/header_container.py create mode 100644 src/core/containers/left_container.py create mode 100644 src/core/containers/right_container.py create mode 100644 src/core/controllers/__init__.py create mode 100644 src/core/controllers/base_controller.py create mode 100644 src/core/controllers/base_controller_data.py create mode 100644 src/core/controllers/bridge_controller.py create mode 100644 src/core/widgets/__init__.py create mode 100644 src/core/widgets/code/__init__.py create mode 100644 src/core/widgets/code/command_system.py create mode 100644 src/core/widgets/code/commands/__init__.py create mode 100644 src/core/widgets/code/commands/buffer_redo.py create mode 100644 src/core/widgets/code/commands/buffer_undo.py create mode 100644 src/core/widgets/code/commands/close_file.py create mode 100644 src/core/widgets/code/commands/cut_to_temp_buffer.py create mode 100644 src/core/widgets/code/commands/dnd_load_file_to_buffer.py create mode 100644 src/core/widgets/code/commands/dnd_load_files.py create mode 100644 src/core/widgets/code/commands/duplicate_line.py create mode 100644 src/core/widgets/code/commands/focus_left_sibling.py create mode 100644 src/core/widgets/code/commands/focus_right_sibling.py create mode 100644 src/core/widgets/code/commands/get_current_file.py create mode 100644 src/core/widgets/code/commands/get_filetype.py create mode 100644 src/core/widgets/code/commands/get_text.py create mode 100644 src/core/widgets/code/commands/go_to.py create mode 100644 src/core/widgets/code/commands/has_focus.py create mode 100644 src/core/widgets/code/commands/line_down.py create mode 100644 src/core/widgets/code/commands/line_up.py create mode 100644 src/core/widgets/code/commands/load_file.py create mode 100644 src/core/widgets/code/commands/load_start_files.py create mode 100644 src/core/widgets/code/commands/move_to_left_sibling.py create mode 100644 src/core/widgets/code/commands/move_to_right_sibling.py create mode 100644 src/core/widgets/code/commands/new_file.py create mode 100644 src/core/widgets/code/commands/open_files.py create mode 100644 src/core/widgets/code/commands/paste_temp_buffer.py create mode 100644 src/core/widgets/code/commands/save_file.py create mode 100644 src/core/widgets/code/commands/save_file_as.py create mode 100644 src/core/widgets/code/commands/set_buffer.py create mode 100644 src/core/widgets/code/commands/set_buffer_language.py create mode 100644 src/core/widgets/code/commands/set_buffer_style.py create mode 100644 src/core/widgets/code/commands/set_focus_border.py create mode 100644 src/core/widgets/code/commands/set_miniview.py create mode 100644 src/core/widgets/code/commands/show_completion.py create mode 100644 src/core/widgets/code/commands/update_info_bar.py create mode 100644 src/core/widgets/code/commands/zoom_in.py create mode 100644 src/core/widgets/code/commands/zoom_out.py create mode 100644 src/core/widgets/code/completion_manager.py create mode 100644 src/core/widgets/code/completion_providers/__init__.py create mode 100644 src/core/widgets/code/completion_providers/example_completion_provider.py create mode 100644 src/core/widgets/code/completion_providers/lsp_completion_provider.py create mode 100644 src/core/widgets/code/completion_providers/python_completion_provider.py create mode 100644 src/core/widgets/code/general_info_widget.py create mode 100644 src/core/widgets/code/key_mapper.py create mode 100644 src/core/widgets/code/miniview_widget.py create mode 100644 src/core/widgets/code/mixins/__init__.py create mode 100644 src/core/widgets/code/mixins/source_view_dnd_mixin.py create mode 100644 src/core/widgets/code/mixins/source_view_events_mixin.py create mode 100644 src/core/widgets/code/source_buffer.py create mode 100644 src/core/widgets/code/source_file.py create mode 100644 src/core/widgets/code/source_files_manager.py create mode 100644 src/core/widgets/code/tab_widget.py create mode 100644 src/core/widgets/code/tabs_widget.py create mode 100644 src/core/widgets/code/view.py create mode 100644 src/core/widgets/controls/__init__.py create mode 100644 src/core/widgets/controls/open_files_button.py create mode 100644 src/core/widgets/controls/save_as_button.py create mode 100644 src/core/widgets/controls/transparency_scale.py create mode 100644 src/core/widgets/save_file_dialog.py create mode 100644 src/core/widgets/separator_widget.py create mode 100644 src/core/widgets/vte_widget.py create mode 100644 src/core/widgets/webkit/__init__.py create mode 100644 src/core/widgets/webkit/webkit_ui.py create mode 100644 src/core/window.py create mode 100644 src/libs/__init__.py create mode 100644 src/libs/db/__init__.py create mode 100644 src/libs/db/db.py create mode 100644 src/libs/db/models.py create mode 100644 src/libs/debugging.py create mode 100644 src/libs/dto/__init__.py create mode 100644 src/libs/dto/code_event.py create mode 100644 src/libs/dto/event.py create mode 100644 src/libs/dto/observable_event.py create mode 100644 src/libs/endpoint_registry.py create mode 100644 src/libs/event_system.py create mode 100644 src/libs/ipc_server.py create mode 100644 src/libs/keybindings.py create mode 100644 src/libs/logger.py create mode 100644 src/libs/mixins/__init__.py create mode 100644 src/libs/mixins/dnd_mixin.py create mode 100644 src/libs/mixins/ipc_signals_mixin.py create mode 100644 src/libs/mixins/keyboard_signals_mixin.py create mode 100644 src/libs/mixins/observable_mixin.py create mode 100644 src/libs/settings/__init__.py create mode 100644 src/libs/settings/manager.py create mode 100644 src/libs/settings/options/__init__.py create mode 100644 src/libs/settings/options/config.py create mode 100644 src/libs/settings/options/debugging.py create mode 100644 src/libs/settings/options/filters.py create mode 100644 src/libs/settings/options/settings.py create mode 100644 src/libs/settings/options/theming.py create mode 100644 src/libs/settings/other/__init__.py create mode 100644 src/libs/settings/other/webkit_ui_settings.py create mode 100644 src/libs/settings/path_manager.py create mode 100644 src/libs/settings/start_check_mixin.py create mode 100644 src/libs/singleton.py create mode 100644 src/libs/singleton_raised.py create mode 100644 src/libs/status_icon.py create mode 100644 src/plugins/__init__.py create mode 100644 src/plugins/dto/__init__.py create mode 100644 src/plugins/dto/manifest.py create mode 100644 src/plugins/dto/manifest_meta.py create mode 100644 src/plugins/dto/requests.py create mode 100644 src/plugins/manifest_manager.py create mode 100644 src/plugins/plugin_base.py create mode 100644 src/plugins/plugin_reload_mixin.py create mode 100644 src/plugins/plugins_controller.py create mode 100755 user_config/bin/ create mode 100644 user_config/usr/applications/newton.desktop create mode 100644 user_config/usr/share/newton/Main_Window.glade create mode 100644 user_config/usr/share/newton/code-key-bindings.json create mode 100644 user_config/usr/share/newton/code_styles/catppuccin-frappe.xml create mode 100644 user_config/usr/share/newton/code_styles/catppuccin-latte.xml create mode 100644 user_config/usr/share/newton/code_styles/catppuccin-macchiato.xml create mode 100644 user_config/usr/share/newton/code_styles/catppuccin-mocha.xml create mode 100644 user_config/usr/share/newton/code_styles/peacocks-in-space.xml create mode 100644 user_config/usr/share/newton/code_styles/penguins-in-space.xml create mode 100644 user_config/usr/share/newton/contexct_menu.json create mode 100644 user_config/usr/share/newton/context_path/index.html create mode 100644 user_config/usr/share/newton/context_path/resources/css/context-menu.css create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/123.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/activity.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/alarm-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/alarm.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-bottom.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-center.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-end.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-middle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-start.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/align-top.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/app-indicator.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/app.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/apple.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/archive-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/archive.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-90deg-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-90deg-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-90deg-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-90deg-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-bar-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-bar-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-bar-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-bar-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-clockwise.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-counterclockwise.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-left-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-left-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-left-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-left-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-right-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-right-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-right-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-right-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-short.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-short.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-repeat.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-return-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-return-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right-short.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-through-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-through-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-left-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-left-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-left-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-left-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-right-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-right-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-right-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-right-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-short.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-angle-contract.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-angle-expand.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-collapse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-expand.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-fullscreen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/arrows-move.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/aspect-ratio-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/aspect-ratio.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/asterisk.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/at.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/award-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/award.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/back.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/backspace-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/backspace-reverse-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/backspace-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/backspace.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-3d-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-3d.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-4k-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-4k.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-8k-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-8k.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-ad-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-ad.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-ar-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-ar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-cc-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-cc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-hd-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-hd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-sd-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-sd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-tm-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-tm.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-vo-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-vo.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-vr-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-vr.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-wc-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/badge-wc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bag.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/balloon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/balloon-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/balloon-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/balloon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bandaid-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bandaid.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bank.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bank2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bar-chart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bar-chart-line-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bar-chart-line.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bar-chart-steps.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bar-chart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/basket3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/battery-charging.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/battery-full.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/battery-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/battery.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/behance.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bell-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bell-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bell-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bell.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bezier.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bezier2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bicycle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/binoculars-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/binoculars.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/blockquote-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/blockquote-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bluetooth.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/body-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/book-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/book-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/book.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-star-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-star.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmark.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmarks-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookmarks.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bookshelf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/boombox-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/boombox.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-icons.css create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-icons.json create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-icons.scss create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-icons.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap-reboot.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bootstrap.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-all.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-bottom.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-center.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-inner.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-middle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-outer.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-style.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-top.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border-width.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/border.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bounding-box-circles.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bounding-box.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-down-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-down-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-down-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-down-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-up-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-up-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-in-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-up-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-up-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box-seam.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box2-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box2-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/box2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/boxes.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/braces-asterisk.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/braces.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bricks.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/briefcase-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/briefcase.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-alt-high-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-alt-high.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-alt-low-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-alt-low.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-high-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-high.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-low-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brightness-low.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/broadcast-pin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/broadcast.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brush-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/brush.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bucket-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bucket.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bug-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bug.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/building.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/bullseye.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calculator-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calculator.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-date-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-date.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-day-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-day.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-event-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-event.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-month-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-month.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-range-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-range.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-week-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-week.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-date-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-date.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-day-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-day.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-event-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-event.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-month-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-month.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-range-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-range.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-week-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-week.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-event-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-event.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-range-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-range.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-week-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3-week.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar4-event.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar4-range.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar4-week.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/calendar4.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-reels-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-reels.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-video-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-video-off-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-video-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera-video.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/camera2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/capslock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/capslock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/card-checklist.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/card-heading.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/card-image.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/card-list.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/card-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-down-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-down-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-left-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-left-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-left-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-right-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-right-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-right-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-up-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-up-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/caret-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cart4.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cash-coin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cash-stack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cast.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-dots-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-dots.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-dots-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-dots.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-quote-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-quote.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-quote-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-quote.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-dots-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-dots.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-quote-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-quote.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-dots-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-dots.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-quote-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-quote.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chat.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-all.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check2-all.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check2-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check2-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/check2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-contract.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-expand.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-bar-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-compact-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-compact-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-compact-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-compact-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-contract.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-double-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-double-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-double-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-double-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-expand.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/chevron-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/circle-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/circle-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-data-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-data.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-pulse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-data-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-data.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-pulse-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-pulse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clipboard2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clock-history.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-arrow-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-arrow-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-download-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-download.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-drizzle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-drizzle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-fog-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-fog.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-fog2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-fog2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-hail-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-hail.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-haze-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-haze.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-haze2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-haze2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-lightning-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-lightning-rain-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-lightning-rain.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-lightning.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-moon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-moon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-rain-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-rain-heavy-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-rain-heavy.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-rain.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-sleet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-sleet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-snow-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-snow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-sun-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-sun.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-upload-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud-upload.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloud.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clouds-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/clouds.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloudy-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cloudy.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/code-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/code-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/code.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/coin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/collection-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/collection-play-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/collection-play.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/collection.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/columns-gap.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/columns.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/command.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/compass-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/compass.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cone-striped.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cone.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/controller.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cpu-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cpu.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card-2-back-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card-2-back.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card-2-front-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card-2-front.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/credit-card.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/crop.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cup-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cup-straw.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cup.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-bitcoin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-dollar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-euro.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-exchange.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-pound.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/currency-yen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cursor-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cursor-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/cursor.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-circle-dotted.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-square-dotted.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/device-hdd-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/device-hdd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/device-ssd-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/device-ssd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diagram-2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diagram-2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diagram-3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diagram-3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diamond-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diamond-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/diamond.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-1-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-1.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-4-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-4.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-5-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-5.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-6-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dice-6.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/disc-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/disc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/discord.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/display-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/display.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/displayport-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/displayport.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/distribute-horizontal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/distribute-vertical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/door-closed-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/door-closed.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/door-open-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/door-open.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dot.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/download.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dpad-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dpad.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/dribbble.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/droplet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/droplet-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/droplet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ear-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ear.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/earbuds.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/easel3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/egg-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/egg-fried.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/egg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eject-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eject.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-angry-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-angry.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-dizzy-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-dizzy.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-expressionless-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-expressionless.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-frown-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-frown.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-heart-eyes-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-heart-eyes.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-kiss-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-kiss.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-laughing-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-laughing.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-neutral-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-neutral.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-smile-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-smile-upside-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-smile-upside-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-smile.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-sunglasses-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-sunglasses.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-wink-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/emoji-wink.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-exclamation-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-open-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-open-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-open-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-open.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-paper-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-paper-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-paper-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-paper.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/envelope.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eraser-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eraser.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ethernet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-diamond-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-diamond.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-octagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-octagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-triangle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation-triangle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/exclude.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/explicit-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/explicit.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eye-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eye-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eye-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eye.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eyedropper.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/eyeglasses.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/facebook.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fan.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-arrow-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-arrow-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-bar-graph-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-bar-graph.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-binary-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-binary.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-break-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-break.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-code-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-code.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-diff-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-diff.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-arrow-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-arrow-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-bar-graph-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-bar-graph.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-binary-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-binary.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-break-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-break.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-code-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-code.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-diff-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-diff.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-easel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-easel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-excel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-excel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-font-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-font.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-image-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-image.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-lock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-lock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-lock2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-lock2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-medical-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-medical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-music-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-music.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-pdf-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-pdf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-person-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-person.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-play-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-play.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-post-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-post.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-ppt-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-ppt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-richtext-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-richtext.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-ruled-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-ruled.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-slides-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-slides.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-spreadsheet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-spreadsheet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-word-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-word.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-zip-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark-zip.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-earmark.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-easel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-easel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-excel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-excel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-font-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-font.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-image-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-image.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-lock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-lock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-lock2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-lock2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-medical-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-medical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-music-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-music.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-pdf-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-pdf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-person-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-person.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-play-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-play.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-post-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-post.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-ppt-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-ppt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-richtext-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-richtext.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-ruled-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-ruled.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-slides-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-slides.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-spreadsheet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-spreadsheet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-text-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-word-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-word.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-zip-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file-zip.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/file.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/files-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/files.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-aac.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-ai.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-bmp.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-cs.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-css.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-csv.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-doc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-docx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-exe.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-gif.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-heic.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-html.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-java.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-jpg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-js.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-json.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-jsx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-key.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-m4p.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-md.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-mdx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-mov.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-mp3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-mp4.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-otf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-pdf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-php.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-png.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-ppt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-pptx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-psd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-py.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-raw.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-rb.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-sass.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-scss.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-sh.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-svg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-tiff.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-tsx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-ttf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-txt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-wav.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-woff.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-xls.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-xlsx.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-xml.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filetype-yml.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/film.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/filter.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fingerprint.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/flag-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/flag.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/flower1.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/flower2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/flower3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-symlink-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-symlink.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder2-open.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/folder2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fonts.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fonts/bootstrap-icons.woff create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fonts/bootstrap-icons.woff2 create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/forward-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/forward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/front.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fullscreen-exit.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/fullscreen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/funnel-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/funnel.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gear-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gear-wide-connected.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gear-wide.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gear.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gem.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gender-ambiguous.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gender-female.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gender-male.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gender-trans.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/geo-alt-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/geo-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/geo-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/geo.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gift-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gift.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/git.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/github.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/globe.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/globe2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/google.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/gpu-card.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/graph-down-arrow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/graph-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/graph-up-arrow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/graph-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-1x2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-1x2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x2-gap-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x2-gap.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x3-gap-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x3-gap.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-3x3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grid.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grip-horizontal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/grip-vertical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hammer.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-index-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-index-thumb-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-index-thumb.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-index.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-thumbs-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-thumbs-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-thumbs-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hand-thumbs-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/handbag-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/handbag.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-network-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-network.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-rack-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-rack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-stack-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd-stack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdd.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdmi-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hdmi.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/headphones.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/headset-vr.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/headset.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart-arrow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart-pulse-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart-pulse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heartbreak-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heartbreak.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hearts.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heptagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heptagon-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/heptagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hexagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hexagon-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hexagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hospital-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hospital.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hourglass-bottom.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hourglass-split.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hourglass-top.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hourglass.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house-door-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house-door.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/house.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hr.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hurricane.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/hypnotize.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/image-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/image-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/image.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/images.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/inbox-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/inbox.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/inboxes-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/inboxes.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/incognito.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/index.html create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/infinity.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/instagram.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/intersect.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-album.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-code.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-medical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-richtext.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-text.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journals.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/joystick.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ladder.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-backward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-forward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-split.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-three-columns.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-wtf.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/life-preserver.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/line.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link-45deg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/linkedin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns-reverse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-nested.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ol.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-stars.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-task.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ul.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magic.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mask.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mastodon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/medium.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/memory.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/messenger.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/meta.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/microsoft.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart-loaded.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moisture.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-beamed.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-list.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/newspaper.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nintendo-switch.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/option.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/outlet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paint-bucket.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paperclip.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paragraph.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paypal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display-horizontal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-horizontal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pci-card.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/percent.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-bounding-box.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-hearts.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-lines-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-rolodex.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-workspace.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-flip.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pinterest.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/playstation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plugin.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-dotted.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-slash-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-dotted.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/power.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code-scan.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quora.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quote.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/radioactive.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rainbow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt-cutoff.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-0.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-1.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-4.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/recycle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reddit.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/robot.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rulers.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/scissors.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/screwdriver.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/segmented-nav.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/server.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-check.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-exclamation.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-shaded.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop-window.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shuffle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skype.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2-vertical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/smartwatch.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snapchat.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up-alt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/soundwave.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spellcheck.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spotify.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack-overflow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stars.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/steam.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/strava.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/subtract.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunglasses.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-horizontal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-vertical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/table.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telegram.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-split.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-center.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-left.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-paragraph.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-right.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-resize.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-t.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-high.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-low.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-snow.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-sun.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots-vertical.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tiktok.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-on.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-on.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tools.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tornado.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/translate.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-half.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tropical-storm.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck-flatbed.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tsunami.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitch.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitter.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-bold.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h1.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h3.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-italic.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-strikethrough.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-underline.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks-grid.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios-grid.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/union.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc-scan.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upload.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-symbol.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vector-pen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-list.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-stacked.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vimeo.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/voicemail.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vr.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/watch.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/water.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/whatsapp.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-1.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-2.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-off.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wind.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dash.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-desktop.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dock.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-fullscreen.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-plus.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-sidebar.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-split.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-stack.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/windows.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wordpress.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-lg.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square-fill.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/xbox.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/yin-yang.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/youtube.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-in.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-out.svg create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css create mode 100644 user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css.map create mode 100644 user_config/usr/share/newton/context_path/resources/css/main.css create mode 100644 user_config/usr/share/newton/context_path/resources/css/overrides.css create mode 100644 user_config/usr/share/newton/context_path/resources/js/ajax.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/context-menu.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/events.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/globals.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/libs/bootstrap5/bootstrap.bundle.min.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/libs/bootstrap5/bootstrap.bundle.min.js.map create mode 100644 user_config/usr/share/newton/context_path/resources/js/libs/jquery-3.7.1.min.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/post-ajax.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/ui-logic.js create mode 100644 user_config/usr/share/newton/context_path/resources/js/utils.js create mode 100644 user_config/usr/share/newton/icons/archive.png create mode 100644 user_config/usr/share/newton/icons/audio.png create mode 100644 user_config/usr/share/newton/icons/bin.png create mode 100644 user_config/usr/share/newton/icons/brain.png create mode 100644 user_config/usr/share/newton/icons/dir.png create mode 100644 user_config/usr/share/newton/icons/doc.png create mode 100644 user_config/usr/share/newton/icons/image.png create mode 100644 user_config/usr/share/newton/icons/newton-64x64.png create mode 100644 user_config/usr/share/newton/icons/newton.png create mode 100644 user_config/usr/share/newton/icons/only-in-selection.png create mode 100644 user_config/usr/share/newton/icons/pdf.png create mode 100644 user_config/usr/share/newton/icons/presentation.png create mode 100644 user_config/usr/share/newton/icons/spreadsheet.png create mode 100644 user_config/usr/share/newton/icons/text.png create mode 100644 user_config/usr/share/newton/icons/trash.png create mode 100644 user_config/usr/share/newton/icons/video.png create mode 100644 user_config/usr/share/newton/icons/web.png create mode 100644 user_config/usr/share/newton/icons/whole-word.png create mode 100644 user_config/usr/share/newton/key-bindings.json create mode 100644 user_config/usr/share/newton/stylesheet.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d4b4e51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,131 @@ +database.db + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d2b8f3 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Python-With-Gtk-Template +A template project for Python with Gtk applications. + +### Requirements +* PyGObject (Gtk introspection library) +* pygobject-stubs (For actually getting pylsp or python-language-server to auto complete in LSPs. Do if GTK3 --no-cache-dir --config-settings=config=Gtk3,Gdk3,Soup2) +* pyxdg (Desktop ".desktop" file parser) +* setproctitle (Define process title to search and kill more easily) +* sqlmodel (SQL databases and is powered by Pydantic and SQLAlchemy) + +### Note +* pyrightconfig.json can prompt IDEs that use pyright lsp on where imports are located- look at venvPath and venv. "venvPath" is parent path of "venv" where "venv" is just the name of the folder under the parent path that is the python created venv. +* Move respetive sub folder content under user_config to the same places in Linux. Though, user/share/ can go to ~/.config folder if prefered. +* In additiion, place the plugins folder in the same app folder you moved to /usr/share/ or ~/.config/ . +There are a "\" strings and files that need to be set according to your app's name located at: +* \_\_builtins\_\_.py +* user_config/bin/app_name +* user_config/usr/share/app_name +* user_config/usr/share/app_name/icons/app_name.png +* user_config/usr/share/app_name/icons/app_name-64x64.png +* user_config/usr/share/applications/app_name.desktop + + +For the user_config, after changing names and files, copy all content to their respective destinations. +The logic follows Debian Dpkg packaging and its placement logic. diff --git a/plugins/README.txt b/plugins/README.txt new file mode 100644 index 0000000..a85e24c --- /dev/null +++ b/plugins/README.txt @@ -0,0 +1,31 @@ +### Note +Copy the example and rename it to your desired name. Plugins define a ui target slot with the 'ui_target' requests data but don't have to if not directly interacted with. +Plugins must have a run method defined; though, you do not need to necessarily do anything within it. The run method implies that the passed in event system or other data is ready for the plugin to use. + + +### Manifest Example (All are required even if empty.) +``` +class Manifest: + name: str = "Example Plugin" + author: str = "John Doe" + version: str = "0.0.1" + support: str = "" + pre_launch: bool = False + requests: {} = { + 'pass_ui_objects': ["plugin_control_list"], + 'pass_events': True, + 'bind_keys': [] + } +``` + + +### Requests +``` +requests: {} = { + 'pass_events': true, # If empty or not present will be ignored. + "pass_ui_objects": [""], # Request reference to a UI component. Will be passed back as array to plugin. + 'bind_keys': [f"{name}||send_message:f"], + f"{name}||do_save:s"] # Bind keys with method and key pare using list. Must pass "name" like shown with delimiter to its right. + +} +``` diff --git a/plugins/autopairs/__init__.py b/plugins/autopairs/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/autopairs/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/autopairs/__main__.py b/plugins/autopairs/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/autopairs/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/autopairs/manifest.json b/plugins/autopairs/manifest.json new file mode 100644 index 0000000..f87c853 --- /dev/null +++ b/plugins/autopairs/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "Autopairs", + "author": "ITDominator", + "credit": "Hamad Al Marri", + "version": "0.0.1", + "support": "", + "requests": { + "pass_events": true + } +} \ No newline at end of file diff --git a/plugins/autopairs/plugin.py b/plugins/autopairs/plugin.py new file mode 100644 index 0000000..848c84e --- /dev/null +++ b/plugins/autopairs/plugin.py @@ -0,0 +1,140 @@ +# Python imports +import os +import threading +import subprocess +import time + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from plugins.plugin_base import PluginBase + + + + +# NOTE: Threads WILL NOT die with parent's destruction. +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() + return wrapper + +# NOTE: Threads WILL die with parent's destruction. +def daemon_threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() + return wrapper + + + + +class Plugin(PluginBase): + def __init__(self): + super().__init__() + + self.name = "Autopairs" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + + self.chars = { + "quotedbl": "\"", + "apostrophe": "'", + "parenleft": "(", + "bracketleft": "[", + "braceleft": "{", + "less": "<", + "grave": "`", + } + + self.close = { + "\"": "\"", + "'": "'", + "(": ")", + "[": "]", + "{": "}", + "<": ">", + "`": "`", + } + + def generate_reference_ui_element(self): + ... + + def run(self): + ... + + def subscribe_to_events(self): + self._event_system.subscribe("set_active_src_view", self._set_active_src_view) + self._event_system.subscribe("autopairs", self._autopairs) + + def _set_active_src_view(self, source_view): + self._active_src_view = source_view + self._buffer = self._active_src_view.get_buffer() + self._tag_table = self._buffer.get_tag_table() + + def _autopairs(self, keyval_name, ctrl, alt, shift): + if keyval_name in self.chars: + return self.text_insert(self._buffer, keyval_name) + + # NOTE: All of below to EOF, lovingly taken from Hamad Al Marri's Gamma + # text editor. I did do some cleanup of comments but otherwise pretty + # much the same code just fitted to my plugin architecture. + # Link: https://gitlab.com/hamadmarri/gamma-text-editor + def text_insert(self, buffer, text): + selection = buffer.get_selection_bounds() + if selection == (): + return self.add_close(buffer, text, ) + else: + return self.add_enclose(buffer, text, selection) + + def add_close(self, buffer, text): + text = self.chars[text] + text += self.close[text] + + position = buffer.get_iter_at_mark( buffer.get_insert() ) + + c = position.get_char() + if not c in (" ", "", ";", ":", "\t", ",", ".", "\n", "\r") \ + and not c in list(self.close.values()): + return False + + buffer.insert(position, text) + + position = buffer.get_iter_at_mark(buffer.get_insert()) + position.backward_char() + buffer.place_cursor(position) + + return True + + def add_enclose(self, buffer, text, selection): + (start, end) = selection + selected = buffer.get_text(start, end, False) + if len(selected) <= 3 and selected in ("<", ">", ">>>" + "<<", ">>", + "\"", "'", "`", + "(", ")", + "[", "]", + "{", "}", + "=", "==", + "!=", "==="): + return False + + start_mark = buffer.create_mark("startclose", start, False) + end_mark = buffer.create_mark("endclose", end, False) + + buffer.begin_user_action() + + t = self.chars[text] + buffer.insert(start, t) + end = buffer.get_iter_at_mark(end_mark) + t = self.close[t] + buffer.insert(end, t) + + start = buffer.get_iter_at_mark(start_mark) + end = buffer.get_iter_at_mark(end_mark) + end.backward_char() + buffer.select_range(start, end) + + buffer.end_user_action() + + return True \ No newline at end of file diff --git a/plugins/colorize/__init__.py b/plugins/colorize/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/colorize/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/colorize/__main__.py b/plugins/colorize/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/colorize/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/colorize/color_converter_mixin.py b/plugins/colorize/color_converter_mixin.py new file mode 100644 index 0000000..0e8cd39 --- /dev/null +++ b/plugins/colorize/color_converter_mixin.py @@ -0,0 +1,107 @@ +# Python imports +import colorsys + +# Lib imports + +# Application imports + + +class ColorConverterMixin: + # NOTE: HSV HSL, and Hex Alpha parsing are available in Gtk 4.0- not lower. + # So, for compatability we're gunna convert to rgba string ourselves... + def get_color_text(self, buffer, start, end): + text = buffer.get_text(start, end, include_hidden_chars = False) + + try: + if "hsl" in text: + text = self.hsl_to_rgb(text) + + if "hsv" in text: + text = self.hsv_to_rgb(text) + + if "#" == text[0]: + hex = text[1:] + size = len(hex) + if size in [4, 8, 16]: + rgba = self.hex_to_rgba(hex, size) + print(rgba) + + except Exception as e: + ... + + return text + + def hex_to_rgba(self, hex, size): + rgba = [] + slots = None + step = 2 + bytes = 16 + + if size == 4: # NOTE: RGBA + step = 1 + slots = (0, 1, 2, 3) + + if size == 6: # NOTE: RR GG BB + slots = (0, 2, 4) + + if size == 8: # NOTE: RR GG BB AA + step = 2 + slots = (0, 2, 4, 6) + + if size == 16: # NOTE: RRRR GGGG BBBB AAAA + step = 4 + slots = (0, 4, 8, 12) + + for i in slots: + v = int(hex[i : i + step], bytes) + rgba.append(v) + + + rgb_sub = ','.join(map(str, tuple(rgba))) + + return f"rgba({rgb_sub})" + + # return tuple(rgba) + + + + def hsl_to_rgb(self, text): + _h, _s , _l = text.replace("hsl", "") \ + .replace("deg", "") \ + .replace("(", "") \ + .replace(")", "") \ + .replace("%", "") \ + .replace(" ", "") \ + .split(",") + + h = None + s = None + l = None + + h, s , l = int(_h) / 360, float(_s) / 100, float(_l) / 100 + + rgb = tuple(round(i * 255) for i in colorsys.hls_to_rgb(h, l, s)) + rgb_sub = ','.join(map(str, rgb)) + + return f"rgb({rgb_sub})" + + + def hsv_to_rgb(self, text): + _h, _s , _v = text.replace("hsv", "") \ + .replace("deg", "") \ + .replace("(", "") \ + .replace(")", "") \ + .replace("%", "") \ + .replace(" ", "") \ + .split(",") + + h = None + s = None + v = None + + h, s , v = int(_h) / 360, float(_s) / 100, float(_v) / 100 + + rgb = tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v)) + rgb_sub = ','.join(map(str, rgb)) + + return f"rgb({rgb_sub})" diff --git a/plugins/colorize/manifest.json b/plugins/colorize/manifest.json new file mode 100644 index 0000000..6cb1aab --- /dev/null +++ b/plugins/colorize/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "Colorize", + "author": "ITDominator", + "version": "0.0.1", + "support": "", + "requests": { + "pass_events": true + } +} \ No newline at end of file diff --git a/plugins/colorize/plugin.py b/plugins/colorize/plugin.py new file mode 100644 index 0000000..ba16125 --- /dev/null +++ b/plugins/colorize/plugin.py @@ -0,0 +1,228 @@ +# Python imports +import random + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk + +# Application imports +from plugins.plugin_base import PluginBase +from .color_converter_mixin import ColorConverterMixin + + + +class Plugin(ColorConverterMixin, PluginBase): + def __init__(self): + super().__init__() + + self.name = "Colorize" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + self.tag_stub_name = "colorize_tag" + self._buffer = None + + + def run(self): + ... + + def generate_reference_ui_element(self): + ... + + def subscribe_to_events(self): + self._event_system.subscribe("set_active_src_view", self._set_active_src_view) + self._event_system.subscribe("buffer_changed_first_load", self._buffer_changed_first_load) + self._event_system.subscribe("buffer_changed", self._buffer_changed) + + + def _set_active_src_view(self, source_view): + self._active_src_view = source_view + + + def _buffer_changed_first_load(self, buffer): + self._buffer = buffer + self._do_colorize(buffer) + + def _buffer_changed(self, buffer): + self._event_system.emit("pause_event_processing") + self._handle_colorize(buffer) + self._event_system.emit("resume_event_processing") + + def _handle_colorize(self, buffer): + self._buffer = buffer + tag_table = buffer.get_tag_table() + mark = buffer.get_insert() + start = None + end = buffer.get_iter_at_mark(mark) + + i = 0 + walker_iter = end.copy() + working_tag = self.find_working_tag(walker_iter, i) + if working_tag: + start = self.find_start_range(walker_iter, working_tag) + + self.find_end_range(end, working_tag) + buffer.remove_tag(working_tag, start, end) + else: + start = self.traverse_backward_25_or_less(walker_iter) + self.traverse_forward_25_or_less(end) + + self._do_colorize(buffer, start, end) + + + + def find_working_tag(self, walker_iter, i): + tags = walker_iter.get_tags() + for tag in tags: + if tag.props.name and self.tag_stub_name in tag.props.name: + return tag + + res = walker_iter.backward_char() + + if not res: return + if i > 25: return + return self.find_working_tag(walker_iter, i + 1) + + def find_start_range(self, walker_iter, working_tag): + tags = walker_iter.get_tags() + for tag in tags: + if tag.props.name and working_tag.props.name in tag.props.name: + res = walker_iter.backward_char() + if res: + self.find_start_range(walker_iter, working_tag) + + return walker_iter + + def find_end_range(self, end, working_tag): + tags = end.get_tags() + for tag in tags: + if tag.props.name and working_tag.props.name in tag.props.name: + res = end.forward_char() + if res: + self.find_end_range(end, working_tag) + + def traverse_backward_25_or_less(self, walker_iter): + i = 1 + while i <= 25: + res = walker_iter.backward_char() + if not res: break + i += 1 + + def traverse_forward_25_or_less(self, end): + i = 1 + while i <= 25: + res = end.forward_char() + if not res: break + i += 1 + + def _do_colorize(self, buffer = None, start_itr = None, end_itr = None): + # rgb(a), hsl, hsv + results = self.finalize_non_hex_matches( self.collect_preliminary_results(buffer, start_itr, end_itr) ) + self.process_results(buffer, results) + + # hex color search + results = self.finalize_hex_matches( self.collect_preliminary_hex_results(buffer, start_itr, end_itr) ) + self.process_results(buffer, results) + + + def collect_preliminary_results(self, buffer = None, start_itr = None, end_itr = None): + if not buffer: return [] + + if not start_itr: + start_itr = buffer.get_start_iter() + + results1 = self.search(start_itr, end_itr, "rgb") + results2 = self.search(start_itr, end_itr, "hsl") + results3 = self.search(start_itr, end_itr, "hsv") + + return results1 + results2 + results3 + + def collect_preliminary_hex_results(self, buffer = None, start_itr = None, end_itr = None): + if not buffer: return [] + + if not start_itr: + start_itr = buffer.get_start_iter() + + results1 = self.search(start_itr, end_itr, "#") + + return results1 + + def search(self, start_itr = None, end_itr = None, query = None): + if not start_itr or not query: return None, None + + results = [] + flags = Gtk.TextSearchFlags.VISIBLE_ONLY | Gtk.TextSearchFlags.TEXT_ONLY + while True: + result = start_itr.forward_search(query, flags, end_itr) + if not result: break + + results.append(result) + start_itr = result[1] + + return results + + def finalize_non_hex_matches(self, result_hits: [] = []): + results = [] + + for start, end in result_hits: + if end.get_char() == "a": + end.forward_char() + + if end.get_char() != "(": + continue + + end.forward_chars(21) + if end.get_char() == ")": + end.forward_char() + results.append([start, end]) + continue + + while end.get_char() != "(": + if end.get_char() == ")": + end.forward_char() + results.append([start, end]) + break + + end.forward_chars(-1) + + return results + + def finalize_hex_matches(self, result_hits: [] = []): + results = [] + + for start, end in result_hits: + i = 0 + _ch = end.get_char() + ch = ord(end.get_char()) if _ch else -1 + + while ((ch >= 48 and ch <= 57) or (ch >= 65 and ch <= 70) or (ch >= 97 and ch <= 102)): + if i > 16: break + + i += 1 + end.forward_char() + _ch = end.get_char() + ch = ord(end.get_char()) if _ch else -1 + + if i in [3, 4, 6, 8, 9, 12, 16]: + results.append([start, end]) + + return results + + def process_results(self, buffer, results): + for start, end in results: + text = self.get_color_text(buffer, start, end) + color = Gdk.RGBA() + + if color.parse(text): + tag = self.get_colorized_tag(buffer, text, color) + buffer.apply_tag(tag, start, end) + + def get_colorized_tag(self, buffer, tag, color: Gdk.RGBA): + tag_table = buffer.get_tag_table() + colorize_tag = f"{self.tag_stub_name}_{tag}" + search_tag = tag_table.lookup(colorize_tag) + if not search_tag: + search_tag = buffer.create_tag(colorize_tag, background_rgba = color) + + return search_tag diff --git a/plugins/commentzar/__init__.py b/plugins/commentzar/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/commentzar/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/commentzar/__main__.py b/plugins/commentzar/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/commentzar/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/commentzar/add_comment_mixin.py b/plugins/commentzar/add_comment_mixin.py new file mode 100755 index 0000000..6e123f3 --- /dev/null +++ b/plugins/commentzar/add_comment_mixin.py @@ -0,0 +1,66 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class AddCommentMixin: + def add_comment_characters(self, buffer, start_tag, end_tag, start, end, deselect, oldPos): + smark = buffer.create_mark("start", start, False) + imark = buffer.create_mark("iter", start, False) + emark = buffer.create_mark("end", end, False) + number_lines = end.get_line() - start.get_line() + 1 + comment_pos_iter = None + count = 0 + + buffer.begin_user_action() + + for i in range(0, number_lines): + iter = buffer.get_iter_at_mark(imark) + if not comment_pos_iter: + (comment_pos_iter, count) = self.discard_white_spaces(iter) + + if self.is_commented(comment_pos_iter, start_tag): + new_code = self.remove_comment_characters(buffer, start_tag, end_tag, start, end) + return + else: + comment_pos_iter = iter + for i in range(count): + c = iter.get_char() + if not c in (" ", "\t"): + break + + iter.forward_char() + + buffer.insert(comment_pos_iter, start_tag) + buffer.insert(comment_pos_iter, " ") + + if end_tag: + if i != number_lines -1: + iter = buffer.get_iter_at_mark(imark) + iter.forward_to_line_end() + buffer.insert(iter, end_tag) + else: + iter = buffer.get_iter_at_mark(emark) + buffer.insert(iter, end_tag) + + iter = buffer.get_iter_at_mark(imark) + iter.forward_line() + buffer.delete_mark(imark) + imark = buffer.create_mark("iter", iter, True) + + buffer.end_user_action() + + buffer.delete_mark(imark) + new_start = buffer.get_iter_at_mark(smark) + new_end = buffer.get_iter_at_mark(emark) + + buffer.select_range(new_start, new_end) + buffer.delete_mark(smark) + buffer.delete_mark(emark) + + if deselect: + oldPosIter = buffer.get_iter_at_offset(oldPos + 2) + buffer.place_cursor(oldPosIter) diff --git a/plugins/commentzar/codecomment_tags.py b/plugins/commentzar/codecomment_tags.py new file mode 100755 index 0000000..ac7d110 --- /dev/null +++ b/plugins/commentzar/codecomment_tags.py @@ -0,0 +1,30 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class CodeCommentTags: + def get_comment_tags(self, lang): + (s, e) = self.get_line_comment_tags(lang) + if (s, e) == (None, None): + (s, e) = self.get_block_comment_tags(lang) + + return (s, e) + + def get_block_comment_tags(self, lang): + start_tag = lang.get_metadata('block-comment-start') + end_tag = lang.get_metadata('block-comment-end') + if start_tag and end_tag: + return (start_tag, end_tag) + + return (None, None) + + def get_line_comment_tags(self, lang): + start_tag = lang.get_metadata('line-comment-start') + if start_tag: + return (start_tag, None) + + return (None, None) diff --git a/plugins/commentzar/manifest.json b/plugins/commentzar/manifest.json new file mode 100644 index 0000000..8197cc3 --- /dev/null +++ b/plugins/commentzar/manifest.json @@ -0,0 +1,11 @@ +{ + "name": "Commentzar", + "author": "ITDominator", + "credit": "Hamad Al Marri", + "version": "0.0.1", + "support": "", + "requests": { + "pass_events": true, + "bind_keys": ["Commentzar||keyboard_tggl_comment:slash"] + } +} diff --git a/plugins/commentzar/plugin.py b/plugins/commentzar/plugin.py new file mode 100644 index 0000000..cbf41bf --- /dev/null +++ b/plugins/commentzar/plugin.py @@ -0,0 +1,118 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from plugins.plugin_base import PluginBase +from .codecomment_tags import CodeCommentTags +from .remove_comment_mixin import RemoveCommentMixin +from .add_comment_mixin import AddCommentMixin + + + +class Plugin(AddCommentMixin, RemoveCommentMixin, CodeCommentTags, PluginBase): + def __init__(self): + super().__init__() + + self.name = "Commentzar" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + + + def generate_reference_ui_element(self): + ... + + def run(self): + ... + + def subscribe_to_events(self): + self._event_system.subscribe("keyboard_tggl_comment", self._keyboard_tggl_comment) + self._event_system.subscribe("set_active_src_view", self._set_active_src_view) + + def _set_active_src_view(self, source_view): + self._active_src_view = source_view + self._buffer = self._active_src_view.get_buffer() + self._tag_table = self._buffer.get_tag_table() + + + def _keyboard_tggl_comment(self): + buffer = self._buffer + lang = buffer.get_language() + if lang is None: + return + + (start_tag, end_tag) = self.get_comment_tags(lang) + if not start_tag and not end_tag: + return + + sel = buffer.get_selection_bounds() + currentPosMark = buffer.get_insert() + oldPos = 0 + + # if user selected chars or multilines + if sel != (): + deselect = False + (start, end) = sel + if not start.starts_line(): + start.set_line_offset(0) + if not end.ends_line(): + end.forward_to_line_end() + else: + deselect = True + start = buffer.get_iter_at_mark(currentPosMark) + oldPos = buffer.get_iter_at_mark(currentPosMark).get_offset() + start.set_line_offset(0) + end = start.copy() + + if not end.ends_line(): + end.forward_to_line_end() + + if start.get_offset() == end.get_offset(): + buffer.begin_user_action() + buffer.insert(start, start_tag) + buffer.insert(start, " ") + buffer.end_user_action() + return + + self._event_system.emit("pause_event_processing") + new_code = self.add_comment_characters(buffer, start_tag, end_tag, start, end, deselect, oldPos) + self._event_system.emit("resume_event_processing") + + def discard_white_spaces(self, iter): + count = 0 + while not iter.ends_line(): + c = iter.get_char() + if not c in (" ", "\t"): + return (iter, count) + + iter.forward_char() + count += 1 + + return (iter, 0) + + def is_commented(self, comment_pos_iter, start_tag): + head_iter = comment_pos_iter.copy() + self.forward_tag(head_iter, start_tag) + s = comment_pos_iter.get_slice(head_iter) + if s == start_tag: + return True + + return False + + def forward_tag(self, iter, tag): + iter.forward_chars(len(tag)) + + def backward_tag(self, iter, tag): + iter.backward_chars(len(tag)) + + def get_tag_position_in_line(self, tag, head_iter, iter): + while not iter.ends_line(): + s = iter.get_slice(head_iter) + if s == tag: + return True + else: + head_iter.forward_char() + iter.forward_char() + return False diff --git a/plugins/commentzar/remove_comment_mixin.py b/plugins/commentzar/remove_comment_mixin.py new file mode 100755 index 0000000..0e956f2 --- /dev/null +++ b/plugins/commentzar/remove_comment_mixin.py @@ -0,0 +1,49 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class RemoveCommentMixin: + def remove_comment_characters(self, buffer, start_tag, end_tag, start, end): + smark = buffer.create_mark("start", start, False) + emark = buffer.create_mark("end", end, False) + number_lines = end.get_line() - start.get_line() + 1 + iter = start.copy() + head_iter = iter.copy() + self.forward_tag(head_iter, start_tag) + + buffer.begin_user_action() + + for i in range(0, number_lines): + if self.get_tag_position_in_line(start_tag, head_iter, iter): + dmark = buffer.create_mark("delete", iter, False) + buffer.delete(iter, head_iter) + + space_iter = head_iter.copy() + space_iter.forward_char() + s = head_iter.get_slice(space_iter) + if s == " ": + buffer.delete(head_iter, space_iter) + + if end_tag: + iter = buffer.get_iter_at_mark(dmark) + head_iter = iter.copy() + self.forward_tag(head_iter, end_tag) + if self.get_tag_position_in_line(end_tag, head_iter, iter): + buffer.delete(iter, head_iter) + buffer.delete_mark(dmark) + + iter = buffer.get_iter_at_mark(smark) + iter.forward_line() + buffer.delete_mark(smark) + head_iter = iter.copy() + self.forward_tag(head_iter, start_tag) + smark = buffer.create_mark("iter", iter, True) + + buffer.end_user_action() + + buffer.delete_mark(smark) + buffer.delete_mark(emark) diff --git a/plugins/lsp_client/__init__.py b/plugins/lsp_client/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/lsp_client/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/lsp_client/__main__.py b/plugins/lsp_client/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/lsp_client/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/lsp_client/client_ipc.py b/plugins/lsp_client/client_ipc.py new file mode 100644 index 0000000..7533763 --- /dev/null +++ b/plugins/lsp_client/client_ipc.py @@ -0,0 +1,182 @@ +# Python imports +import traceback +import os +import threading +import time +import json +import base64 +from multiprocessing.connection import Client +from multiprocessing.connection import Listener + +# Lib imports +import gi +from gi.repository import GLib + +# Application imports +from .lsp_message_structs import LSPResponseRequest +from .lsp_message_structs import LSPResponseNotification, LSPIDResponseNotification +from .lsp_message_structs import get_message_obj + + + +class ClientIPC: + """ Create a Messenger so talk to LSP Manager. """ + def __init__(self, ipc_address: str = '127.0.0.1', conn_type: str = "socket"): + self.is_ipc_alive = False + self._ipc_port = 4848 + self._ipc_address = ipc_address + self._conn_type = conn_type + self._ipc_authkey = b'' + bytes(f'lsp-client-endpoint-ipc', 'utf-8') + self._manager_ipc_authkey = b'' + bytes(f'lsp-manager-endpoint-ipc', 'utf-8') + self._ipc_timeout = 15.0 + self._event_system = None + + if conn_type == "socket": + self._ipc_address = f'/tmp/lsp-client-endpoint-ipc.sock' + self._manager_ipc_address = f'/tmp/lsp-manager-endpoint-ipc.sock' + elif conn_type == "full_network": + self._ipc_address = '0.0.0.0' + elif conn_type == "full_network_unsecured": + self._ipc_authkey = None + self._ipc_address = '0.0.0.0' + elif conn_type == "local_network_unsecured": + self._ipc_authkey = None + + + def set_event_system(self, event_system): + self._event_system = event_system + + def create_ipc_listener(self) -> None: + if self._conn_type == "socket": + if os.path.exists(self._ipc_address) and settings_manager.is_dirty_start(): + os.unlink(self._ipc_address) + + listener = Listener(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + listener = Listener((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + listener = Listener((self._ipc_address, self._ipc_port)) + + + self.is_ipc_alive = True + self._run_ipc_loop(listener) + + @daemon_threaded + def _run_ipc_loop(self, listener) -> None: + # NOTE: Not thread safe if using with Gtk. Need to import GLib and use idle_add + while self.is_ipc_alive: + try: + conn = listener.accept() + start_time = time.perf_counter() + self._handle_ipc_message(conn, start_time) + except Exception as e: + logger.debug( traceback.print_exc() ) + + listener.close() + + def _handle_ipc_message(self, conn, start_time) -> None: + while self.is_ipc_alive: + msg = conn.recv() + + if "MANAGER|" in msg: + data = msg.split("MANAGER|")[1].strip() + + if data: + data_str = base64.b64decode(data.encode("utf-8")).decode("utf-8") + lsp_response = None + keys = None + + try: + lsp_response = json.loads(data_str) + keys = lsp_response.keys() + except Exception as e: + raise e + + if "result" in keys: + lsp_response = LSPResponseRequest(**get_message_obj(data_str)) + + if "method" in keys: + lsp_response = LSPResponseNotification( **get_message_obj(data_str) ) if not "id" in keys else LSPIDResponseNotification( **get_message_obj(data_str) ) + + if "notification" in keys: + ... + + if "response" in keys: + ... + + if "ignorable" in keys: + ... + + if lsp_response: + GLib.idle_add(self._do_emit, lsp_response) + + conn.close() + break + + if msg in ['close connection', 'close server']: + conn.close() + break + + # NOTE: Not perfect but insures we don't lock up the connection for too long. + end_time = time.perf_counter() + if (end_time - start_time) > self._ipc_timeout: + conn.close() + break + + def _do_emit(self, lsp_response): + self._event_system.emit("handle-lsp-message", (lsp_response,)) + + def send_manager_ipc_message(self, message: str) -> None: + try: + if self._conn_type == "socket": + if not os.path.exists(self._manager_ipc_address): + logger.error(f"Socket: {self._manager_ipc_address} doesn't exist. NOT sending message...") + return + + conn = Client(address=self._manager_ipc_address, family="AF_UNIX", authkey=self._manager_ipc_authkey) + elif "unsecured" not in self._conn_type: + conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + conn = Client((self._ipc_address, self._ipc_port)) + + conn.send( f"CLIENT|{ base64.b64encode(message.encode('utf-8')).decode('utf-8') }" ) + conn.close() + except ConnectionRefusedError as e: + logger.error("Connection refused...") + except Exception as e: + logger.error( repr(e) ) + + + def send_ipc_message(self, message: str = "Empty Data...") -> None: + try: + if self._conn_type == "socket": + conn = Client(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + conn = Client((self._ipc_address, self._ipc_port)) + + conn.send(message) + conn.close() + except ConnectionRefusedError as e: + logger.error("Connection refused...") + except Exception as e: + logger.error( repr(e) ) + + def send_test_ipc_message(self, message: str = "Empty Data...") -> None: + try: + if self._conn_type == "socket": + conn = Client(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + conn = Client((self._ipc_address, self._ipc_port)) + + conn.send(message) + conn.close() + except ConnectionRefusedError as e: + if self._conn_type == "socket": + logger.error("LSP Socket no longer valid.... Removing.") + os.unlink(self._ipc_address) + except Exception as e: + logger.error( repr(e) ) \ No newline at end of file diff --git a/plugins/lsp_client/config.json b/plugins/lsp_client/config.json new file mode 100644 index 0000000..ae53ba3 --- /dev/null +++ b/plugins/lsp_client/config.json @@ -0,0 +1,7 @@ +{ + "lsp_manager_start_command": ["python", "/opt/lsp-manager.zip"], + "websocket": { + "host": "localhost", + "port": 8765 + } +} \ No newline at end of file diff --git a/plugins/lsp_client/lsp_message_structs.py b/plugins/lsp_client/lsp_message_structs.py new file mode 100644 index 0000000..eae0ad4 --- /dev/null +++ b/plugins/lsp_client/lsp_message_structs.py @@ -0,0 +1,54 @@ +# Python imports +from dataclasses import dataclass +import json + +# Lib imports + +# Application imports + + + +def get_message_obj(data: str): + return json.loads(data) + + +@dataclass +class LSPResponseRequest(object): + """ + Constructs a new LSP Response Request instance. + + :param id result: The id of the given message. + :param dict result: The arguments of the given method. + """ + jsonrpc: str + id: int + result: dict + +@dataclass +class LSPResponseNotification(object): + """ + Constructs a new LSP Response Notification instance. + + :param str method: The type of lsp notification being made. + :params dict result: The arguments of the given method. + """ + jsonrpc: str + method: str + params: dict + +@dataclass +class LSPIDResponseNotification(object): + """ + Constructs a new LSP Response Notification instance. + + :param str method: The type of lsp notification being made. + :params dict result: The arguments of the given method. + """ + jsonrpc: str + id: int + method: str + params: dict + + +class LSPResponseTypes(LSPResponseRequest, LSPResponseNotification, LSPIDResponseNotification): + ... \ No newline at end of file diff --git a/plugins/lsp_client/manifest.json b/plugins/lsp_client/manifest.json new file mode 100644 index 0000000..dab7ee4 --- /dev/null +++ b/plugins/lsp_client/manifest.json @@ -0,0 +1,16 @@ +{ + "name": "LSP Client", + "author": "ITDominator", + "version": "0.0.1", + "credit": "", + "support": "", + "requests": { + "pass_events": true, + "pass_ui_objects": [ + "separator_right" + ], + "bind_keys": [ + "LSP Client Toggle||tggl_lsp_window:l" + ] + } +} diff --git a/plugins/lsp_client/plugin.py b/plugins/lsp_client/plugin.py new file mode 100644 index 0000000..cab6c38 --- /dev/null +++ b/plugins/lsp_client/plugin.py @@ -0,0 +1,270 @@ +# Python imports +import signal +import subprocess +import json + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from plugins.plugin_base import PluginBase +from .client_ipc import ClientIPC + + + +class Plugin(PluginBase): + def __init__(self): + + super().__init__() + self.name = "LSP Client" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + self.config_file = "config.json" + self.config: dict = {} + self.lsp_client_proc = None + self.lsp_window = None + + + def generate_reference_ui_element(self): + ... + + def run(self): + try: + with open(self.config_file) as f: + self.config = json.load(f) + except Exception as e: + raise Exception(f"Couldn't load config.json...\n{repr(e)}") + + self.lsp_window = Gtk.Window() + box1 = Gtk.Box() + box2 = Gtk.Box() + start_btn = Gtk.Button(label = "Start LSP Client") + stop_btn = Gtk.Button(label = "Stop LSP Client") + pid_label = Gtk.Label(label = "LSP PID: ") + + box1.set_orientation( Gtk.Orientation.VERTICAL ) + + self.lsp_window.set_deletable(False) + self.lsp_window.set_skip_pager_hint(True) + self.lsp_window.set_skip_taskbar_hint(True) + self.lsp_window.set_title("LSP Manager") + self.lsp_window.set_size_request(480, 320) + + start_btn.connect("clicked", self.start_lsp_manager) + stop_btn.connect("clicked", self.stop_lsp_manager) + + box1.add(pid_label) + box2.add(start_btn) + box2.add(stop_btn) + box1.add(box2) + self.lsp_window.add(box1) + + box1.show_all() + + self.inner_subscribe_to_events() + + def _shutting_down(self): + self.stop_lsp_manager() + + def _tear_down(self, widget, eve): + return True + + def _tggl_lsp_window(self, widget = None): + if not self.lsp_window.is_visible(): + self.lsp_window.show() + else: + self.lsp_window.hide() + + + def subscribe_to_events(self): + self._event_system.subscribe("tggl_lsp_window", self._tggl_lsp_window) + + def inner_subscribe_to_events(self): + self._event_system.subscribe("shutting_down", self._shutting_down) + + self._event_system.subscribe("textDocument/didOpen", self._lsp_did_open) + self._event_system.subscribe("textDocument/didSave", self._lsp_did_save) + self._event_system.subscribe("textDocument/didClose", self._lsp_did_close) + self._event_system.subscribe("textDocument/didChange", self._lsp_did_change) + self._event_system.subscribe("textDocument/definition", self._lsp_goto) + self._event_system.subscribe("textDocument/completion", self._lsp_completion) + + def start_lsp_manager(self, button): + if self.lsp_client_proc: return + self.lsp_client_proc = subprocess.Popen(self.config["lsp_manager_start_command"]) + self._load_client_ipc_server() + + def _load_client_ipc_server(self): + self.client_ipc = ClientIPC() + self.client_ipc.set_event_system(self._event_system) + self._ipc_realization_check(self.client_ipc) + + if not self.client_ipc.is_ipc_alive: + raise AppLaunchException(f"LSP IPC Server Already Exists...") + + def _ipc_realization_check(self, ipc_server): + try: + ipc_server.create_ipc_listener() + except Exception: + ipc_server.send_test_ipc_message() + + try: + ipc_server.create_ipc_listener() + except Exception as e: + ... + + def stop_lsp_manager(self, button = None): + if not self.lsp_client_proc: return + if not self.lsp_client_proc.poll() is None: + self.lsp_client_proc = None + return + + self.lsp_client_proc.terminate() + self.client_ipc.is_ipc_alive = False + self.lsp_client_proc = None + + def _lsp_did_open(self, language_id: str, uri: str, text: str): + if not self.lsp_client_proc: return + + data = { + "method": "textDocument/didOpen", + "language_id": language_id, + "uri": uri, + "version": -1, + "text": text, + "line": -1, + "column": -1, + "char": "" + } + + self.send_message(data) + + def _lsp_did_save(self, uri: str, text: str): + if not self.lsp_client_proc: return + + data = { + "method": "textDocument/didSave", + "language_id": "", + "uri": uri, + "version": -1, + "text": text, + "line": -1, + "column": -1, + "char": "" + } + + self.send_message(data) + + def _lsp_did_close(self, uri: str): + if not self.lsp_client_proc: return + + data = { + "method": "textDocument/didClose", + "language_id": "", + "uri": uri, + "version": -1, + "text": "", + "line": -1, + "column": -1, + "char": "" + } + + self.send_message(data) + + def _lsp_did_change(self, language_id: str, uri: str, buffer): + if not self.lsp_client_proc: return + + iter = buffer.get_iter_at_mark( buffer.get_insert() ) + line = iter.get_line() + column = iter.get_line_offset() + + start, end = buffer.get_bounds() + + text = buffer.get_text(start, end, include_hidden_chars = True) + data = { + "method": "textDocument/didChange", + "language_id": language_id, + "uri": uri, + "version": buffer.version_id, + "text": text, + "line": line, + "column": column, + "char": "" + } + + self.send_message(data) + + +# def _lsp_did_change(self, language_id: str, uri: str, buffer): +# if not self.lsp_client_proc: return + +# iter = buffer.get_iter_at_mark( buffer.get_insert() ) +# line = iter.get_line() +# column = iter.get_line_offset() +# start = iter.copy() +# end = iter.copy() + +# start.backward_line() +# start.forward_line() +# end.forward_line() + +# text = buffer.get_text(start, end, include_hidden_chars = True) +# data = { +# "method": "textDocument/didChange", +# "language_id": language_id, +# "uri": uri, +# "version": buffer.version_id, +# "text": text, +# "line": line, +# "column": column, +# "char": "" +# } + +# self.send_message(data) + + + def _lsp_goto(self, language_id: str, uri: str, line: int, column: int): + if not self.lsp_client_proc: return + + data = { + "method": "textDocument/definition", + "language_id": language_id, + "uri": uri, + "version": -1, + "text": "", + "line": line, + "column": column, + "char": "" + } + + self.send_message(data) + + def _lsp_completion(self, source_view): + if not self.lsp_client_proc: return + + filepath = source_view.get_current_file() + if not filepath: return + + uri = filepath.get_uri() + buffer = source_view.get_buffer() + iter = buffer.get_iter_at_mark( buffer.get_insert() ) + line = iter.get_line() + column = iter.get_line_offset() + char = iter.get_char() + + data = { + "method": "textDocument/completion", + "language_id": source_view.get_filetype(), + "uri": uri, + "version": source_view.get_version_id(), + "text": "", + "line": line, + "column": column, + "char": char + } + + self.send_message(data) + + def send_message(self, data: dict): + self.client_ipc.send_manager_ipc_message( json.dumps(data) ) diff --git a/plugins/markdown_preview/__init__.py b/plugins/markdown_preview/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/markdown_preview/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/markdown_preview/__main__.py b/plugins/markdown_preview/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/markdown_preview/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/markdown_preview/manifest.json b/plugins/markdown_preview/manifest.json new file mode 100644 index 0000000..3fe464b --- /dev/null +++ b/plugins/markdown_preview/manifest.json @@ -0,0 +1,11 @@ +{ + "name": "Markdown Preview", + "author": "ITDominator", + "version": "0.0.1", + "support": "", + "requests": { + "pass_events": true, + "pass_ui_objects": ["separator_right"], + "bind_keys": ["Markdown Preview||tggle_markdown_preview:m"] + } +} \ No newline at end of file diff --git a/plugins/markdown_preview/markdown/__init__.py b/plugins/markdown_preview/markdown/__init__.py new file mode 100644 index 0000000..9674d6e --- /dev/null +++ b/plugins/markdown_preview/markdown/__init__.py @@ -0,0 +1,48 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# - Documentation: https://python-markdown.github.io/ +# - GitHub: https://github.com/Python-Markdown/markdown/ +# - PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# - Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# - Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# - Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +Python-Markdown provides two public functions ([`markdown.markdown`][] and [`markdown.markdownFromFile`][]) +both of which wrap the public class [`markdown.Markdown`][]. All submodules support these public functions +and class and/or provide extension support. + +Modules: + core: Core functionality. + preprocessors: Pre-processors. + blockparser: Core Markdown block parser. + blockprocessors: Block processors. + treeprocessors: Tree processors. + inlinepatterns: Inline patterns. + postprocessors: Post-processors. + serializers: Serializers. + util: Utility functions. + htmlparser: HTML parser. + test_tools: Testing utilities. + extensions: Markdown extensions. +""" + +from __future__ import annotations + +from .core import Markdown, markdown, markdownFromFile +from .__meta__ import __version__, __version_info__ # noqa + +# For backward compatibility as some extensions expect it... +from .extensions import Extension # noqa + +__all__ = ['Markdown', 'markdown', 'markdownFromFile'] diff --git a/plugins/markdown_preview/markdown/__main__.py b/plugins/markdown_preview/markdown/__main__.py new file mode 100644 index 0000000..c323aaa --- /dev/null +++ b/plugins/markdown_preview/markdown/__main__.py @@ -0,0 +1,151 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +from __future__ import annotations + +import sys +import optparse +import codecs +import warnings +import markdown +try: + # We use `unsafe_load` because users may need to pass in actual Python + # objects. As this is only available from the CLI, the user has much + # worse problems if an attacker can use this as an attach vector. + from yaml import unsafe_load as yaml_load +except ImportError: # pragma: no cover + try: + # Fall back to PyYAML <5.1 + from yaml import load as yaml_load + except ImportError: + # Fall back to JSON + from json import load as yaml_load + +import logging +from logging import DEBUG, WARNING, CRITICAL + +logger = logging.getLogger('MARKDOWN') + + +def parse_options(args=None, values=None): + """ + Define and parse `optparse` options for command-line usage. + """ + usage = """%prog [options] [INPUTFILE] + (STDIN is assumed if no INPUTFILE is given)""" + desc = "A Python implementation of John Gruber's Markdown. " \ + "https://Python-Markdown.github.io/" + ver = "%%prog %s" % markdown.__version__ + + parser = optparse.OptionParser(usage=usage, description=desc, version=ver) + parser.add_option("-f", "--file", dest="filename", default=None, + help="Write output to OUTPUT_FILE. Defaults to STDOUT.", + metavar="OUTPUT_FILE") + parser.add_option("-e", "--encoding", dest="encoding", + help="Encoding for input and output files.",) + parser.add_option("-o", "--output_format", dest="output_format", + default='xhtml', metavar="OUTPUT_FORMAT", + help="Use output format 'xhtml' (default) or 'html'.") + parser.add_option("-n", "--no_lazy_ol", dest="lazy_ol", + action='store_false', default=True, + help="Observe number of first item of ordered lists.") + parser.add_option("-x", "--extension", action="append", dest="extensions", + help="Load extension EXTENSION.", metavar="EXTENSION") + parser.add_option("-c", "--extension_configs", + dest="configfile", default=None, + help="Read extension configurations from CONFIG_FILE. " + "CONFIG_FILE must be of JSON or YAML format. YAML " + "format requires that a python YAML library be " + "installed. The parsed JSON or YAML must result in a " + "python dictionary which would be accepted by the " + "'extension_configs' keyword on the markdown.Markdown " + "class. The extensions must also be loaded with the " + "`--extension` option.", + metavar="CONFIG_FILE") + parser.add_option("-q", "--quiet", default=CRITICAL, + action="store_const", const=CRITICAL+10, dest="verbose", + help="Suppress all warnings.") + parser.add_option("-v", "--verbose", + action="store_const", const=WARNING, dest="verbose", + help="Print all warnings.") + parser.add_option("--noisy", + action="store_const", const=DEBUG, dest="verbose", + help="Print debug messages.") + + (options, args) = parser.parse_args(args, values) + + if len(args) == 0: + input_file = None + else: + input_file = args[0] + + if not options.extensions: + options.extensions = [] + + extension_configs = {} + if options.configfile: + with codecs.open( + options.configfile, mode="r", encoding=options.encoding + ) as fp: + try: + extension_configs = yaml_load(fp) + except Exception as e: + message = "Failed parsing extension config file: %s" % \ + options.configfile + e.args = (message,) + e.args[1:] + raise + + opts = { + 'input': input_file, + 'output': options.filename, + 'extensions': options.extensions, + 'extension_configs': extension_configs, + 'encoding': options.encoding, + 'output_format': options.output_format, + 'lazy_ol': options.lazy_ol + } + + return opts, options.verbose + + +def run(): # pragma: no cover + """Run Markdown from the command line.""" + + # Parse options and adjust logging level if necessary + options, logging_level = parse_options() + if not options: + sys.exit(2) + logger.setLevel(logging_level) + console_handler = logging.StreamHandler() + logger.addHandler(console_handler) + if logging_level <= WARNING: + # Ensure deprecation warnings get displayed + warnings.filterwarnings('default') + logging.captureWarnings(True) + warn_logger = logging.getLogger('py.warnings') + warn_logger.addHandler(console_handler) + + # Run + markdown.markdownFromFile(**options) + + +if __name__ == '__main__': # pragma: no cover + # Support running module as a command line command. + # python -m markdown [options] [args] + run() diff --git a/plugins/markdown_preview/markdown/__meta__.py b/plugins/markdown_preview/markdown/__meta__.py new file mode 100644 index 0000000..21fceac --- /dev/null +++ b/plugins/markdown_preview/markdown/__meta__.py @@ -0,0 +1,51 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +# __version_info__ format: +# (major, minor, patch, dev/alpha/beta/rc/final, #) +# (1, 1, 2, 'dev', 0) => "1.1.2.dev0" +# (1, 1, 2, 'alpha', 1) => "1.1.2a1" +# (1, 2, 0, 'beta', 2) => "1.2b2" +# (1, 2, 0, 'rc', 4) => "1.2rc4" +# (1, 2, 0, 'final', 0) => "1.2" + +from __future__ import annotations + + +__version_info__ = (3, 5, 1, 'final', 0) + + +def _get_version(version_info): + " Returns a PEP 440-compliant version number from `version_info`. " + assert len(version_info) == 5 + assert version_info[3] in ('dev', 'alpha', 'beta', 'rc', 'final') + + parts = 2 if version_info[2] == 0 else 3 + v = '.'.join(map(str, version_info[:parts])) + + if version_info[3] == 'dev': + v += '.dev' + str(version_info[4]) + elif version_info[3] != 'final': + mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'} + v += mapping[version_info[3]] + str(version_info[4]) + + return v + + +__version__ = _get_version(__version_info__) diff --git a/plugins/markdown_preview/markdown/blockparser.py b/plugins/markdown_preview/markdown/blockparser.py new file mode 100644 index 0000000..549c9ec --- /dev/null +++ b/plugins/markdown_preview/markdown/blockparser.py @@ -0,0 +1,160 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +The block parser handles basic parsing of Markdown blocks. It doesn't concern +itself with inline elements such as `**bold**` or `*italics*`, but rather just +catches blocks, lists, quotes, etc. + +The `BlockParser` is made up of a bunch of `BlockProcessors`, each handling a +different type of block. Extensions may add/replace/remove `BlockProcessors` +as they need to alter how Markdown blocks are parsed. +""" + +from __future__ import annotations + +import xml.etree.ElementTree as etree +from typing import TYPE_CHECKING, Iterable, Any +from . import util + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + from .blockprocessors import BlockProcessor + + +class State(list): + """ Track the current and nested state of the parser. + + This utility class is used to track the state of the `BlockParser` and + support multiple levels if nesting. It's just a simple API wrapped around + a list. Each time a state is set, that state is appended to the end of the + list. Each time a state is reset, that state is removed from the end of + the list. + + Therefore, each time a state is set for a nested block, that state must be + reset when we back out of that level of nesting or the state could be + corrupted. + + While all the methods of a list object are available, only the three + defined below need be used. + + """ + + def set(self, state: Any): + """ Set a new state. """ + self.append(state) + + def reset(self) -> None: + """ Step back one step in nested state. """ + self.pop() + + def isstate(self, state: Any) -> bool: + """ Test that top (current) level is of given state. """ + if len(self): + return self[-1] == state + else: + return False + + +class BlockParser: + """ Parse Markdown blocks into an `ElementTree` object. + + A wrapper class that stitches the various `BlockProcessors` together, + looping through them and creating an `ElementTree` object. + + """ + + def __init__(self, md: Markdown): + """ Initialize the block parser. + + Arguments: + md: A Markdown instance. + + Attributes: + BlockParser.md (Markdown): A Markdown instance. + BlockParser.state (State): Tracks the nesting level of current location in document being parsed. + BlockParser.blockprocessors (util.Registry): A collection of + [`blockprocessors`][markdown.blockprocessors]. + + """ + self.blockprocessors: util.Registry[BlockProcessor] = util.Registry() + self.state = State() + self.md = md + + def parseDocument(self, lines: Iterable[str]) -> etree.ElementTree: + """ Parse a Markdown document into an `ElementTree`. + + Given a list of lines, an `ElementTree` object (not just a parent + `Element`) is created and the root element is passed to the parser + as the parent. The `ElementTree` object is returned. + + This should only be called on an entire document, not pieces. + + Arguments: + lines: A list of lines (strings). + + Returns: + An element tree. + """ + # Create an `ElementTree` from the lines + self.root = etree.Element(self.md.doc_tag) + self.parseChunk(self.root, '\n'.join(lines)) + return etree.ElementTree(self.root) + + def parseChunk(self, parent: etree.Element, text: str) -> None: + """ Parse a chunk of Markdown text and attach to given `etree` node. + + While the `text` argument is generally assumed to contain multiple + blocks which will be split on blank lines, it could contain only one + block. Generally, this method would be called by extensions when + block parsing is required. + + The `parent` `etree` Element passed in is altered in place. + Nothing is returned. + + Arguments: + parent: The parent element. + text: The text to parse. + + """ + self.parseBlocks(parent, text.split('\n\n')) + + def parseBlocks(self, parent: etree.Element, blocks: list[str]) -> None: + """ Process blocks of Markdown text and attach to given `etree` node. + + Given a list of `blocks`, each `blockprocessor` is stepped through + until there are no blocks left. While an extension could potentially + call this method directly, it's generally expected to be used + internally. + + This is a public method as an extension may need to add/alter + additional `BlockProcessors` which call this method to recursively + parse a nested block. + + Arguments: + parent: The parent element. + blocks: The blocks of text to parse. + + """ + while blocks: + for processor in self.blockprocessors: + if processor.test(parent, blocks[0]): + if processor.run(parent, blocks) is not False: + # run returns True or None + break diff --git a/plugins/markdown_preview/markdown/blockprocessors.py b/plugins/markdown_preview/markdown/blockprocessors.py new file mode 100644 index 0000000..d808468 --- /dev/null +++ b/plugins/markdown_preview/markdown/blockprocessors.py @@ -0,0 +1,636 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +A block processor parses blocks of text and adds new elements to the ElementTree. Blocks of text, +separated from other text by blank lines, may have a different syntax and produce a differently +structured tree than other Markdown. Block processors excel at handling code formatting, equation +layouts, tables, etc. +""" + +from __future__ import annotations + +import logging +import re +import xml.etree.ElementTree as etree +from typing import TYPE_CHECKING, Any +from . import util +from .blockparser import BlockParser + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + +logger = logging.getLogger('MARKDOWN') + + +def build_block_parser(md: Markdown, **kwargs: Any) -> BlockParser: + """ Build the default block parser used by Markdown. """ + parser = BlockParser(md) + parser.blockprocessors.register(EmptyBlockProcessor(parser), 'empty', 100) + parser.blockprocessors.register(ListIndentProcessor(parser), 'indent', 90) + parser.blockprocessors.register(CodeBlockProcessor(parser), 'code', 80) + parser.blockprocessors.register(HashHeaderProcessor(parser), 'hashheader', 70) + parser.blockprocessors.register(SetextHeaderProcessor(parser), 'setextheader', 60) + parser.blockprocessors.register(HRProcessor(parser), 'hr', 50) + parser.blockprocessors.register(OListProcessor(parser), 'olist', 40) + parser.blockprocessors.register(UListProcessor(parser), 'ulist', 30) + parser.blockprocessors.register(BlockQuoteProcessor(parser), 'quote', 20) + parser.blockprocessors.register(ReferenceProcessor(parser), 'reference', 15) + parser.blockprocessors.register(ParagraphProcessor(parser), 'paragraph', 10) + return parser + + +class BlockProcessor: + """ Base class for block processors. + + Each subclass will provide the methods below to work with the source and + tree. Each processor will need to define it's own `test` and `run` + methods. The `test` method should return True or False, to indicate + whether the current block should be processed by this processor. If the + test passes, the parser will call the processors `run` method. + + Attributes: + BlockProcessor.parser (BlockParser): The `BlockParser` instance this is attached to. + BlockProcessor.tab_length (int): The tab length set on the `Markdown` instance. + + """ + + def __init__(self, parser: BlockParser): + self.parser = parser + self.tab_length = parser.md.tab_length + + def lastChild(self, parent: etree.Element) -> etree.Element | None: + """ Return the last child of an `etree` element. """ + if len(parent): + return parent[-1] + else: + return None + + def detab(self, text: str, length: int | None = None) -> tuple[str, str]: + """ Remove a tab from the front of each line of the given text. """ + if length is None: + length = self.tab_length + newtext = [] + lines = text.split('\n') + for line in lines: + if line.startswith(' ' * length): + newtext.append(line[length:]) + elif not line.strip(): + newtext.append('') + else: + break + return '\n'.join(newtext), '\n'.join(lines[len(newtext):]) + + def looseDetab(self, text: str, level: int = 1) -> str: + """ Remove a tab from front of lines but allowing dedented lines. """ + lines = text.split('\n') + for i in range(len(lines)): + if lines[i].startswith(' '*self.tab_length*level): + lines[i] = lines[i][self.tab_length*level:] + return '\n'.join(lines) + + def test(self, parent: etree.Element, block: str) -> bool: + """ Test for block type. Must be overridden by subclasses. + + As the parser loops through processors, it will call the `test` + method on each to determine if the given block of text is of that + type. This method must return a boolean `True` or `False`. The + actual method of testing is left to the needs of that particular + block type. It could be as simple as `block.startswith(some_string)` + or a complex regular expression. As the block type may be different + depending on the parent of the block (i.e. inside a list), the parent + `etree` element is also provided and may be used as part of the test. + + Keyword arguments: + parent: An `etree` element which will be the parent of the block. + block: A block of text from the source which has been split at blank lines. + """ + pass # pragma: no cover + + def run(self, parent: etree.Element, blocks: list[str]) -> bool | None: + """ Run processor. Must be overridden by subclasses. + + When the parser determines the appropriate type of a block, the parser + will call the corresponding processor's `run` method. This method + should parse the individual lines of the block and append them to + the `etree`. + + Note that both the `parent` and `etree` keywords are pointers + to instances of the objects which should be edited in place. Each + processor must make changes to the existing objects as there is no + mechanism to return new/different objects to replace them. + + This means that this method should be adding `SubElements` or adding text + to the parent, and should remove (`pop`) or add (`insert`) items to + the list of blocks. + + If `False` is returned, this will have the same effect as returning `False` + from the `test` method. + + Keyword arguments: + parent: An `etree` element which is the parent of the current block. + blocks: A list of all remaining blocks of the document. + """ + pass # pragma: no cover + + +class ListIndentProcessor(BlockProcessor): + """ Process children of list items. + + Example + + * a list item + process this part + + or this part + + """ + + ITEM_TYPES = ['li'] + """ List of tags used for list items. """ + LIST_TYPES = ['ul', 'ol'] + """ Types of lists this processor can operate on. """ + + def __init__(self, *args): + super().__init__(*args) + self.INDENT_RE = re.compile(r'^(([ ]{%s})+)' % self.tab_length) + + def test(self, parent, block): + return block.startswith(' '*self.tab_length) and \ + not self.parser.state.isstate('detabbed') and \ + (parent.tag in self.ITEM_TYPES or + (len(parent) and parent[-1] is not None and + (parent[-1].tag in self.LIST_TYPES))) + + def run(self, parent, blocks): + block = blocks.pop(0) + level, sibling = self.get_level(parent, block) + block = self.looseDetab(block, level) + + self.parser.state.set('detabbed') + if parent.tag in self.ITEM_TYPES: + # It's possible that this parent has a `ul` or `ol` child list + # with a member. If that is the case, then that should be the + # parent. This is intended to catch the edge case of an indented + # list whose first member was parsed previous to this point + # see `OListProcessor` + if len(parent) and parent[-1].tag in self.LIST_TYPES: + self.parser.parseBlocks(parent[-1], [block]) + else: + # The parent is already a `li`. Just parse the child block. + self.parser.parseBlocks(parent, [block]) + elif sibling.tag in self.ITEM_TYPES: + # The sibling is a `li`. Use it as parent. + self.parser.parseBlocks(sibling, [block]) + elif len(sibling) and sibling[-1].tag in self.ITEM_TYPES: + # The parent is a list (`ol` or `ul`) which has children. + # Assume the last child `li` is the parent of this block. + if sibling[-1].text: + # If the parent `li` has text, that text needs to be moved to a `p` + # The `p` must be 'inserted' at beginning of list in the event + # that other children already exist i.e.; a nested sub-list. + p = etree.Element('p') + p.text = sibling[-1].text + sibling[-1].text = '' + sibling[-1].insert(0, p) + self.parser.parseChunk(sibling[-1], block) + else: + self.create_item(sibling, block) + self.parser.state.reset() + + def create_item(self, parent: etree.Element, block: str) -> None: + """ Create a new `li` and parse the block with it as the parent. """ + li = etree.SubElement(parent, 'li') + self.parser.parseBlocks(li, [block]) + + def get_level(self, parent: etree.Element, block: str) -> tuple[int, etree.Element]: + """ Get level of indentation based on list level. """ + # Get indent level + m = self.INDENT_RE.match(block) + if m: + indent_level = len(m.group(1))/self.tab_length + else: + indent_level = 0 + if self.parser.state.isstate('list'): + # We're in a tight-list - so we already are at correct parent. + level = 1 + else: + # We're in a loose-list - so we need to find parent. + level = 0 + # Step through children of tree to find matching indent level. + while indent_level > level: + child = self.lastChild(parent) + if (child is not None and + (child.tag in self.LIST_TYPES or child.tag in self.ITEM_TYPES)): + if child.tag in self.LIST_TYPES: + level += 1 + parent = child + else: + # No more child levels. If we're short of `indent_level`, + # we have a code block. So we stop here. + break + return level, parent + + +class CodeBlockProcessor(BlockProcessor): + """ Process code blocks. """ + + def test(self, parent, block): + return block.startswith(' '*self.tab_length) + + def run(self, parent, blocks): + sibling = self.lastChild(parent) + block = blocks.pop(0) + theRest = '' + if (sibling is not None and sibling.tag == "pre" and + len(sibling) and sibling[0].tag == "code"): + # The previous block was a code block. As blank lines do not start + # new code blocks, append this block to the previous, adding back + # line breaks removed from the split into a list. + code = sibling[0] + block, theRest = self.detab(block) + code.text = util.AtomicString( + '{}\n{}\n'.format(code.text, util.code_escape(block.rstrip())) + ) + else: + # This is a new code block. Create the elements and insert text. + pre = etree.SubElement(parent, 'pre') + code = etree.SubElement(pre, 'code') + block, theRest = self.detab(block) + code.text = util.AtomicString('%s\n' % util.code_escape(block.rstrip())) + if theRest: + # This block contained unindented line(s) after the first indented + # line. Insert these lines as the first block of the master blocks + # list for future processing. + blocks.insert(0, theRest) + + +class BlockQuoteProcessor(BlockProcessor): + """ Process blockquotes. """ + + RE = re.compile(r'(^|\n)[ ]{0,3}>[ ]?(.*)') + + def test(self, parent, block): + return bool(self.RE.search(block)) and not util.nearing_recursion_limit() + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + before = block[:m.start()] # Lines before blockquote + # Pass lines before blockquote in recursively for parsing first. + self.parser.parseBlocks(parent, [before]) + # Remove `> ` from beginning of each line. + block = '\n'.join( + [self.clean(line) for line in block[m.start():].split('\n')] + ) + sibling = self.lastChild(parent) + if sibling is not None and sibling.tag == "blockquote": + # Previous block was a blockquote so set that as this blocks parent + quote = sibling + else: + # This is a new blockquote. Create a new parent element. + quote = etree.SubElement(parent, 'blockquote') + # Recursively parse block with blockquote as parent. + # change parser state so blockquotes embedded in lists use `p` tags + self.parser.state.set('blockquote') + self.parser.parseChunk(quote, block) + self.parser.state.reset() + + def clean(self, line: str) -> str: + """ Remove `>` from beginning of a line. """ + m = self.RE.match(line) + if line.strip() == ">": + return "" + elif m: + return m.group(2) + else: + return line + + +class OListProcessor(BlockProcessor): + """ Process ordered list blocks. """ + + TAG: str = 'ol' + """ The tag used for the the wrapping element. """ + STARTSWITH: str = '1' + """ + The integer (as a string ) with which the list starts. For example, if a list is initialized as + `3. Item`, then the `ol` tag will be assigned an HTML attribute of `starts="3"`. Default: `"1"`. + """ + LAZY_OL: bool = True + """ Ignore `STARTSWITH` if `True`. """ + SIBLING_TAGS: list[str] = ['ol', 'ul'] + """ + Markdown does not require the type of a new list item match the previous list item type. + This is the list of types which can be mixed. + """ + + def __init__(self, parser: BlockParser): + super().__init__(parser) + # Detect an item (`1. item`). `group(1)` contains contents of item. + self.RE = re.compile(r'^[ ]{0,%d}\d+\.[ ]+(.*)' % (self.tab_length - 1)) + # Detect items on secondary lines. they can be of either list type. + self.CHILD_RE = re.compile(r'^[ ]{0,%d}((\d+\.)|[*+-])[ ]+(.*)' % + (self.tab_length - 1)) + # Detect indented (nested) items of either type + self.INDENT_RE = re.compile(r'^[ ]{%d,%d}((\d+\.)|[*+-])[ ]+.*' % + (self.tab_length, self.tab_length * 2 - 1)) + + def test(self, parent, block): + return bool(self.RE.match(block)) + + def run(self, parent, blocks): + # Check for multiple items in one block. + items = self.get_items(blocks.pop(0)) + sibling = self.lastChild(parent) + + if sibling is not None and sibling.tag in self.SIBLING_TAGS: + # Previous block was a list item, so set that as parent + lst = sibling + # make sure previous item is in a `p` - if the item has text, + # then it isn't in a `p` + if lst[-1].text: + # since it's possible there are other children for this + # sibling, we can't just `SubElement` the `p`, we need to + # insert it as the first item. + p = etree.Element('p') + p.text = lst[-1].text + lst[-1].text = '' + lst[-1].insert(0, p) + # if the last item has a tail, then the tail needs to be put in a `p` + # likely only when a header is not followed by a blank line + lch = self.lastChild(lst[-1]) + if lch is not None and lch.tail: + p = etree.SubElement(lst[-1], 'p') + p.text = lch.tail.lstrip() + lch.tail = '' + + # parse first block differently as it gets wrapped in a `p`. + li = etree.SubElement(lst, 'li') + self.parser.state.set('looselist') + firstitem = items.pop(0) + self.parser.parseBlocks(li, [firstitem]) + self.parser.state.reset() + elif parent.tag in ['ol', 'ul']: + # this catches the edge case of a multi-item indented list whose + # first item is in a blank parent-list item: + # * * subitem1 + # * subitem2 + # see also `ListIndentProcessor` + lst = parent + else: + # This is a new list so create parent with appropriate tag. + lst = etree.SubElement(parent, self.TAG) + # Check if a custom start integer is set + if not self.LAZY_OL and self.STARTSWITH != '1': + lst.attrib['start'] = self.STARTSWITH + + self.parser.state.set('list') + # Loop through items in block, recursively parsing each with the + # appropriate parent. + for item in items: + if item.startswith(' '*self.tab_length): + # Item is indented. Parse with last item as parent + self.parser.parseBlocks(lst[-1], [item]) + else: + # New item. Create `li` and parse with it as parent + li = etree.SubElement(lst, 'li') + self.parser.parseBlocks(li, [item]) + self.parser.state.reset() + + def get_items(self, block: str) -> list[str]: + """ Break a block into list items. """ + items = [] + for line in block.split('\n'): + m = self.CHILD_RE.match(line) + if m: + # This is a new list item + # Check first item for the start index + if not items and self.TAG == 'ol': + # Detect the integer value of first list item + INTEGER_RE = re.compile(r'(\d+)') + self.STARTSWITH = INTEGER_RE.match(m.group(1)).group() + # Append to the list + items.append(m.group(3)) + elif self.INDENT_RE.match(line): + # This is an indented (possibly nested) item. + if items[-1].startswith(' '*self.tab_length): + # Previous item was indented. Append to that item. + items[-1] = '{}\n{}'.format(items[-1], line) + else: + items.append(line) + else: + # This is another line of previous item. Append to that item. + items[-1] = '{}\n{}'.format(items[-1], line) + return items + + +class UListProcessor(OListProcessor): + """ Process unordered list blocks. """ + + TAG: str = 'ul' + """ The tag used for the the wrapping element. """ + + def __init__(self, parser: BlockParser): + super().__init__(parser) + # Detect an item (`1. item`). `group(1)` contains contents of item. + self.RE = re.compile(r'^[ ]{0,%d}[*+-][ ]+(.*)' % (self.tab_length - 1)) + + +class HashHeaderProcessor(BlockProcessor): + """ Process Hash Headers. """ + + # Detect a header at start of any line in block + RE = re.compile(r'(?:^|\n)(?P#{1,6})(?P
(?:\\.|[^\\])*?)#*(?:\n|$)') + + def test(self, parent, block): + return bool(self.RE.search(block)) + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + before = block[:m.start()] # All lines before header + after = block[m.end():] # All lines after header + if before: + # As the header was not the first line of the block and the + # lines before the header must be parsed first, + # recursively parse this lines as a block. + self.parser.parseBlocks(parent, [before]) + # Create header using named groups from RE + h = etree.SubElement(parent, 'h%d' % len(m.group('level'))) + h.text = m.group('header').strip() + if after: + # Insert remaining lines as first block for future parsing. + blocks.insert(0, after) + else: # pragma: no cover + # This should never happen, but just in case... + logger.warn("We've got a problem header: %r" % block) + + +class SetextHeaderProcessor(BlockProcessor): + """ Process Setext-style Headers. """ + + # Detect Setext-style header. Must be first 2 lines of block. + RE = re.compile(r'^.*?\n[=-]+[ ]*(\n|$)', re.MULTILINE) + + def test(self, parent, block): + return bool(self.RE.match(block)) + + def run(self, parent, blocks): + lines = blocks.pop(0).split('\n') + # Determine level. `=` is 1 and `-` is 2. + if lines[1].startswith('='): + level = 1 + else: + level = 2 + h = etree.SubElement(parent, 'h%d' % level) + h.text = lines[0].strip() + if len(lines) > 2: + # Block contains additional lines. Add to master blocks for later. + blocks.insert(0, '\n'.join(lines[2:])) + + +class HRProcessor(BlockProcessor): + """ Process Horizontal Rules. """ + + # Python's `re` module doesn't officially support atomic grouping. However you can fake it. + # See https://stackoverflow.com/a/13577411/866026 + RE = r'^[ ]{0,3}(?=(?P(-+[ ]{0,2}){3,}|(_+[ ]{0,2}){3,}|(\*+[ ]{0,2}){3,}))(?P=atomicgroup)[ ]*$' + # Detect hr on any line of a block. + SEARCH_RE = re.compile(RE, re.MULTILINE) + + def test(self, parent, block): + m = self.SEARCH_RE.search(block) + if m: + # Save match object on class instance so we can use it later. + self.match = m + return True + return False + + def run(self, parent, blocks): + block = blocks.pop(0) + match = self.match + # Check for lines in block before `hr`. + prelines = block[:match.start()].rstrip('\n') + if prelines: + # Recursively parse lines before `hr` so they get parsed first. + self.parser.parseBlocks(parent, [prelines]) + # create hr + etree.SubElement(parent, 'hr') + # check for lines in block after `hr`. + postlines = block[match.end():].lstrip('\n') + if postlines: + # Add lines after `hr` to master blocks for later parsing. + blocks.insert(0, postlines) + + +class EmptyBlockProcessor(BlockProcessor): + """ Process blocks that are empty or start with an empty line. """ + + def test(self, parent, block): + return not block or block.startswith('\n') + + def run(self, parent, blocks): + block = blocks.pop(0) + filler = '\n\n' + if block: + # Starts with empty line + # Only replace a single line. + filler = '\n' + # Save the rest for later. + theRest = block[1:] + if theRest: + # Add remaining lines to master blocks for later. + blocks.insert(0, theRest) + sibling = self.lastChild(parent) + if (sibling is not None and sibling.tag == 'pre' and + len(sibling) and sibling[0].tag == 'code'): + # Last block is a code block. Append to preserve whitespace. + sibling[0].text = util.AtomicString( + '{}{}'.format(sibling[0].text, filler) + ) + + +class ReferenceProcessor(BlockProcessor): + """ Process link references. """ + RE = re.compile( + r'^[ ]{0,3}\[([^\[\]]*)\]:[ ]*\n?[ ]*([^\s]+)[ ]*(?:\n[ ]*)?((["\'])(.*)\4[ ]*|\((.*)\)[ ]*)?$', re.MULTILINE + ) + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + if m: + id = m.group(1).strip().lower() + link = m.group(2).lstrip('<').rstrip('>') + title = m.group(5) or m.group(6) + self.parser.md.references[id] = (link, title) + if block[m.end():].strip(): + # Add any content after match back to blocks as separate block + blocks.insert(0, block[m.end():].lstrip('\n')) + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + +class ParagraphProcessor(BlockProcessor): + """ Process Paragraph blocks. """ + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + block = blocks.pop(0) + if block.strip(): + # Not a blank block. Add to parent, otherwise throw it away. + if self.parser.state.isstate('list'): + # The parent is a tight-list. + # + # Check for any children. This will likely only happen in a + # tight-list when a header isn't followed by a blank line. + # For example: + # + # * # Header + # Line 2 of list item - not part of header. + sibling = self.lastChild(parent) + if sibling is not None: + # Insert after sibling. + if sibling.tail: + sibling.tail = '{}\n{}'.format(sibling.tail, block) + else: + sibling.tail = '\n%s' % block + else: + # Append to parent.text + if parent.text: + parent.text = '{}\n{}'.format(parent.text, block) + else: + parent.text = block.lstrip() + else: + # Create a regular paragraph + p = etree.SubElement(parent, 'p') + p.text = block.lstrip() diff --git a/plugins/markdown_preview/markdown/core.py b/plugins/markdown_preview/markdown/core.py new file mode 100644 index 0000000..6b556b4 --- /dev/null +++ b/plugins/markdown_preview/markdown/core.py @@ -0,0 +1,510 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +from __future__ import annotations + +import codecs +import sys +import logging +import importlib +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Mapping, Sequence, TextIO +from . import util +from .preprocessors import build_preprocessors +from .blockprocessors import build_block_parser +from .treeprocessors import build_treeprocessors +from .inlinepatterns import build_inlinepatterns +from .postprocessors import build_postprocessors +from .extensions import Extension +from .serializers import to_html_string, to_xhtml_string +from .util import BLOCK_LEVEL_ELEMENTS + +if TYPE_CHECKING: # pragma: no cover + from xml.etree.ElementTree import Element + +__all__ = ['Markdown', 'markdown', 'markdownFromFile'] + + +logger = logging.getLogger('MARKDOWN') + + +class Markdown: + """ + A parser which converts Markdown to HTML. + + Attributes: + Markdown.tab_length (int): The number of spaces which correspond to a single tab. Default: `4`. + Markdown.ESCAPED_CHARS (list[str]): List of characters which get the backslash escape treatment. + Markdown.block_level_elements (list[str]): List of HTML tags which get treated as block-level elements. + See [`markdown.util.BLOCK_LEVEL_ELEMENTS`][] for the full list of elements. + Markdown.registeredExtensions (list[Extension]): List of extensions which have called + [`registerExtension`][markdown.Markdown.registerExtension] during setup. + Markdown.doc_tag (str): Element used to wrap document. Default: `div`. + Markdown.stripTopLevelTags (bool): Indicates whether the `doc_tag` should be removed. Default: 'True'. + Markdown.references (dict[str, tuple[str, str]]): A mapping of link references found in a parsed document + where the key is the reference name and the value is a tuple of the URL and title. + Markdown.htmlStash (util.HtmlStash): The instance of the `HtmlStash` used by an instance of this class. + Markdown.output_formats (dict[str, Callable[xml.etree.ElementTree.Element]]): A mapping of known output + formats by name and their respective serializers. Each serializer must be a callable which accepts an + [`Element`][xml.etree.ElementTree.Element] and returns a `str`. + Markdown.output_format (str): The output format set by + [`set_output_format`][markdown.Markdown.set_output_format]. + Markdown.serializer (Callable[xml.etree.ElementTree.Element]): The serializer set by + [`set_output_format`][markdown.Markdown.set_output_format]. + Markdown.preprocessors (util.Registry): A collection of [`preprocessors`][markdown.preprocessors]. + Markdown.parser (blockparser.BlockParser): A collection of [`blockprocessors`][markdown.blockprocessors]. + Markdown.inlinePatterns (util.Registry): A collection of [`inlinepatterns`][markdown.inlinepatterns]. + Markdown.treeprocessors (util.Registry): A collection of [`treeprocessors`][markdown.treeprocessors]. + Markdown.postprocessors (util.Registry): A collection of [`postprocessors`][markdown.postprocessors]. + + """ + + doc_tag = "div" # Element used to wrap document - later removed + + output_formats: ClassVar[dict[str, Callable[[Element], str]]] = { + 'html': to_html_string, + 'xhtml': to_xhtml_string, + } + """ + A mapping of known output formats by name and their respective serializers. Each serializer must be a + callable which accepts an [`Element`][xml.etree.ElementTree.Element] and returns a `str`. + """ + + def __init__(self, **kwargs): + """ + Creates a new Markdown instance. + + Keyword Arguments: + extensions (list[Extension | str]): A list of extensions. + + If an item is an instance of a subclass of [`markdown.extensions.Extension`][], + the instance will be used as-is. If an item is of type `str`, it is passed + to [`build_extension`][markdown.Markdown.build_extension] with its corresponding + `extension_configs` and the returned instance of [`markdown.extensions.Extension`][] + is used. + extension_configs (dict[str, dict[str, Any]]): Configuration settings for extensions. + output_format (str): Format of output. Supported formats are: + + * `xhtml`: Outputs XHTML style tags. Default. + * `html`: Outputs HTML style tags. + tab_length (int): Length of tabs in the source. Default: `4` + + """ + + self.tab_length: int = kwargs.get('tab_length', 4) + + self.ESCAPED_CHARS: list[str] = [ + '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!' + ] + """ List of characters which get the backslash escape treatment. """ + + self.block_level_elements: list[str] = BLOCK_LEVEL_ELEMENTS.copy() + + self.registeredExtensions: list[Extension] = [] + self.docType = "" # TODO: Maybe delete this. It does not appear to be used anymore. + self.stripTopLevelTags: bool = True + + self.build_parser() + + self.references: dict[str, tuple[str, str]] = {} + self.htmlStash: util.HtmlStash = util.HtmlStash() + self.registerExtensions(extensions=kwargs.get('extensions', []), + configs=kwargs.get('extension_configs', {})) + self.set_output_format(kwargs.get('output_format', 'xhtml')) + self.reset() + + def build_parser(self) -> Markdown: + """ + Build the parser from the various parts. + + Assigns a value to each of the following attributes on the class instance: + + * **`Markdown.preprocessors`** ([`Registry`][markdown.util.Registry]) -- A collection of + [`preprocessors`][markdown.preprocessors]. + * **`Markdown.parser`** ([`BlockParser`][markdown.blockparser.BlockParser]) -- A collection of + [`blockprocessors`][markdown.blockprocessors]. + * **`Markdown.inlinePatterns`** ([`Registry`][markdown.util.Registry]) -- A collection of + [`inlinepatterns`][markdown.inlinepatterns]. + * **`Markdown.treeprocessors`** ([`Registry`][markdown.util.Registry]) -- A collection of + [`treeprocessors`][markdown.treeprocessors]. + * **`Markdown.postprocessors`** ([`Registry`][markdown.util.Registry]) -- A collection of + [`postprocessors`][markdown.postprocessors]. + + This method could be redefined in a subclass to build a custom parser which is made up of a different + combination of processors and patterns. + + """ + self.preprocessors = build_preprocessors(self) + self.parser = build_block_parser(self) + self.inlinePatterns = build_inlinepatterns(self) + self.treeprocessors = build_treeprocessors(self) + self.postprocessors = build_postprocessors(self) + return self + + def registerExtensions( + self, + extensions: Sequence[Extension | str], + configs: Mapping[str, Mapping[str, Any]] + ) -> Markdown: + """ + Load a list of extensions into an instance of the `Markdown` class. + + Arguments: + extensions (list[Extension | str]): A list of extensions. + + If an item is an instance of a subclass of [`markdown.extensions.Extension`][], + the instance will be used as-is. If an item is of type `str`, it is passed + to [`build_extension`][markdown.Markdown.build_extension] with its corresponding `configs` and the + returned instance of [`markdown.extensions.Extension`][] is used. + configs (dict[str, dict[str, Any]]): Configuration settings for extensions. + + """ + for ext in extensions: + if isinstance(ext, str): + ext = self.build_extension(ext, configs.get(ext, {})) + if isinstance(ext, Extension): + ext.extendMarkdown(self) + logger.debug( + 'Successfully loaded extension "%s.%s".' + % (ext.__class__.__module__, ext.__class__.__name__) + ) + elif ext is not None: + raise TypeError( + 'Extension "{}.{}" must be of type: "{}.{}"'.format( + ext.__class__.__module__, ext.__class__.__name__, + Extension.__module__, Extension.__name__ + ) + ) + return self + + def build_extension(self, ext_name: str, configs: Mapping[str, Any]) -> Extension: + """ + Build extension from a string name, then return an instance using the given `configs`. + + Arguments: + ext_name: Name of extension as a string. + configs: Configuration settings for extension. + + Returns: + An instance of the extension with the given configuration settings. + + First attempt to load an entry point. The string name must be registered as an entry point in the + `markdown.extensions` group which points to a subclass of the [`markdown.extensions.Extension`][] class. + If multiple distributions have registered the same name, the first one found is returned. + + If no entry point is found, assume dot notation (`path.to.module:ClassName`). Load the specified class and + return an instance. If no class is specified, import the module and call a `makeExtension` function and return + the [`markdown.extensions.Extension`][] instance returned by that function. + """ + configs = dict(configs) + + entry_points = [ep for ep in util.get_installed_extensions() if ep.name == ext_name] + if entry_points: + ext = entry_points[0].load() + return ext(**configs) + + # Get class name (if provided): `path.to.module:ClassName` + ext_name, class_name = ext_name.split(':', 1) if ':' in ext_name else (ext_name, '') + + try: + module = importlib.import_module(ext_name) + logger.debug( + 'Successfully imported extension module "%s".' % ext_name + ) + except ImportError as e: + message = 'Failed loading extension "%s".' % ext_name + e.args = (message,) + e.args[1:] + raise + + if class_name: + # Load given class name from module. + return getattr(module, class_name)(**configs) + else: + # Expect `makeExtension()` function to return a class. + try: + return module.makeExtension(**configs) + except AttributeError as e: + message = e.args[0] + message = "Failed to initiate extension " \ + "'%s': %s" % (ext_name, message) + e.args = (message,) + e.args[1:] + raise + + def registerExtension(self, extension: Extension) -> Markdown: + """ + Register an extension as having a resettable state. + + Arguments: + extension: An instance of the extension to register. + + This should get called once by an extension during setup. A "registered" extension's + `reset` method is called by [`Markdown.reset()`][markdown.Markdown.reset]. Not all extensions have or need a + resettable state, and so it should not be assumed that all extensions are "registered." + + """ + self.registeredExtensions.append(extension) + return self + + def reset(self) -> Markdown: + """ + Resets all state variables to prepare the parser instance for new input. + + Called once upon creation of a class instance. Should be called manually between calls + to [`Markdown.convert`][markdown.Markdown.convert]. + """ + self.htmlStash.reset() + self.references.clear() + + for extension in self.registeredExtensions: + if hasattr(extension, 'reset'): + extension.reset() + + return self + + def set_output_format(self, format: str) -> Markdown: + """ + Set the output format for the class instance. + + Arguments: + format: Must be a known value in `Markdown.output_formats`. + + """ + self.output_format = format.lower().rstrip('145') # ignore number + try: + self.serializer = self.output_formats[self.output_format] + except KeyError as e: + valid_formats = list(self.output_formats.keys()) + valid_formats.sort() + message = 'Invalid Output Format: "%s". Use one of %s.' \ + % (self.output_format, + '"' + '", "'.join(valid_formats) + '"') + e.args = (message,) + e.args[1:] + raise + return self + + # Note: the `tag` argument is type annotated `Any` as ElementTree uses many various objects as tags. + # As there is no standardization in ElementTree, the type of a given tag is unpredictable. + def is_block_level(self, tag: Any) -> bool: + """ + Check if the given `tag` is a block level HTML tag. + + Returns `True` for any string listed in `Markdown.block_level_elements`. A `tag` which is + not a string always returns `False`. + + """ + if isinstance(tag, str): + return tag.lower().rstrip('/') in self.block_level_elements + # Some ElementTree tags are not strings, so return False. + return False + + def convert(self, source: str) -> str: + """ + Convert a Markdown string to a string in the specified output format. + + Arguments: + source: Markdown formatted text as Unicode or ASCII string. + + Returns: + A string in the specified output format. + + Markdown parsing takes place in five steps: + + 1. A bunch of [`preprocessors`][markdown.preprocessors] munge the input text. + 2. A [`BlockParser`][markdown.blockparser.BlockParser] parses the high-level structural elements of the + pre-processed text into an [`ElementTree`][xml.etree.ElementTree.ElementTree] object. + 3. A bunch of [`treeprocessors`][markdown.treeprocessors] are run against the + [`ElementTree`][xml.etree.ElementTree.ElementTree] object. One such `treeprocessor` + ([`markdown.treeprocessors.InlineProcessor`][]) runs [`inlinepatterns`][markdown.inlinepatterns] + against the [`ElementTree`][xml.etree.ElementTree.ElementTree] object, parsing inline markup. + 4. Some [`postprocessors`][markdown.postprocessors] are run against the text after the + [`ElementTree`][xml.etree.ElementTree.ElementTree] object has been serialized into text. + 5. The output is returned as a string. + + """ + + # Fix up the source text + if not source.strip(): + return '' # a blank Unicode string + + try: + source = str(source) + except UnicodeDecodeError as e: # pragma: no cover + # Customize error message while maintaining original traceback + e.reason += '. -- Note: Markdown only accepts Unicode input!' + raise + + # Split into lines and run the line preprocessors. + self.lines = source.split("\n") + for prep in self.preprocessors: + self.lines = prep.run(self.lines) + + # Parse the high-level elements. + root = self.parser.parseDocument(self.lines).getroot() + + # Run the tree-processors + for treeprocessor in self.treeprocessors: + newRoot = treeprocessor.run(root) + if newRoot is not None: + root = newRoot + + # Serialize _properly_. Strip top-level tags. + output = self.serializer(root) + if self.stripTopLevelTags: + try: + start = output.index( + '<%s>' % self.doc_tag) + len(self.doc_tag) + 2 + end = output.rindex('' % self.doc_tag) + output = output[start:end].strip() + except ValueError as e: # pragma: no cover + if output.strip().endswith('<%s />' % self.doc_tag): + # We have an empty document + output = '' + else: + # We have a serious problem + raise ValueError('Markdown failed to strip top-level ' + 'tags. Document=%r' % output.strip()) from e + + # Run the text post-processors + for pp in self.postprocessors: + output = pp.run(output) + + return output.strip() + + def convertFile( + self, + input: str | TextIO | None = None, + output: str | TextIO | None = None, + encoding: str | None = None, + ) -> Markdown: + """ + Converts a Markdown file and returns the HTML as a Unicode string. + + Decodes the file using the provided encoding (defaults to `utf-8`), + passes the file content to markdown, and outputs the HTML to either + the provided stream or the file with provided name, using the same + encoding as the source file. The + [`xmlcharrefreplace`](https://docs.python.org/3/library/codecs.html#error-handlers) + error handler is used when encoding the output. + + **Note:** This is the only place that decoding and encoding of Unicode + takes place in Python-Markdown. (All other code is Unicode-in / + Unicode-out.) + + Arguments: + input: File object or path. Reads from `stdin` if `None`. + output: File object or path. Writes to `stdout` if `None`. + encoding: Encoding of input and output files. Defaults to `utf-8`. + + """ + + encoding = encoding or "utf-8" + + # Read the source + if input: + if isinstance(input, str): + input_file = codecs.open(input, mode="r", encoding=encoding) + else: + input_file = codecs.getreader(encoding)(input) + text = input_file.read() + input_file.close() + else: + text = sys.stdin.read() + if not isinstance(text, str): # pragma: no cover + text = text.decode(encoding) + + text = text.lstrip('\ufeff') # remove the byte-order mark + + # Convert + html = self.convert(text) + + # Write to file or stdout + if output: + if isinstance(output, str): + output_file = codecs.open(output, "w", + encoding=encoding, + errors="xmlcharrefreplace") + output_file.write(html) + output_file.close() + else: + writer = codecs.getwriter(encoding) + output_file = writer(output, errors="xmlcharrefreplace") + output_file.write(html) + # Don't close here. User may want to write more. + else: + # Encode manually and write bytes to stdout. + html = html.encode(encoding, "xmlcharrefreplace") + try: + # Write bytes directly to buffer (Python 3). + sys.stdout.buffer.write(html) + except AttributeError: # pragma: no cover + # Probably Python 2, which works with bytes by default. + sys.stdout.write(html) + + return self + + +""" +EXPORTED FUNCTIONS +============================================================================= + +Those are the two functions we really mean to export: `markdown()` and +`markdownFromFile()`. +""" + + +def markdown(text: str, **kwargs: Any) -> str: + """ + Convert a markdown string to HTML and return HTML as a Unicode string. + + This is a shortcut function for [`Markdown`][markdown.Markdown] class to cover the most + basic use case. It initializes an instance of [`Markdown`][markdown.Markdown], loads the + necessary extensions and runs the parser on the given text. + + Arguments: + text: Markdown formatted text as Unicode or ASCII string. + + Keyword arguments: + **kwargs: Any arguments accepted by the Markdown class. + + Returns: + A string in the specified output format. + + """ + md = Markdown(**kwargs) + return md.convert(text) + + +def markdownFromFile(**kwargs: Any): + """ + Read Markdown text from a file and write output to a file or a stream. + + This is a shortcut function which initializes an instance of [`Markdown`][markdown.Markdown], + and calls the [`convertFile`][markdown.Markdown.convertFile] method rather than + [`convert`][markdown.Markdown.convert]. + + Keyword arguments: + input (str | TextIO): A file name or readable object. + output (str | TextIO): A file name or writable object. + encoding (str): Encoding of input and output. + **kwargs: Any arguments accepted by the `Markdown` class. + + """ + md = Markdown(**kwargs) + md.convertFile(kwargs.get('input', None), + kwargs.get('output', None), + kwargs.get('encoding', None)) diff --git a/plugins/markdown_preview/markdown/extensions/__init__.py b/plugins/markdown_preview/markdown/extensions/__init__.py new file mode 100644 index 0000000..070c4cc --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/__init__.py @@ -0,0 +1,145 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +Markdown accepts an [`Extension`][markdown.extensions.Extension] instance for each extension. Therefore, each extension +must to define a class that extends [`Extension`][markdown.extensions.Extension] and over-rides the +[`extendMarkdown`][markdown.extensions.Extension.extendMarkdown] method. Within this class one can manage configuration +options for their extension and attach the various processors and patterns which make up an extension to the +[`Markdown`][markdown.Markdown] instance. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Mapping, Sequence +from ..util import parseBoolValue + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + + +class Extension: + """ Base class for extensions to subclass. """ + + config: Mapping[str, list] = {} + """ + Default configuration for an extension. + + This attribute is to be defined in a subclass and must be of the following format: + + ``` python + config = { + 'key': ['value', 'description'] + } + ``` + + Note that [`setConfig`][markdown.extensions.Extension.setConfig] will raise a [`KeyError`][] + if a default is not set for each option. + """ + + def __init__(self, **kwargs): + """ Initiate Extension and set up configs. """ + self.setConfigs(kwargs) + + def getConfig(self, key: str, default: Any = '') -> Any: + """ + Return a single configuration option value. + + Arguments: + key: The configuration option name. + default: Default value to return if key is not set. + + Returns: + Value of stored configuration option. + """ + if key in self.config: + return self.config[key][0] + else: + return default + + def getConfigs(self) -> dict[str, Any]: + """ + Return all configuration options. + + Returns: + All configuration options. + """ + return {key: self.getConfig(key) for key in self.config.keys()} + + def getConfigInfo(self) -> list[tuple[str, str]]: + """ + Return descriptions of all configuration options. + + Returns: + All descriptions of configuration options. + """ + return [(key, self.config[key][1]) for key in self.config.keys()] + + def setConfig(self, key: str, value: Any) -> None: + """ + Set a configuration option. + + If the corresponding default value set in [`config`][markdown.extensions.Extension.config] + is a `bool` value or `None`, then `value` is passed through + [`parseBoolValue`][markdown.util.parseBoolValue] before being stored. + + Arguments: + key: Name of configuration option to set. + value: Value to assign to option. + + Raises: + KeyError: If `key` is not known. + """ + if isinstance(self.config[key][0], bool): + value = parseBoolValue(value) + if self.config[key][0] is None: + value = parseBoolValue(value, preserve_none=True) + self.config[key][0] = value + + def setConfigs(self, items: Mapping[str, Any] | Sequence[tuple[str, Any]]): + """ + Loop through a collection of configuration options, passing each to + [`setConfig`][markdown.extensions.Extension.setConfig]. + + Arguments: + items: Collection of configuration options. + + Raises: + KeyError: for any unknown key. + """ + if hasattr(items, 'items'): + # it's a dict + items = items.items() + for key, value in items: + self.setConfig(key, value) + + def extendMarkdown(self, md: Markdown) -> None: + """ + Add the various processors and patterns to the Markdown Instance. + + This method must be overridden by every extension. + + Arguments: + md: The Markdown instance. + + """ + raise NotImplementedError( + 'Extension "%s.%s" must define an "extendMarkdown"' + 'method.' % (self.__class__.__module__, self.__class__.__name__) + ) diff --git a/plugins/markdown_preview/markdown/extensions/abbr.py b/plugins/markdown_preview/markdown/extensions/abbr.py new file mode 100644 index 0000000..c060f47 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/abbr.py @@ -0,0 +1,105 @@ +# Abbreviation Extension for Python-Markdown +# ========================================== + +# This extension adds abbreviation handling to Python-Markdown. + +# See https://Python-Markdown.github.io/extensions/abbreviations +# for documentation. + +# Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/) +# and [Seemant Kulleen](http://www.kulleen.org/) + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +This extension adds abbreviation handling to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/abbreviations) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor +from ..inlinepatterns import InlineProcessor +from ..util import AtomicString +import re +import xml.etree.ElementTree as etree + + +class AbbrExtension(Extension): + """ Abbreviation Extension for Python-Markdown. """ + + def extendMarkdown(self, md): + """ Insert `AbbrPreprocessor` before `ReferencePreprocessor`. """ + md.parser.blockprocessors.register(AbbrPreprocessor(md.parser), 'abbr', 16) + + +class AbbrPreprocessor(BlockProcessor): + """ Abbreviation Preprocessor - parse text for abbr references. """ + + RE = re.compile(r'^[*]\[(?P[^\]]*)\][ ]?:[ ]*\n?[ ]*(?P.*)$', re.MULTILINE) + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + """ + Find and remove all Abbreviation references from the text. + Each reference is set as a new `AbbrPattern` in the markdown instance. + + """ + block = blocks.pop(0) + m = self.RE.search(block) + if m: + abbr = m.group('abbr').strip() + title = m.group('title').strip() + self.parser.md.inlinePatterns.register( + AbbrInlineProcessor(self._generate_pattern(abbr), title), 'abbr-%s' % abbr, 2 + ) + if block[m.end():].strip(): + # Add any content after match back to blocks as separate block + blocks.insert(0, block[m.end():].lstrip('\n')) + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + def _generate_pattern(self, text): + """ + Given a string, returns an regex pattern to match that string. + + 'HTML' -> r'(?P<abbr>[H][T][M][L])' + + Note: we force each char as a literal match (in brackets) as we don't + know what they will be beforehand. + + """ + chars = list(text) + for i in range(len(chars)): + chars[i] = r'[%s]' % chars[i] + return r'(?P<abbr>\b%s\b)' % (r''.join(chars)) + + +class AbbrInlineProcessor(InlineProcessor): + """ Abbreviation inline pattern. """ + + def __init__(self, pattern, title): + super().__init__(pattern) + self.title = title + + def handleMatch(self, m, data): + abbr = etree.Element('abbr') + abbr.text = AtomicString(m.group('abbr')) + abbr.set('title', self.title) + return abbr, m.start(0), m.end(0) + + +def makeExtension(**kwargs): # pragma: no cover + return AbbrExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/admonition.py b/plugins/markdown_preview/markdown/extensions/admonition.py new file mode 100644 index 0000000..f05d089 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/admonition.py @@ -0,0 +1,179 @@ +# Admonition extension for Python-Markdown +# ======================================== + +# Adds rST-style admonitions. Inspired by [rST][] feature with the same name. + +# [rST]: http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions + +# See https://Python-Markdown.github.io/extensions/admonition +# for documentation. + +# Original code Copyright [Tiago Serafim](https://www.tiagoserafim.com/). + +# All changes Copyright The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + + +""" +Adds rST-style admonitions. Inspired by [rST][] feature with the same name. + +[rST]: http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions + +See the [documentation](https://Python-Markdown.github.io/extensions/admonition) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor +import xml.etree.ElementTree as etree +import re + + +class AdmonitionExtension(Extension): + """ Admonition extension for Python-Markdown. """ + + def extendMarkdown(self, md): + """ Add Admonition to Markdown instance. """ + md.registerExtension(self) + + md.parser.blockprocessors.register(AdmonitionProcessor(md.parser), 'admonition', 105) + + +class AdmonitionProcessor(BlockProcessor): + + CLASSNAME = 'admonition' + CLASSNAME_TITLE = 'admonition-title' + RE = re.compile(r'(?:^|\n)!!! ?([\w\-]+(?: +[\w\-]+)*)(?: +"(.*?)")? *(?:\n|$)') + RE_SPACES = re.compile(' +') + + def __init__(self, parser): + """Initialization.""" + + super().__init__(parser) + + self.current_sibling = None + self.content_indention = 0 + + def parse_content(self, parent, block): + """Get sibling admonition. + + Retrieve the appropriate sibling element. This can get tricky when + dealing with lists. + + """ + + old_block = block + the_rest = '' + + # We already acquired the block via test + if self.current_sibling is not None: + sibling = self.current_sibling + block, the_rest = self.detab(block, self.content_indent) + self.current_sibling = None + self.content_indent = 0 + return sibling, block, the_rest + + sibling = self.lastChild(parent) + + if sibling is None or sibling.tag != 'div' or sibling.get('class', '').find(self.CLASSNAME) == -1: + sibling = None + else: + # If the last child is a list and the content is sufficiently indented + # to be under it, then the content's sibling is in the list. + last_child = self.lastChild(sibling) + indent = 0 + while last_child is not None: + if ( + sibling is not None and block.startswith(' ' * self.tab_length * 2) and + last_child is not None and last_child.tag in ('ul', 'ol', 'dl') + ): + + # The expectation is that we'll find an `<li>` or `<dt>`. + # We should get its last child as well. + sibling = self.lastChild(last_child) + last_child = self.lastChild(sibling) if sibling is not None else None + + # Context has been lost at this point, so we must adjust the + # text's indentation level so it will be evaluated correctly + # under the list. + block = block[self.tab_length:] + indent += self.tab_length + else: + last_child = None + + if not block.startswith(' ' * self.tab_length): + sibling = None + + if sibling is not None: + indent += self.tab_length + block, the_rest = self.detab(old_block, indent) + self.current_sibling = sibling + self.content_indent = indent + + return sibling, block, the_rest + + def test(self, parent, block): + + if self.RE.search(block): + return True + else: + return self.parse_content(parent, block)[0] is not None + + def run(self, parent, blocks): + block = blocks.pop(0) + m = self.RE.search(block) + + if m: + if m.start() > 0: + self.parser.parseBlocks(parent, [block[:m.start()]]) + block = block[m.end():] # removes the first line + block, theRest = self.detab(block) + else: + sibling, block, theRest = self.parse_content(parent, block) + + if m: + klass, title = self.get_class_and_title(m) + div = etree.SubElement(parent, 'div') + div.set('class', '{} {}'.format(self.CLASSNAME, klass)) + if title: + p = etree.SubElement(div, 'p') + p.text = title + p.set('class', self.CLASSNAME_TITLE) + else: + # Sibling is a list item, but we need to wrap it's content should be wrapped in <p> + if sibling.tag in ('li', 'dd') and sibling.text: + text = sibling.text + sibling.text = '' + p = etree.SubElement(sibling, 'p') + p.text = text + + div = sibling + + self.parser.parseChunk(div, block) + + if theRest: + # This block contained unindented line(s) after the first indented + # line. Insert these lines as the first block of the master blocks + # list for future processing. + blocks.insert(0, theRest) + + def get_class_and_title(self, match): + klass, title = match.group(1).lower(), match.group(2) + klass = self.RE_SPACES.sub(' ', klass) + if title is None: + # no title was provided, use the capitalized class name as title + # e.g.: `!!! note` will render + # `<p class="admonition-title">Note</p>` + title = klass.split(' ', 1)[0].capitalize() + elif title == '': + # an explicit blank title should not be rendered + # e.g.: `!!! warning ""` will *not* render `p` with a title + title = None + return klass, title + + +def makeExtension(**kwargs): # pragma: no cover + return AdmonitionExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/attr_list.py b/plugins/markdown_preview/markdown/extensions/attr_list.py new file mode 100644 index 0000000..0c317d1 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/attr_list.py @@ -0,0 +1,179 @@ +# Attribute List Extension for Python-Markdown +# ============================================ + +# Adds attribute list syntax. Inspired by +# [Maruku](http://maruku.rubyforge.org/proposal.html#attribute_lists)'s +# feature of the same name. + +# See https://Python-Markdown.github.io/extensions/attr_list +# for documentation. + +# Original code Copyright 2011 [Waylan Limberg](http://achinghead.com/). + +# All changes Copyright 2011-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" + Adds attribute list syntax. Inspired by +[Maruku](http://maruku.rubyforge.org/proposal.html#attribute_lists)'s +feature of the same name. + +See the [documentation](https://Python-Markdown.github.io/extensions/attr_list) +for details. +""" + +from __future__ import annotations +from typing import TYPE_CHECKING + +from . import Extension +from ..treeprocessors import Treeprocessor +import re + +if TYPE_CHECKING: # pragma: no cover + from xml.etree.ElementTree import Element + + +def _handle_double_quote(s, t): + k, v = t.split('=', 1) + return k, v.strip('"') + + +def _handle_single_quote(s, t): + k, v = t.split('=', 1) + return k, v.strip("'") + + +def _handle_key_value(s, t): + return t.split('=', 1) + + +def _handle_word(s, t): + if t.startswith('.'): + return '.', t[1:] + if t.startswith('#'): + return 'id', t[1:] + return t, t + + +_scanner = re.Scanner([ + (r'[^ =]+=".*?"', _handle_double_quote), + (r"[^ =]+='.*?'", _handle_single_quote), + (r'[^ =]+=[^ =]+', _handle_key_value), + (r'[^ =]+', _handle_word), + (r' ', None) +]) + + +def get_attrs(str: str) -> list[tuple[str, str]]: + """ Parse attribute list and return a list of attribute tuples. """ + return _scanner.scan(str)[0] + + +def isheader(elem: Element) -> bool: + return elem.tag in ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] + + +class AttrListTreeprocessor(Treeprocessor): + + BASE_RE = r'\{\:?[ ]*([^\}\n ][^\}\n]*)[ ]*\}' + HEADER_RE = re.compile(r'[ ]+{}[ ]*$'.format(BASE_RE)) + BLOCK_RE = re.compile(r'\n[ ]*{}[ ]*$'.format(BASE_RE)) + INLINE_RE = re.compile(r'^{}'.format(BASE_RE)) + NAME_RE = re.compile(r'[^A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff' + r'\u0370-\u037d\u037f-\u1fff\u200c-\u200d' + r'\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff' + r'\uf900-\ufdcf\ufdf0-\ufffd' + r'\:\-\.0-9\u00b7\u0300-\u036f\u203f-\u2040]+') + + def run(self, doc: Element): + for elem in doc.iter(): + if self.md.is_block_level(elem.tag): + # Block level: check for `attrs` on last line of text + RE = self.BLOCK_RE + if isheader(elem) or elem.tag in ['dt', 'td', 'th']: + # header, def-term, or table cell: check for attributes at end of element + RE = self.HEADER_RE + if len(elem) and elem.tag == 'li': + # special case list items. children may include a `ul` or `ol`. + pos = None + # find the `ul` or `ol` position + for i, child in enumerate(elem): + if child.tag in ['ul', 'ol']: + pos = i + break + if pos is None and elem[-1].tail: + # use tail of last child. no `ul` or `ol`. + m = RE.search(elem[-1].tail) + if m: + self.assign_attrs(elem, m.group(1)) + elem[-1].tail = elem[-1].tail[:m.start()] + elif pos is not None and pos > 0 and elem[pos-1].tail: + # use tail of last child before `ul` or `ol` + m = RE.search(elem[pos-1].tail) + if m: + self.assign_attrs(elem, m.group(1)) + elem[pos-1].tail = elem[pos-1].tail[:m.start()] + elif elem.text: + # use text. `ul` is first child. + m = RE.search(elem.text) + if m: + self.assign_attrs(elem, m.group(1)) + elem.text = elem.text[:m.start()] + elif len(elem) and elem[-1].tail: + # has children. Get from tail of last child + m = RE.search(elem[-1].tail) + if m: + self.assign_attrs(elem, m.group(1)) + elem[-1].tail = elem[-1].tail[:m.start()] + if isheader(elem): + # clean up trailing #s + elem[-1].tail = elem[-1].tail.rstrip('#').rstrip() + elif elem.text: + # no children. Get from text. + m = RE.search(elem.text) + if m: + self.assign_attrs(elem, m.group(1)) + elem.text = elem.text[:m.start()] + if isheader(elem): + # clean up trailing #s + elem.text = elem.text.rstrip('#').rstrip() + else: + # inline: check for `attrs` at start of tail + if elem.tail: + m = self.INLINE_RE.match(elem.tail) + if m: + self.assign_attrs(elem, m.group(1)) + elem.tail = elem.tail[m.end():] + + def assign_attrs(self, elem: Element, attrs: str) -> None: + """ Assign `attrs` to element. """ + for k, v in get_attrs(attrs): + if k == '.': + # add to class + cls = elem.get('class') + if cls: + elem.set('class', '{} {}'.format(cls, v)) + else: + elem.set('class', v) + else: + # assign attribute `k` with `v` + elem.set(self.sanitize_name(k), v) + + def sanitize_name(self, name: str) -> str: + """ + Sanitize name as 'an XML Name, minus the ":"'. + See https://www.w3.org/TR/REC-xml-names/#NT-NCName + """ + return self.NAME_RE.sub('_', name) + + +class AttrListExtension(Extension): + """ Attribute List extension for Python-Markdown """ + def extendMarkdown(self, md): + md.treeprocessors.register(AttrListTreeprocessor(md), 'attr_list', 8) + md.registerExtension(self) + + +def makeExtension(**kwargs): # pragma: no cover + return AttrListExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/codehilite.py b/plugins/markdown_preview/markdown/extensions/codehilite.py new file mode 100644 index 0000000..f8d25b0 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/codehilite.py @@ -0,0 +1,338 @@ +# CodeHilite Extension for Python-Markdown +# ======================================== + +# Adds code/syntax highlighting to standard Python-Markdown code blocks. + +# See https://Python-Markdown.github.io/extensions/code_hilite +# for documentation. + +# Original code Copyright 2006-2008 [Waylan Limberg](http://achinghead.com/). + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Adds code/syntax highlighting to standard Python-Markdown code blocks. + +See the [documentation](https://Python-Markdown.github.io/extensions/code_hilite) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..treeprocessors import Treeprocessor +from ..util import parseBoolValue + +try: # pragma: no cover + from pygments import highlight + from pygments.lexers import get_lexer_by_name, guess_lexer + from pygments.formatters import get_formatter_by_name + from pygments.util import ClassNotFound + pygments = True +except ImportError: # pragma: no cover + pygments = False + + +def parse_hl_lines(expr: str) -> list[int]: + """Support our syntax for emphasizing certain lines of code. + + `expr` should be like '1 2' to emphasize lines 1 and 2 of a code block. + Returns a list of integers, the line numbers to emphasize. + """ + if not expr: + return [] + + try: + return list(map(int, expr.split())) + except ValueError: # pragma: no cover + return [] + + +# ------------------ The Main CodeHilite Class ---------------------- +class CodeHilite: + """ + Determine language of source code, and pass it on to the Pygments highlighter. + + Usage: + + ```python + code = CodeHilite(src=some_code, lang='python') + html = code.hilite() + ``` + + Arguments: + src: Source string or any object with a `.readline` attribute. + + Keyword arguments: + lang (str): String name of Pygments lexer to use for highlighting. Default: `None`. + guess_lang (bool): Auto-detect which lexer to use. + Ignored if `lang` is set to a valid value. Default: `True`. + use_pygments (bool): Pass code to Pygments for code highlighting. If `False`, the code is + instead wrapped for highlighting by a JavaScript library. Default: `True`. + pygments_formatter (str): The name of a Pygments formatter or a formatter class used for + highlighting the code blocks. Default: `html`. + linenums (bool): An alias to Pygments `linenos` formatter option. Default: `None`. + css_class (str): An alias to Pygments `cssclass` formatter option. Default: 'codehilite'. + lang_prefix (str): Prefix prepended to the language. Default: "language-". + + Other Options: + + Any other options are accepted and passed on to the lexer and formatter. Therefore, + valid options include any options which are accepted by the `html` formatter or + whichever lexer the code's language uses. Note that most lexers do not have any + options. However, a few have very useful options, such as PHP's `startinline` option. + Any invalid options are ignored without error. + + * **Formatter options**: <https://pygments.org/docs/formatters/#HtmlFormatter> + * **Lexer Options**: <https://pygments.org/docs/lexers/> + + Additionally, when Pygments is enabled, the code's language is passed to the + formatter as an extra option `lang_str`, whose value being `{lang_prefix}{lang}`. + This option has no effect to the Pygments' builtin formatters. + + Advanced Usage: + + ```python + code = CodeHilite( + src = some_code, + lang = 'php', + startinline = True, # Lexer option. Snippet does not start with `<?php`. + linenostart = 42, # Formatter option. Snippet starts on line 42. + hl_lines = [45, 49, 50], # Formatter option. Highlight lines 45, 49, and 50. + linenos = 'inline' # Formatter option. Avoid alignment problems. + ) + html = code.hilite() + ``` + + """ + + def __init__(self, src: str, **options): + self.src = src + self.lang = options.pop('lang', None) + self.guess_lang = options.pop('guess_lang', True) + self.use_pygments = options.pop('use_pygments', True) + self.lang_prefix = options.pop('lang_prefix', 'language-') + self.pygments_formatter = options.pop('pygments_formatter', 'html') + + if 'linenos' not in options: + options['linenos'] = options.pop('linenums', None) + if 'cssclass' not in options: + options['cssclass'] = options.pop('css_class', 'codehilite') + if 'wrapcode' not in options: + # Override Pygments default + options['wrapcode'] = True + # Disallow use of `full` option + options['full'] = False + + self.options = options + + def hilite(self, shebang=True) -> str: + """ + Pass code to the [Pygments](https://pygments.org/) highlighter with + optional line numbers. The output should then be styled with CSS to + your liking. No styles are applied by default - only styling hooks + (i.e.: `<span class="k">`). + + returns : A string of html. + + """ + + self.src = self.src.strip('\n') + + if self.lang is None and shebang: + self._parseHeader() + + if pygments and self.use_pygments: + try: + lexer = get_lexer_by_name(self.lang, **self.options) + except ValueError: + try: + if self.guess_lang: + lexer = guess_lexer(self.src, **self.options) + else: + lexer = get_lexer_by_name('text', **self.options) + except ValueError: # pragma: no cover + lexer = get_lexer_by_name('text', **self.options) + if not self.lang: + # Use the guessed lexer's language instead + self.lang = lexer.aliases[0] + lang_str = f'{self.lang_prefix}{self.lang}' + if isinstance(self.pygments_formatter, str): + try: + formatter = get_formatter_by_name(self.pygments_formatter, **self.options) + except ClassNotFound: + formatter = get_formatter_by_name('html', **self.options) + else: + formatter = self.pygments_formatter(lang_str=lang_str, **self.options) + return highlight(self.src, lexer, formatter) + else: + # just escape and build markup usable by JavaScript highlighting libraries + txt = self.src.replace('&', '&') + txt = txt.replace('<', '<') + txt = txt.replace('>', '>') + txt = txt.replace('"', '"') + classes = [] + if self.lang: + classes.append('{}{}'.format(self.lang_prefix, self.lang)) + if self.options['linenos']: + classes.append('linenums') + class_str = '' + if classes: + class_str = ' class="{}"'.format(' '.join(classes)) + return '<pre class="{}"><code{}>{}\n</code></pre>\n'.format( + self.options['cssclass'], + class_str, + txt + ) + + def _parseHeader(self): + """ + Determines language of a code block from shebang line and whether the + said line should be removed or left in place. If the shebang line + contains a path (even a single /) then it is assumed to be a real + shebang line and left alone. However, if no path is given + (e.i.: `#!python` or `:::python`) then it is assumed to be a mock shebang + for language identification of a code fragment and removed from the + code block prior to processing for code highlighting. When a mock + shebang (e.i: `#!python`) is found, line numbering is turned on. When + colons are found in place of a shebang (e.i.: `:::python`), line + numbering is left in the current state - off by default. + + Also parses optional list of highlight lines, like: + + :::python hl_lines="1 3" + """ + + import re + + # split text into lines + lines = self.src.split("\n") + # pull first line to examine + fl = lines.pop(0) + + c = re.compile(r''' + (?:(?:^::+)|(?P<shebang>^[#]!)) # Shebang or 2 or more colons + (?P<path>(?:/\w+)*[/ ])? # Zero or 1 path + (?P<lang>[\w#.+-]*) # The language + \s* # Arbitrary whitespace + # Optional highlight lines, single- or double-quote-delimited + (hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot))? + ''', re.VERBOSE) + # search first line for shebang + m = c.search(fl) + if m: + # we have a match + try: + self.lang = m.group('lang').lower() + except IndexError: # pragma: no cover + self.lang = None + if m.group('path'): + # path exists - restore first line + lines.insert(0, fl) + if self.options['linenos'] is None and m.group('shebang'): + # Overridable and Shebang exists - use line numbers + self.options['linenos'] = True + + self.options['hl_lines'] = parse_hl_lines(m.group('hl_lines')) + else: + # No match + lines.insert(0, fl) + + self.src = "\n".join(lines).strip("\n") + + +# ------------------ The Markdown Extension ------------------------------- + + +class HiliteTreeprocessor(Treeprocessor): + """ Highlight source code in code blocks. """ + + def code_unescape(self, text): + """Unescape code.""" + text = text.replace("<", "<") + text = text.replace(">", ">") + # Escaped '&' should be replaced at the end to avoid + # conflicting with < and >. + text = text.replace("&", "&") + return text + + def run(self, root): + """ Find code blocks and store in `htmlStash`. """ + blocks = root.iter('pre') + for block in blocks: + if len(block) == 1 and block[0].tag == 'code': + local_config = self.config.copy() + code = CodeHilite( + self.code_unescape(block[0].text), + tab_length=self.md.tab_length, + style=local_config.pop('pygments_style', 'default'), + **local_config + ) + placeholder = self.md.htmlStash.store(code.hilite()) + # Clear code block in `etree` instance + block.clear() + # Change to `p` element which will later + # be removed when inserting raw html + block.tag = 'p' + block.text = placeholder + + +class CodeHiliteExtension(Extension): + """ Add source code highlighting to markdown code blocks. """ + + def __init__(self, **kwargs): + # define default configs + self.config = { + 'linenums': [ + None, "Use lines numbers. True|table|inline=yes, False=no, None=auto. Default: `None`." + ], + 'guess_lang': [ + True, "Automatic language detection - Default: `True`." + ], + 'css_class': [ + "codehilite", "Set class name for wrapper <div> - Default: `codehilite`." + ], + 'pygments_style': [ + 'default', 'Pygments HTML Formatter Style (Colorscheme). Default: `default`.' + ], + 'noclasses': [ + False, 'Use inline styles instead of CSS classes - Default `False`.' + ], + 'use_pygments': [ + True, 'Highlight code blocks with pygments. Disable if using a JavaScript library. Default: `True`.' + ], + 'lang_prefix': [ + 'language-', 'Prefix prepended to the language when `use_pygments` is false. Default: `language-`.' + ], + 'pygments_formatter': [ + 'html', 'Use a specific formatter for Pygments highlighting. Default: `html`.' + ], + } + """ Default configuration options. """ + + for key, value in kwargs.items(): + if key in self.config: + self.setConfig(key, value) + else: + # manually set unknown keywords. + if isinstance(value, str): + try: + # Attempt to parse `str` as a boolean value + value = parseBoolValue(value, preserve_none=True) + except ValueError: + pass # Assume it's not a boolean value. Use as-is. + self.config[key] = [value, ''] + + def extendMarkdown(self, md): + """ Add `HilitePostprocessor` to Markdown instance. """ + hiliter = HiliteTreeprocessor(md) + hiliter.config = self.getConfigs() + md.treeprocessors.register(hiliter, 'hilite', 30) + + md.registerExtension(self) + + +def makeExtension(**kwargs): # pragma: no cover + return CodeHiliteExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/def_list.py b/plugins/markdown_preview/markdown/extensions/def_list.py new file mode 100644 index 0000000..54273b6 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/def_list.py @@ -0,0 +1,119 @@ +# Definition List Extension for Python-Markdown +# ============================================= + +# Adds parsing of Definition Lists to Python-Markdown. + +# See https://Python-Markdown.github.io/extensions/definition_lists +# for documentation. + +# Original code Copyright 2008 [Waylan Limberg](http://achinghead.com) + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Adds parsing of Definition Lists to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/definition_lists) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor, ListIndentProcessor +import xml.etree.ElementTree as etree +import re + + +class DefListProcessor(BlockProcessor): + """ Process Definition Lists. """ + + RE = re.compile(r'(^|\n)[ ]{0,3}:[ ]{1,3}(.*?)(\n|$)') + NO_INDENT_RE = re.compile(r'^[ ]{0,3}[^ :]') + + def test(self, parent, block): + return bool(self.RE.search(block)) + + def run(self, parent, blocks): + + raw_block = blocks.pop(0) + m = self.RE.search(raw_block) + terms = [term.strip() for term in + raw_block[:m.start()].split('\n') if term.strip()] + block = raw_block[m.end():] + no_indent = self.NO_INDENT_RE.match(block) + if no_indent: + d, theRest = (block, None) + else: + d, theRest = self.detab(block) + if d: + d = '{}\n{}'.format(m.group(2), d) + else: + d = m.group(2) + sibling = self.lastChild(parent) + if not terms and sibling is None: + # This is not a definition item. Most likely a paragraph that + # starts with a colon at the beginning of a document or list. + blocks.insert(0, raw_block) + return False + if not terms and sibling.tag == 'p': + # The previous paragraph contains the terms + state = 'looselist' + terms = sibling.text.split('\n') + parent.remove(sibling) + # Acquire new sibling + sibling = self.lastChild(parent) + else: + state = 'list' + + if sibling is not None and sibling.tag == 'dl': + # This is another item on an existing list + dl = sibling + if not terms and len(dl) and dl[-1].tag == 'dd' and len(dl[-1]): + state = 'looselist' + else: + # This is a new list + dl = etree.SubElement(parent, 'dl') + # Add terms + for term in terms: + dt = etree.SubElement(dl, 'dt') + dt.text = term + # Add definition + self.parser.state.set(state) + dd = etree.SubElement(dl, 'dd') + self.parser.parseBlocks(dd, [d]) + self.parser.state.reset() + + if theRest: + blocks.insert(0, theRest) + + +class DefListIndentProcessor(ListIndentProcessor): + """ Process indented children of definition list items. """ + + # Definition lists need to be aware of all list types + ITEM_TYPES = ['dd', 'li'] + """ Include `dd` in list item types. """ + LIST_TYPES = ['dl', 'ol', 'ul'] + """ Include `dl` is list types. """ + + def create_item(self, parent, block): + """ Create a new `dd` or `li` (depending on parent) and parse the block with it as the parent. """ + + dd = etree.SubElement(parent, 'dd') + self.parser.parseBlocks(dd, [block]) + + +class DefListExtension(Extension): + """ Add definition lists to Markdown. """ + + def extendMarkdown(self, md): + """ Add an instance of `DefListProcessor` to `BlockParser`. """ + md.parser.blockprocessors.register(DefListIndentProcessor(md.parser), 'defindent', 85) + md.parser.blockprocessors.register(DefListProcessor(md.parser), 'deflist', 25) + + +def makeExtension(**kwargs): # pragma: no cover + return DefListExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/extra.py b/plugins/markdown_preview/markdown/extensions/extra.py new file mode 100644 index 0000000..74ebc19 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/extra.py @@ -0,0 +1,66 @@ +# Python-Markdown Extra Extension +# =============================== + +# A compilation of various Python-Markdown extensions that imitates +# [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/). + +# See https://Python-Markdown.github.io/extensions/extra +# for documentation. + +# Copyright The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +A compilation of various Python-Markdown extensions that imitates +[PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/). + +Note that each of the individual extensions still need to be available +on your `PYTHONPATH`. This extension simply wraps them all up as a +convenience so that only one extension needs to be listed when +initiating Markdown. See the documentation for each individual +extension for specifics about that extension. + +There may be additional extensions that are distributed with +Python-Markdown that are not included here in Extra. Those extensions +are not part of PHP Markdown Extra, and therefore, not part of +Python-Markdown Extra. If you really would like Extra to include +additional extensions, we suggest creating your own clone of Extra +under a different name. You could also edit the `extensions` global +variable defined below, but be aware that such changes may be lost +when you upgrade to any future version of Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/extra) +for details. +""" + +from __future__ import annotations + +from . import Extension + +extensions = [ + 'fenced_code', + 'footnotes', + 'attr_list', + 'def_list', + 'tables', + 'abbr', + 'md_in_html' +] +""" The list of included extensions. """ + + +class ExtraExtension(Extension): + """ Add various extensions to Markdown class.""" + + def __init__(self, **kwargs): + """ `config` is a dumb holder which gets passed to the actual extension later. """ + self.config = kwargs + + def extendMarkdown(self, md): + """ Register extension instances. """ + md.registerExtensions(extensions, self.config) + + +def makeExtension(**kwargs): # pragma: no cover + return ExtraExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/fenced_code.py b/plugins/markdown_preview/markdown/extensions/fenced_code.py new file mode 100644 index 0000000..241bb6d --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/fenced_code.py @@ -0,0 +1,182 @@ +# Fenced Code Extension for Python Markdown +# ========================================= + +# This extension adds Fenced Code Blocks to Python-Markdown. + +# See https://Python-Markdown.github.io/extensions/fenced_code_blocks +# for documentation. + +# Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com/). + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +This extension adds Fenced Code Blocks to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/fenced_code_blocks) +for details. +""" + +from __future__ import annotations + +from textwrap import dedent +from . import Extension +from ..preprocessors import Preprocessor +from .codehilite import CodeHilite, CodeHiliteExtension, parse_hl_lines +from .attr_list import get_attrs, AttrListExtension +from ..util import parseBoolValue +from ..serializers import _escape_attrib_html +import re + + +class FencedCodeExtension(Extension): + def __init__(self, **kwargs): + self.config = { + 'lang_prefix': ['language-', 'Prefix prepended to the language. Default: "language-"'] + } + """ Default configuration options. """ + super().__init__(**kwargs) + + def extendMarkdown(self, md): + """ Add `FencedBlockPreprocessor` to the Markdown instance. """ + md.registerExtension(self) + + md.preprocessors.register(FencedBlockPreprocessor(md, self.getConfigs()), 'fenced_code_block', 25) + + +class FencedBlockPreprocessor(Preprocessor): + """ Find and extract fenced code blocks. """ + + FENCED_BLOCK_RE = re.compile( + dedent(r''' + (?P<fence>^(?:~{3,}|`{3,}))[ ]* # opening fence + ((\{(?P<attrs>[^\}\n]*)\})| # (optional {attrs} or + (\.?(?P<lang>[\w#.+-]*)[ ]*)? # optional (.)lang + (hl_lines=(?P<quot>"|')(?P<hl_lines>.*?)(?P=quot)[ ]*)?) # optional hl_lines) + \n # newline (end of opening fence) + (?P<code>.*?)(?<=\n) # the code block + (?P=fence)[ ]*$ # closing fence + '''), + re.MULTILINE | re.DOTALL | re.VERBOSE + ) + + def __init__(self, md, config): + super().__init__(md) + self.config = config + self.checked_for_deps = False + self.codehilite_conf = {} + self.use_attr_list = False + # List of options to convert to boolean values + self.bool_options = [ + 'linenums', + 'guess_lang', + 'noclasses', + 'use_pygments' + ] + + def run(self, lines): + """ Match and store Fenced Code Blocks in the `HtmlStash`. """ + + # Check for dependent extensions + if not self.checked_for_deps: + for ext in self.md.registeredExtensions: + if isinstance(ext, CodeHiliteExtension): + self.codehilite_conf = ext.getConfigs() + if isinstance(ext, AttrListExtension): + self.use_attr_list = True + + self.checked_for_deps = True + + text = "\n".join(lines) + while 1: + m = self.FENCED_BLOCK_RE.search(text) + if m: + lang, id, classes, config = None, '', [], {} + if m.group('attrs'): + id, classes, config = self.handle_attrs(get_attrs(m.group('attrs'))) + if len(classes): + lang = classes.pop(0) + else: + if m.group('lang'): + lang = m.group('lang') + if m.group('hl_lines'): + # Support `hl_lines` outside of `attrs` for backward-compatibility + config['hl_lines'] = parse_hl_lines(m.group('hl_lines')) + + # If `config` is not empty, then the `codehighlite` extension + # is enabled, so we call it to highlight the code + if self.codehilite_conf and self.codehilite_conf['use_pygments'] and config.get('use_pygments', True): + local_config = self.codehilite_conf.copy() + local_config.update(config) + # Combine classes with `cssclass`. Ensure `cssclass` is at end + # as Pygments appends a suffix under certain circumstances. + # Ignore ID as Pygments does not offer an option to set it. + if classes: + local_config['css_class'] = '{} {}'.format( + ' '.join(classes), + local_config['css_class'] + ) + highliter = CodeHilite( + m.group('code'), + lang=lang, + style=local_config.pop('pygments_style', 'default'), + **local_config + ) + + code = highliter.hilite(shebang=False) + else: + id_attr = lang_attr = class_attr = kv_pairs = '' + if lang: + prefix = self.config.get('lang_prefix', 'language-') + lang_attr = f' class="{prefix}{_escape_attrib_html(lang)}"' + if classes: + class_attr = f' class="{_escape_attrib_html(" ".join(classes))}"' + if id: + id_attr = f' id="{_escape_attrib_html(id)}"' + if self.use_attr_list and config and not config.get('use_pygments', False): + # Only assign key/value pairs to code element if `attr_list` extension is enabled, key/value + # pairs were defined on the code block, and the `use_pygments` key was not set to `True`. The + # `use_pygments` key could be either set to `False` or not defined. It is omitted from output. + kv_pairs = ''.join( + f' {k}="{_escape_attrib_html(v)}"' for k, v in config.items() if k != 'use_pygments' + ) + code = self._escape(m.group('code')) + code = f'<pre{id_attr}{class_attr}><code{lang_attr}{kv_pairs}>{code}</code></pre>' + + placeholder = self.md.htmlStash.store(code) + text = f'{text[:m.start()]}\n{placeholder}\n{text[m.end():]}' + else: + break + return text.split("\n") + + def handle_attrs(self, attrs): + """ Return tuple: `(id, [list, of, classes], {configs})` """ + id = '' + classes = [] + configs = {} + for k, v in attrs: + if k == 'id': + id = v + elif k == '.': + classes.append(v) + elif k == 'hl_lines': + configs[k] = parse_hl_lines(v) + elif k in self.bool_options: + configs[k] = parseBoolValue(v, fail_on_errors=False, preserve_none=True) + else: + configs[k] = v + return id, classes, configs + + def _escape(self, txt): + """ basic html escaping """ + txt = txt.replace('&', '&') + txt = txt.replace('<', '<') + txt = txt.replace('>', '>') + txt = txt.replace('"', '"') + return txt + + +def makeExtension(**kwargs): # pragma: no cover + return FencedCodeExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/footnotes.py b/plugins/markdown_preview/markdown/extensions/footnotes.py new file mode 100644 index 0000000..2424dbc --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/footnotes.py @@ -0,0 +1,416 @@ +# Footnotes Extension for Python-Markdown +# ======================================= + +# Adds footnote handling to Python-Markdown. + +# See https://Python-Markdown.github.io/extensions/footnotes +# for documentation. + +# Copyright The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Adds footnote handling to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/footnotes) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor +from ..inlinepatterns import InlineProcessor +from ..treeprocessors import Treeprocessor +from ..postprocessors import Postprocessor +from .. import util +from collections import OrderedDict +import re +import copy +import xml.etree.ElementTree as etree + +FN_BACKLINK_TEXT = util.STX + "zz1337820767766393qq" + util.ETX +NBSP_PLACEHOLDER = util.STX + "qq3936677670287331zz" + util.ETX +RE_REF_ID = re.compile(r'(fnref)(\d+)') + + +class FootnoteExtension(Extension): + """ Footnote Extension. """ + + def __init__(self, **kwargs): + """ Setup configs. """ + + self.config = { + 'PLACE_MARKER': [ + '///Footnotes Go Here///', 'The text string that marks where the footnotes go' + ], + 'UNIQUE_IDS': [ + False, 'Avoid name collisions across multiple calls to `reset()`.' + ], + 'BACKLINK_TEXT': [ + '↩', "The text string that links from the footnote to the reader's place." + ], + 'SUPERSCRIPT_TEXT': [ + '{}', "The text string that links from the reader's place to the footnote." + ], + 'BACKLINK_TITLE': [ + 'Jump back to footnote %d in the text', + 'The text string used for the title HTML attribute of the backlink. ' + '%d will be replaced by the footnote number.' + ], + 'SEPARATOR': [ + ':', 'Footnote separator.' + ] + } + """ Default configuration options. """ + super().__init__(**kwargs) + + # In multiple invocations, emit links that don't get tangled. + self.unique_prefix = 0 + self.found_refs = {} + self.used_refs = set() + + self.reset() + + def extendMarkdown(self, md): + """ Add pieces to Markdown. """ + md.registerExtension(self) + self.parser = md.parser + self.md = md + # Insert a `blockprocessor` before `ReferencePreprocessor` + md.parser.blockprocessors.register(FootnoteBlockProcessor(self), 'footnote', 17) + + # Insert an inline pattern before `ImageReferencePattern` + FOOTNOTE_RE = r'\[\^([^\]]*)\]' # blah blah [^1] blah + md.inlinePatterns.register(FootnoteInlineProcessor(FOOTNOTE_RE, self), 'footnote', 175) + # Insert a tree-processor that would actually add the footnote div + # This must be before all other tree-processors (i.e., `inline` and + # `codehilite`) so they can run on the the contents of the div. + md.treeprocessors.register(FootnoteTreeprocessor(self), 'footnote', 50) + + # Insert a tree-processor that will run after inline is done. + # In this tree-processor we want to check our duplicate footnote tracker + # And add additional `backrefs` to the footnote pointing back to the + # duplicated references. + md.treeprocessors.register(FootnotePostTreeprocessor(self), 'footnote-duplicate', 15) + + # Insert a postprocessor after amp_substitute processor + md.postprocessors.register(FootnotePostprocessor(self), 'footnote', 25) + + def reset(self) -> None: + """ Clear footnotes on reset, and prepare for distinct document. """ + self.footnotes: OrderedDict[str, str] = OrderedDict() + self.unique_prefix += 1 + self.found_refs = {} + self.used_refs = set() + + def unique_ref(self, reference, found: bool = False): + """ Get a unique reference if there are duplicates. """ + if not found: + return reference + + original_ref = reference + while reference in self.used_refs: + ref, rest = reference.split(self.get_separator(), 1) + m = RE_REF_ID.match(ref) + if m: + reference = '%s%d%s%s' % (m.group(1), int(m.group(2))+1, self.get_separator(), rest) + else: + reference = '%s%d%s%s' % (ref, 2, self.get_separator(), rest) + + self.used_refs.add(reference) + if original_ref in self.found_refs: + self.found_refs[original_ref] += 1 + else: + self.found_refs[original_ref] = 1 + return reference + + def findFootnotesPlaceholder(self, root): + """ Return ElementTree Element that contains Footnote placeholder. """ + def finder(element): + for child in element: + if child.text: + if child.text.find(self.getConfig("PLACE_MARKER")) > -1: + return child, element, True + if child.tail: + if child.tail.find(self.getConfig("PLACE_MARKER")) > -1: + return child, element, False + child_res = finder(child) + if child_res is not None: + return child_res + return None + + res = finder(root) + return res + + def setFootnote(self, id, text) -> None: + """ Store a footnote for later retrieval. """ + self.footnotes[id] = text + + def get_separator(self): + """ Get the footnote separator. """ + return self.getConfig("SEPARATOR") + + def makeFootnoteId(self, id): + """ Return footnote link id. """ + if self.getConfig("UNIQUE_IDS"): + return 'fn%s%d-%s' % (self.get_separator(), self.unique_prefix, id) + else: + return 'fn{}{}'.format(self.get_separator(), id) + + def makeFootnoteRefId(self, id, found: bool = False): + """ Return footnote back-link id. """ + if self.getConfig("UNIQUE_IDS"): + return self.unique_ref('fnref%s%d-%s' % (self.get_separator(), self.unique_prefix, id), found) + else: + return self.unique_ref('fnref{}{}'.format(self.get_separator(), id), found) + + def makeFootnotesDiv(self, root): + """ Return `div` of footnotes as `etree` Element. """ + + if not list(self.footnotes.keys()): + return None + + div = etree.Element("div") + div.set('class', 'footnote') + etree.SubElement(div, "hr") + ol = etree.SubElement(div, "ol") + surrogate_parent = etree.Element("div") + + # Backward compatibility with old '%d' placeholder + backlink_title = self.getConfig("BACKLINK_TITLE").replace("%d", "{}") + + for index, id in enumerate(self.footnotes.keys(), start=1): + li = etree.SubElement(ol, "li") + li.set("id", self.makeFootnoteId(id)) + # Parse footnote with surrogate parent as `li` cannot be used. + # List block handlers have special logic to deal with `li`. + # When we are done parsing, we will copy everything over to `li`. + self.parser.parseChunk(surrogate_parent, self.footnotes[id]) + for el in list(surrogate_parent): + li.append(el) + surrogate_parent.remove(el) + backlink = etree.Element("a") + backlink.set("href", "#" + self.makeFootnoteRefId(id)) + backlink.set("class", "footnote-backref") + backlink.set( + "title", + backlink_title.format(index) + ) + backlink.text = FN_BACKLINK_TEXT + + if len(li): + node = li[-1] + if node.tag == "p": + node.text = node.text + NBSP_PLACEHOLDER + node.append(backlink) + else: + p = etree.SubElement(li, "p") + p.append(backlink) + return div + + +class FootnoteBlockProcessor(BlockProcessor): + """ Find all footnote references and store for later use. """ + + RE = re.compile(r'^[ ]{0,3}\[\^([^\]]*)\]:[ ]*(.*)$', re.MULTILINE) + + def __init__(self, footnotes): + super().__init__(footnotes.parser) + self.footnotes = footnotes + + def test(self, parent, block): + return True + + def run(self, parent, blocks): + """ Find, set, and remove footnote definitions. """ + block = blocks.pop(0) + m = self.RE.search(block) + if m: + id = m.group(1) + fn_blocks = [m.group(2)] + + # Handle rest of block + therest = block[m.end():].lstrip('\n') + m2 = self.RE.search(therest) + if m2: + # Another footnote exists in the rest of this block. + # Any content before match is continuation of this footnote, which may be lazily indented. + before = therest[:m2.start()].rstrip('\n') + fn_blocks[0] = '\n'.join([fn_blocks[0], self.detab(before)]).lstrip('\n') + # Add back to blocks everything from beginning of match forward for next iteration. + blocks.insert(0, therest[m2.start():]) + else: + # All remaining lines of block are continuation of this footnote, which may be lazily indented. + fn_blocks[0] = '\n'.join([fn_blocks[0], self.detab(therest)]).strip('\n') + + # Check for child elements in remaining blocks. + fn_blocks.extend(self.detectTabbed(blocks)) + + footnote = "\n\n".join(fn_blocks) + self.footnotes.setFootnote(id, footnote.rstrip()) + + if block[:m.start()].strip(): + # Add any content before match back to blocks as separate block + blocks.insert(0, block[:m.start()].rstrip('\n')) + return True + # No match. Restore block. + blocks.insert(0, block) + return False + + def detectTabbed(self, blocks) -> list[str]: + """ Find indented text and remove indent before further processing. + + Returns: + A list of blocks with indentation removed. + """ + fn_blocks = [] + while blocks: + if blocks[0].startswith(' '*4): + block = blocks.pop(0) + # Check for new footnotes within this block and split at new footnote. + m = self.RE.search(block) + if m: + # Another footnote exists in this block. + # Any content before match is continuation of this footnote, which may be lazily indented. + before = block[:m.start()].rstrip('\n') + fn_blocks.append(self.detab(before)) + # Add back to blocks everything from beginning of match forward for next iteration. + blocks.insert(0, block[m.start():]) + # End of this footnote. + break + else: + # Entire block is part of this footnote. + fn_blocks.append(self.detab(block)) + else: + # End of this footnote. + break + return fn_blocks + + def detab(self, block): + """ Remove one level of indent from a block. + + Preserve lazily indented blocks by only removing indent from indented lines. + """ + lines = block.split('\n') + for i, line in enumerate(lines): + if line.startswith(' '*4): + lines[i] = line[4:] + return '\n'.join(lines) + + +class FootnoteInlineProcessor(InlineProcessor): + """ `InlineProcessor` for footnote markers in a document's body text. """ + + def __init__(self, pattern, footnotes): + super().__init__(pattern) + self.footnotes = footnotes + + def handleMatch(self, m, data): + id = m.group(1) + if id in self.footnotes.footnotes.keys(): + sup = etree.Element("sup") + a = etree.SubElement(sup, "a") + sup.set('id', self.footnotes.makeFootnoteRefId(id, found=True)) + a.set('href', '#' + self.footnotes.makeFootnoteId(id)) + a.set('class', 'footnote-ref') + a.text = self.footnotes.getConfig("SUPERSCRIPT_TEXT").format( + list(self.footnotes.footnotes.keys()).index(id) + 1 + ) + return sup, m.start(0), m.end(0) + else: + return None, None, None + + +class FootnotePostTreeprocessor(Treeprocessor): + """ Amend footnote div with duplicates. """ + + def __init__(self, footnotes): + self.footnotes = footnotes + + def add_duplicates(self, li, duplicates) -> None: + """ Adjust current `li` and add the duplicates: `fnref2`, `fnref3`, etc. """ + for link in li.iter('a'): + # Find the link that needs to be duplicated. + if link.attrib.get('class', '') == 'footnote-backref': + ref, rest = link.attrib['href'].split(self.footnotes.get_separator(), 1) + # Duplicate link the number of times we need to + # and point the to the appropriate references. + links = [] + for index in range(2, duplicates + 1): + sib_link = copy.deepcopy(link) + sib_link.attrib['href'] = '%s%d%s%s' % (ref, index, self.footnotes.get_separator(), rest) + links.append(sib_link) + self.offset += 1 + # Add all the new duplicate links. + el = list(li)[-1] + for link in links: + el.append(link) + break + + def get_num_duplicates(self, li): + """ Get the number of duplicate refs of the footnote. """ + fn, rest = li.attrib.get('id', '').split(self.footnotes.get_separator(), 1) + link_id = '{}ref{}{}'.format(fn, self.footnotes.get_separator(), rest) + return self.footnotes.found_refs.get(link_id, 0) + + def handle_duplicates(self, parent) -> None: + """ Find duplicate footnotes and format and add the duplicates. """ + for li in list(parent): + # Check number of duplicates footnotes and insert + # additional links if needed. + count = self.get_num_duplicates(li) + if count > 1: + self.add_duplicates(li, count) + + def run(self, root): + """ Crawl the footnote div and add missing duplicate footnotes. """ + self.offset = 0 + for div in root.iter('div'): + if div.attrib.get('class', '') == 'footnote': + # Footnotes should be under the first ordered list under + # the footnote div. So once we find it, quit. + for ol in div.iter('ol'): + self.handle_duplicates(ol) + break + + +class FootnoteTreeprocessor(Treeprocessor): + """ Build and append footnote div to end of document. """ + + def __init__(self, footnotes): + self.footnotes = footnotes + + def run(self, root): + footnotesDiv = self.footnotes.makeFootnotesDiv(root) + if footnotesDiv is not None: + result = self.footnotes.findFootnotesPlaceholder(root) + if result: + child, parent, isText = result + ind = list(parent).index(child) + if isText: + parent.remove(child) + parent.insert(ind, footnotesDiv) + else: + parent.insert(ind + 1, footnotesDiv) + child.tail = None + else: + root.append(footnotesDiv) + + +class FootnotePostprocessor(Postprocessor): + """ Replace placeholders with html entities. """ + def __init__(self, footnotes): + self.footnotes = footnotes + + def run(self, text): + text = text.replace( + FN_BACKLINK_TEXT, self.footnotes.getConfig("BACKLINK_TEXT") + ) + return text.replace(NBSP_PLACEHOLDER, " ") + + +def makeExtension(**kwargs): # pragma: no cover + """ Return an instance of the `FootnoteExtension` """ + return FootnoteExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/legacy_attrs.py b/plugins/markdown_preview/markdown/extensions/legacy_attrs.py new file mode 100644 index 0000000..56ad2e8 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/legacy_attrs.py @@ -0,0 +1,67 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +An extension to Python Markdown which implements legacy attributes. + +Prior to Python-Markdown version 3.0, the Markdown class had an `enable_attributes` +keyword which was on by default and provided for attributes to be defined for elements +using the format `{@key=value}`. This extension is provided as a replacement for +backward compatibility. New documents should be authored using `attr_lists`. However, +numerous documents exist which have been using the old attribute format for many +years. This extension can be used to continue to render those documents correctly. +""" + +from __future__ import annotations + +import re +from markdown.treeprocessors import Treeprocessor, isString +from markdown.extensions import Extension + + +ATTR_RE = re.compile(r'\{@([^\}]*)=([^\}]*)}') # {@id=123} + + +class LegacyAttrs(Treeprocessor): + def run(self, doc): + """Find and set values of attributes ({@key=value}). """ + for el in doc.iter(): + alt = el.get('alt', None) + if alt is not None: + el.set('alt', self.handleAttributes(el, alt)) + if el.text and isString(el.text): + el.text = self.handleAttributes(el, el.text) + if el.tail and isString(el.tail): + el.tail = self.handleAttributes(el, el.tail) + + def handleAttributes(self, el, txt): + """ Set attributes and return text without definitions. """ + def attributeCallback(match): + el.set(match.group(1), match.group(2).replace('\n', ' ')) + return ATTR_RE.sub(attributeCallback, txt) + + +class LegacyAttrExtension(Extension): + def extendMarkdown(self, md): + """ Add `LegacyAttrs` to Markdown instance. """ + md.treeprocessors.register(LegacyAttrs(md), 'legacyattrs', 15) + + +def makeExtension(**kwargs): # pragma: no cover + return LegacyAttrExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/legacy_em.py b/plugins/markdown_preview/markdown/extensions/legacy_em.py new file mode 100644 index 0000000..a6f67b7 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/legacy_em.py @@ -0,0 +1,52 @@ +# Legacy Em Extension for Python-Markdown +# ======================================= + +# This extension provides legacy behavior for _connected_words_. + +# Copyright 2015-2018 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +This extension provides legacy behavior for _connected_words_. +""" + +from __future__ import annotations + +from . import Extension +from ..inlinepatterns import UnderscoreProcessor, EmStrongItem, EM_STRONG2_RE, STRONG_EM2_RE +import re + +# _emphasis_ +EMPHASIS_RE = r'(_)([^_]+)\1' + +# __strong__ +STRONG_RE = r'(_{2})(.+?)\1' + +# __strong_em___ +STRONG_EM_RE = r'(_)\1(?!\1)([^_]+?)\1(?!\1)(.+?)\1{3}' + + +class LegacyUnderscoreProcessor(UnderscoreProcessor): + """Emphasis processor for handling strong and em matches inside underscores.""" + + PATTERNS = [ + EmStrongItem(re.compile(EM_STRONG2_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'), + EmStrongItem(re.compile(STRONG_EM2_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'), + EmStrongItem(re.compile(STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'), + EmStrongItem(re.compile(STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'), + EmStrongItem(re.compile(EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em') + ] + + +class LegacyEmExtension(Extension): + """ Add legacy_em extension to Markdown class.""" + + def extendMarkdown(self, md): + """ Modify inline patterns. """ + md.inlinePatterns.register(LegacyUnderscoreProcessor(r'_'), 'em_strong2', 50) + + +def makeExtension(**kwargs): # pragma: no cover + """ Return an instance of the `LegacyEmExtension` """ + return LegacyEmExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/md_in_html.py b/plugins/markdown_preview/markdown/extensions/md_in_html.py new file mode 100644 index 0000000..982d603 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/md_in_html.py @@ -0,0 +1,372 @@ +# Python-Markdown Markdown in HTML Extension +# =============================== + +# An implementation of [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/)'s +# parsing of Markdown syntax in raw HTML. + +# See https://Python-Markdown.github.io/extensions/raw_html +# for documentation. + +# Copyright The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +An implementation of [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/)'s +parsing of Markdown syntax in raw HTML. + +See the [documentation](https://Python-Markdown.github.io/extensions/raw_html) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor +from ..preprocessors import Preprocessor +from ..postprocessors import RawHtmlPostprocessor +from .. import util +from ..htmlparser import HTMLExtractor, blank_line_re +import xml.etree.ElementTree as etree + + +class HTMLExtractorExtra(HTMLExtractor): + """ + Override `HTMLExtractor` and create `etree` `Elements` for any elements which should have content parsed as + Markdown. + """ + + def __init__(self, md, *args, **kwargs): + # All block-level tags. + self.block_level_tags = set(md.block_level_elements.copy()) + # Block-level tags in which the content only gets span level parsing + self.span_tags = set( + ['address', 'dd', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'legend', 'li', 'p', 'summary', 'td', 'th'] + ) + # Block-level tags which never get their content parsed. + self.raw_tags = set(['canvas', 'math', 'option', 'pre', 'script', 'style', 'textarea']) + + super().__init__(md, *args, **kwargs) + + # Block-level tags in which the content gets parsed as blocks + self.block_tags = set(self.block_level_tags) - (self.span_tags | self.raw_tags | self.empty_tags) + self.span_and_blocks_tags = self.block_tags | self.span_tags + + def reset(self): + """Reset this instance. Loses all unprocessed data.""" + self.mdstack = [] # When markdown=1, stack contains a list of tags + self.treebuilder = etree.TreeBuilder() + self.mdstate = [] # one of 'block', 'span', 'off', or None + super().reset() + + def close(self): + """Handle any buffered data.""" + super().close() + # Handle any unclosed tags. + if self.mdstack: + # Close the outermost parent. `handle_endtag` will close all unclosed children. + self.handle_endtag(self.mdstack[0]) + + def get_element(self): + """ Return element from `treebuilder` and reset `treebuilder` for later use. """ + element = self.treebuilder.close() + self.treebuilder = etree.TreeBuilder() + return element + + def get_state(self, tag, attrs): + """ Return state from tag and `markdown` attribute. One of 'block', 'span', or 'off'. """ + md_attr = attrs.get('markdown', '0') + if md_attr == 'markdown': + # `<tag markdown>` is the same as `<tag markdown='1'>`. + md_attr = '1' + parent_state = self.mdstate[-1] if self.mdstate else None + if parent_state == 'off' or (parent_state == 'span' and md_attr != '0'): + # Only use the parent state if it is more restrictive than the markdown attribute. + md_attr = parent_state + if ((md_attr == '1' and tag in self.block_tags) or + (md_attr == 'block' and tag in self.span_and_blocks_tags)): + return 'block' + elif ((md_attr == '1' and tag in self.span_tags) or + (md_attr == 'span' and tag in self.span_and_blocks_tags)): + return 'span' + elif tag in self.block_level_tags: + return 'off' + else: # pragma: no cover + return None + + def handle_starttag(self, tag, attrs): + # Handle tags that should always be empty and do not specify a closing tag + if tag in self.empty_tags and (self.at_line_start() or self.intail): + attrs = {key: value if value is not None else key for key, value in attrs} + if "markdown" in attrs: + attrs.pop('markdown') + element = etree.Element(tag, attrs) + data = etree.tostring(element, encoding='unicode', method='html') + else: + data = self.get_starttag_text() + self.handle_empty_tag(data, True) + return + + if tag in self.block_level_tags and (self.at_line_start() or self.intail): + # Valueless attribute (ex: `<tag checked>`) results in `[('checked', None)]`. + # Convert to `{'checked': 'checked'}`. + attrs = {key: value if value is not None else key for key, value in attrs} + state = self.get_state(tag, attrs) + if self.inraw or (state in [None, 'off'] and not self.mdstack): + # fall back to default behavior + attrs.pop('markdown', None) + super().handle_starttag(tag, attrs) + else: + if 'p' in self.mdstack and tag in self.block_level_tags: + # Close unclosed 'p' tag + self.handle_endtag('p') + self.mdstate.append(state) + self.mdstack.append(tag) + attrs['markdown'] = state + self.treebuilder.start(tag, attrs) + else: + # Span level tag + if self.inraw: + super().handle_starttag(tag, attrs) + else: + text = self.get_starttag_text() + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + if tag in self.CDATA_CONTENT_ELEMENTS: + # This is presumably a standalone tag in a code span (see #1036). + self.clear_cdata_mode() + + def handle_endtag(self, tag): + if tag in self.block_level_tags: + if self.inraw: + super().handle_endtag(tag) + elif tag in self.mdstack: + # Close element and any unclosed children + while self.mdstack: + item = self.mdstack.pop() + self.mdstate.pop() + self.treebuilder.end(item) + if item == tag: + break + if not self.mdstack: + # Last item in stack is closed. Stash it + element = self.get_element() + # Get last entry to see if it ends in newlines + # If it is an element, assume there is no newlines + item = self.cleandoc[-1] if self.cleandoc else '' + # If we only have one newline before block element, add another + if not item.endswith('\n\n') and item.endswith('\n'): + self.cleandoc.append('\n') + self.cleandoc.append(self.md.htmlStash.store(element)) + self.cleandoc.append('\n\n') + self.state = [] + # Check if element has a tail + if not blank_line_re.match( + self.rawdata[self.line_offset + self.offset + len(self.get_endtag_text(tag)):]): + # More content exists after `endtag`. + self.intail = True + else: + # Treat orphan closing tag as a span level tag. + text = self.get_endtag_text(tag) + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + else: + # Span level tag + if self.inraw: + super().handle_endtag(tag) + else: + text = self.get_endtag_text(tag) + if self.mdstate and self.mdstate[-1] == "off": + self.handle_data(self.md.htmlStash.store(text)) + else: + self.handle_data(text) + + def handle_startendtag(self, tag, attrs): + if tag in self.empty_tags: + attrs = {key: value if value is not None else key for key, value in attrs} + if "markdown" in attrs: + attrs.pop('markdown') + element = etree.Element(tag, attrs) + data = etree.tostring(element, encoding='unicode', method='html') + else: + data = self.get_starttag_text() + else: + data = self.get_starttag_text() + self.handle_empty_tag(data, is_block=self.md.is_block_level(tag)) + + def handle_data(self, data): + if self.intail and '\n' in data: + self.intail = False + if self.inraw or not self.mdstack: + super().handle_data(data) + else: + self.treebuilder.data(data) + + def handle_empty_tag(self, data, is_block): + if self.inraw or not self.mdstack: + super().handle_empty_tag(data, is_block) + else: + if self.at_line_start() and is_block: + self.handle_data('\n' + self.md.htmlStash.store(data) + '\n\n') + else: + self.handle_data(self.md.htmlStash.store(data)) + + def parse_pi(self, i): + if self.at_line_start() or self.intail or self.mdstack: + # The same override exists in `HTMLExtractor` without the check + # for `mdstack`. Therefore, use parent of `HTMLExtractor` instead. + return super(HTMLExtractor, self).parse_pi(i) + # This is not the beginning of a raw block so treat as plain data + # and avoid consuming any tags which may follow (see #1066). + self.handle_data('<?') + return i + 2 + + def parse_html_declaration(self, i): + if self.at_line_start() or self.intail or self.mdstack: + # The same override exists in `HTMLExtractor` without the check + # for `mdstack`. Therefore, use parent of `HTMLExtractor` instead. + return super(HTMLExtractor, self).parse_html_declaration(i) + # This is not the beginning of a raw block so treat as plain data + # and avoid consuming any tags which may follow (see #1066). + self.handle_data('<!') + return i + 2 + + +class HtmlBlockPreprocessor(Preprocessor): + """Remove html blocks from the text and store them for later retrieval.""" + + def run(self, lines): + source = '\n'.join(lines) + parser = HTMLExtractorExtra(self.md) + parser.feed(source) + parser.close() + return ''.join(parser.cleandoc).split('\n') + + +class MarkdownInHtmlProcessor(BlockProcessor): + """Process Markdown Inside HTML Blocks which have been stored in the `HtmlStash`.""" + + def test(self, parent, block): + # Always return True. `run` will return `False` it not a valid match. + return True + + def parse_element_content(self, element): + """ + Recursively parse the text content of an `etree` Element as Markdown. + + Any block level elements generated from the Markdown will be inserted as children of the element in place + of the text content. All `markdown` attributes are removed. For any elements in which Markdown parsing has + been disabled, the text content of it and its children are wrapped in an `AtomicString`. + """ + + md_attr = element.attrib.pop('markdown', 'off') + + if md_attr == 'block': + # Parse content as block level + # The order in which the different parts are parsed (text, children, tails) is important here as the + # order of elements needs to be preserved. We can't be inserting items at a later point in the current + # iteration as we don't want to do raw processing on elements created from parsing Markdown text (for + # example). Therefore, the order of operations is children, tails, text. + + # Recursively parse existing children from raw HTML + for child in list(element): + self.parse_element_content(child) + + # Parse Markdown text in tail of children. Do this separate to avoid raw HTML parsing. + # Save the position of each item to be inserted later in reverse. + tails = [] + for pos, child in enumerate(element): + if child.tail: + block = child.tail.rstrip('\n') + child.tail = '' + # Use a dummy placeholder element. + dummy = etree.Element('div') + self.parser.parseBlocks(dummy, block.split('\n\n')) + children = list(dummy) + children.reverse() + tails.append((pos + 1, children)) + + # Insert the elements created from the tails in reverse. + tails.reverse() + for pos, tail in tails: + for item in tail: + element.insert(pos, item) + + # Parse Markdown text content. Do this last to avoid raw HTML parsing. + if element.text: + block = element.text.rstrip('\n') + element.text = '' + # Use a dummy placeholder element as the content needs to get inserted before existing children. + dummy = etree.Element('div') + self.parser.parseBlocks(dummy, block.split('\n\n')) + children = list(dummy) + children.reverse() + for child in children: + element.insert(0, child) + + elif md_attr == 'span': + # Span level parsing will be handled by inline processors. + # Walk children here to remove any `markdown` attributes. + for child in list(element): + self.parse_element_content(child) + + else: + # Disable inline parsing for everything else + if element.text is None: + element.text = '' + element.text = util.AtomicString(element.text) + for child in list(element): + self.parse_element_content(child) + if child.tail: + child.tail = util.AtomicString(child.tail) + + def run(self, parent, blocks): + m = util.HTML_PLACEHOLDER_RE.match(blocks[0]) + if m: + index = int(m.group(1)) + element = self.parser.md.htmlStash.rawHtmlBlocks[index] + if isinstance(element, etree.Element): + # We have a matched element. Process it. + blocks.pop(0) + self.parse_element_content(element) + parent.append(element) + # Cleanup stash. Replace element with empty string to avoid confusing postprocessor. + self.parser.md.htmlStash.rawHtmlBlocks.pop(index) + self.parser.md.htmlStash.rawHtmlBlocks.insert(index, '') + # Confirm the match to the `blockparser`. + return True + # No match found. + return False + + +class MarkdownInHTMLPostprocessor(RawHtmlPostprocessor): + def stash_to_string(self, text): + """ Override default to handle any `etree` elements still in the stash. """ + if isinstance(text, etree.Element): + return self.md.serializer(text) + else: + return str(text) + + +class MarkdownInHtmlExtension(Extension): + """Add Markdown parsing in HTML to Markdown class.""" + + def extendMarkdown(self, md): + """ Register extension instances. """ + + # Replace raw HTML preprocessor + md.preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20) + # Add `blockprocessor` which handles the placeholders for `etree` elements + md.parser.blockprocessors.register( + MarkdownInHtmlProcessor(md.parser), 'markdown_block', 105 + ) + # Replace raw HTML postprocessor + md.postprocessors.register(MarkdownInHTMLPostprocessor(md), 'raw_html', 30) + + +def makeExtension(**kwargs): # pragma: no cover + return MarkdownInHtmlExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/meta.py b/plugins/markdown_preview/markdown/extensions/meta.py new file mode 100644 index 0000000..8217927 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/meta.py @@ -0,0 +1,85 @@ +# Meta Data Extension for Python-Markdown +# ======================================= + +# This extension adds Meta Data handling to markdown. + +# See https://Python-Markdown.github.io/extensions/meta_data +# for documentation. + +# Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com). + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +This extension adds Meta Data handling to markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/meta_data) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..preprocessors import Preprocessor +import re +import logging + +log = logging.getLogger('MARKDOWN') + +# Global Vars +META_RE = re.compile(r'^[ ]{0,3}(?P<key>[A-Za-z0-9_-]+):\s*(?P<value>.*)') +META_MORE_RE = re.compile(r'^[ ]{4,}(?P<value>.*)') +BEGIN_RE = re.compile(r'^-{3}(\s.*)?') +END_RE = re.compile(r'^(-{3}|\.{3})(\s.*)?') + + +class MetaExtension (Extension): + """ Meta-Data extension for Python-Markdown. """ + + def extendMarkdown(self, md): + """ Add `MetaPreprocessor` to Markdown instance. """ + md.registerExtension(self) + self.md = md + md.preprocessors.register(MetaPreprocessor(md), 'meta', 27) + + def reset(self) -> None: + self.md.Meta = {} + + +class MetaPreprocessor(Preprocessor): + """ Get Meta-Data. """ + + def run(self, lines): + """ Parse Meta-Data and store in Markdown.Meta. """ + meta = {} + key = None + if lines and BEGIN_RE.match(lines[0]): + lines.pop(0) + while lines: + line = lines.pop(0) + m1 = META_RE.match(line) + if line.strip() == '' or END_RE.match(line): + break # blank line or end of YAML header - done + if m1: + key = m1.group('key').lower().strip() + value = m1.group('value').strip() + try: + meta[key].append(value) + except KeyError: + meta[key] = [value] + else: + m2 = META_MORE_RE.match(line) + if m2 and key: + # Add another line to existing key + meta[key].append(m2.group('value').strip()) + else: + lines.insert(0, line) + break # no meta data - done + self.md.Meta = meta + return lines + + +def makeExtension(**kwargs): # pragma: no cover + return MetaExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/nl2br.py b/plugins/markdown_preview/markdown/extensions/nl2br.py new file mode 100644 index 0000000..177df1e --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/nl2br.py @@ -0,0 +1,41 @@ +# `NL2BR` Extension +# =============== + +# A Python-Markdown extension to treat newlines as hard breaks; like +# GitHub-flavored Markdown does. + +# See https://Python-Markdown.github.io/extensions/nl2br +# for documentation. + +# Original code Copyright 2011 [Brian Neal](https://deathofagremmie.com/) + +# All changes Copyright 2011-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +A Python-Markdown extension to treat newlines as hard breaks; like +GitHub-flavored Markdown does. + +See the [documentation](https://Python-Markdown.github.io/extensions/nl2br) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..inlinepatterns import SubstituteTagInlineProcessor + +BR_RE = r'\n' + + +class Nl2BrExtension(Extension): + + def extendMarkdown(self, md): + """ Add a `SubstituteTagInlineProcessor` to Markdown. """ + br_tag = SubstituteTagInlineProcessor(BR_RE, 'br') + md.inlinePatterns.register(br_tag, 'nl', 5) + + +def makeExtension(**kwargs): # pragma: no cover + return Nl2BrExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/sane_lists.py b/plugins/markdown_preview/markdown/extensions/sane_lists.py new file mode 100644 index 0000000..305bd99 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/sane_lists.py @@ -0,0 +1,65 @@ +# Sane List Extension for Python-Markdown +# ======================================= + +# Modify the behavior of Lists in Python-Markdown to act in a sane manor. + +# See https://Python-Markdown.github.io/extensions/sane_lists +# for documentation. + +# Original code Copyright 2011 [Waylan Limberg](http://achinghead.com) + +# All changes Copyright 2011-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Modify the behavior of Lists in Python-Markdown to act in a sane manor. + +See [documentation](https://Python-Markdown.github.io/extensions/sane_lists) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import OListProcessor, UListProcessor +import re + + +class SaneOListProcessor(OListProcessor): + """ Override `SIBLING_TAGS` to not include `ul` and set `LAZY_OL` to `False`. """ + + SIBLING_TAGS = ['ol'] + """ Exclude `ul` from list of siblings. """ + LAZY_OL = False + """ Disable lazy list behavior. """ + + def __init__(self, parser): + super().__init__(parser) + self.CHILD_RE = re.compile(r'^[ ]{0,%d}((\d+\.))[ ]+(.*)' % + (self.tab_length - 1)) + + +class SaneUListProcessor(UListProcessor): + """ Override `SIBLING_TAGS` to not include `ol`. """ + + SIBLING_TAGS = ['ul'] + """ Exclude `ol` from list of siblings. """ + + def __init__(self, parser): + super().__init__(parser) + self.CHILD_RE = re.compile(r'^[ ]{0,%d}(([*+-]))[ ]+(.*)' % + (self.tab_length - 1)) + + +class SaneListExtension(Extension): + """ Add sane lists to Markdown. """ + + def extendMarkdown(self, md): + """ Override existing Processors. """ + md.parser.blockprocessors.register(SaneOListProcessor(md.parser), 'olist', 40) + md.parser.blockprocessors.register(SaneUListProcessor(md.parser), 'ulist', 30) + + +def makeExtension(**kwargs): # pragma: no cover + return SaneListExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/smarty.py b/plugins/markdown_preview/markdown/extensions/smarty.py new file mode 100644 index 0000000..3274bf8 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/smarty.py @@ -0,0 +1,265 @@ +# Smarty extension for Python-Markdown +# ==================================== + +# Adds conversion of ASCII dashes, quotes and ellipses to their HTML +# entity equivalents. + +# See https://Python-Markdown.github.io/extensions/smarty +# for documentation. + +# Author: 2013, Dmitry Shachnev <mitya57@gmail.com> + +# All changes Copyright 2013-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +# SmartyPants license: + +# Copyright (c) 2003 John Gruber <https://daringfireball.net/> +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: + +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. + +# * Neither the name "SmartyPants" nor the names of its contributors +# may be used to endorse or promote products derived from this +# software without specific prior written permission. + +# This software is provided by the copyright holders and contributors "as +# is" and any express or implied warranties, including, but not limited +# to, the implied warranties of merchantability and fitness for a +# particular purpose are disclaimed. In no event shall the copyright +# owner or contributors be liable for any direct, indirect, incidental, +# special, exemplary, or consequential damages (including, but not +# limited to, procurement of substitute goods or services; loss of use, +# data, or profits; or business interruption) however caused and on any +# theory of liability, whether in contract, strict liability, or tort +# (including negligence or otherwise) arising in any way out of the use +# of this software, even if advised of the possibility of such damage. + + +# `smartypants.py` license: + +# `smartypants.py` is a derivative work of SmartyPants. +# Copyright (c) 2004, 2007 Chad Miller <http://web.chad.org/> + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: + +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. + +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. + +# This software is provided by the copyright holders and contributors "as +# is" and any express or implied warranties, including, but not limited +# to, the implied warranties of merchantability and fitness for a +# particular purpose are disclaimed. In no event shall the copyright +# owner or contributors be liable for any direct, indirect, incidental, +# special, exemplary, or consequential damages (including, but not +# limited to, procurement of substitute goods or services; loss of use, +# data, or profits; or business interruption) however caused and on any +# theory of liability, whether in contract, strict liability, or tort +# (including negligence or otherwise) arising in any way out of the use +# of this software, even if advised of the possibility of such damage. + +""" +Adds conversion of ASCII dashes, quotes and ellipses to their HTML +entity equivalents. + +See the [documentation](https://Python-Markdown.github.io/extensions/smarty) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..inlinepatterns import HtmlInlineProcessor, HTML_RE +from ..treeprocessors import InlineProcessor +from ..util import Registry + + +# Constants for quote education. +punctClass = r"""[!"#\$\%'()*+,-.\/:;<=>?\@\[\\\]\^_`{|}~]""" +endOfWordClass = r"[\s.,;:!?)]" +closeClass = r"[^\ \t\r\n\[\{\(\-\u0002\u0003]" + +openingQuotesBase = ( + r'(\s' # a whitespace char + r'| ' # or a non-breaking space entity + r'|--' # or dashes + r'|–|—' # or Unicode + r'|&[mn]dash;' # or named dash entities + r'|–|—' # or decimal entities + r')' +) + +substitutions = { + 'mdash': '—', + 'ndash': '–', + 'ellipsis': '…', + 'left-angle-quote': '«', + 'right-angle-quote': '»', + 'left-single-quote': '‘', + 'right-single-quote': '’', + 'left-double-quote': '“', + 'right-double-quote': '”', +} + + +# Special case if the very first character is a quote +# followed by punctuation at a non-word-break. Close the quotes by brute force: +singleQuoteStartRe = r"^'(?=%s\B)" % punctClass +doubleQuoteStartRe = r'^"(?=%s\B)' % punctClass + +# Special case for double sets of quotes, e.g.: +# <p>He said, "'Quoted' words in a larger quote."</p> +doubleQuoteSetsRe = r""""'(?=\w)""" +singleQuoteSetsRe = r"""'"(?=\w)""" + +# Special case for decade abbreviations (the '80s): +decadeAbbrRe = r"(?<!\w)'(?=\d{2}s)" + +# Get most opening double quotes: +openingDoubleQuotesRegex = r'%s"(?=\w)' % openingQuotesBase + +# Double closing quotes: +closingDoubleQuotesRegex = r'"(?=\s)' +closingDoubleQuotesRegex2 = '(?<=%s)"' % closeClass + +# Get most opening single quotes: +openingSingleQuotesRegex = r"%s'(?=\w)" % openingQuotesBase + +# Single closing quotes: +closingSingleQuotesRegex = r"(?<=%s)'(?!\s|s\b|\d)" % closeClass +closingSingleQuotesRegex2 = r"'(\s|s\b)" + +# All remaining quotes should be opening ones +remainingSingleQuotesRegex = r"'" +remainingDoubleQuotesRegex = r'"' + +HTML_STRICT_RE = HTML_RE + r'(?!\>)' + + +class SubstituteTextPattern(HtmlInlineProcessor): + def __init__(self, pattern, replace, md): + """ Replaces matches with some text. """ + HtmlInlineProcessor.__init__(self, pattern) + self.replace = replace + self.md = md + + def handleMatch(self, m, data): + result = '' + for part in self.replace: + if isinstance(part, int): + result += m.group(part) + else: + result += self.md.htmlStash.store(part) + return result, m.start(0), m.end(0) + + +class SmartyExtension(Extension): + """ Add Smarty to Markdown. """ + def __init__(self, **kwargs): + self.config = { + 'smart_quotes': [True, 'Educate quotes'], + 'smart_angled_quotes': [False, 'Educate angled quotes'], + 'smart_dashes': [True, 'Educate dashes'], + 'smart_ellipses': [True, 'Educate ellipses'], + 'substitutions': [{}, 'Overwrite default substitutions'], + } + """ Default configuration options. """ + super().__init__(**kwargs) + self.substitutions = dict(substitutions) + self.substitutions.update(self.getConfig('substitutions', default={})) + + def _addPatterns(self, md, patterns, serie, priority): + for ind, pattern in enumerate(patterns): + pattern += (md,) + pattern = SubstituteTextPattern(*pattern) + name = 'smarty-%s-%d' % (serie, ind) + self.inlinePatterns.register(pattern, name, priority-ind) + + def educateDashes(self, md) -> None: + emDashesPattern = SubstituteTextPattern( + r'(?<!-)---(?!-)', (self.substitutions['mdash'],), md + ) + enDashesPattern = SubstituteTextPattern( + r'(?<!-)--(?!-)', (self.substitutions['ndash'],), md + ) + self.inlinePatterns.register(emDashesPattern, 'smarty-em-dashes', 50) + self.inlinePatterns.register(enDashesPattern, 'smarty-en-dashes', 45) + + def educateEllipses(self, md) -> None: + ellipsesPattern = SubstituteTextPattern( + r'(?<!\.)\.{3}(?!\.)', (self.substitutions['ellipsis'],), md + ) + self.inlinePatterns.register(ellipsesPattern, 'smarty-ellipses', 10) + + def educateAngledQuotes(self, md) -> None: + leftAngledQuotePattern = SubstituteTextPattern( + r'\<\<', (self.substitutions['left-angle-quote'],), md + ) + rightAngledQuotePattern = SubstituteTextPattern( + r'\>\>', (self.substitutions['right-angle-quote'],), md + ) + self.inlinePatterns.register(leftAngledQuotePattern, 'smarty-left-angle-quotes', 40) + self.inlinePatterns.register(rightAngledQuotePattern, 'smarty-right-angle-quotes', 35) + + def educateQuotes(self, md) -> None: + lsquo = self.substitutions['left-single-quote'] + rsquo = self.substitutions['right-single-quote'] + ldquo = self.substitutions['left-double-quote'] + rdquo = self.substitutions['right-double-quote'] + patterns = ( + (singleQuoteStartRe, (rsquo,)), + (doubleQuoteStartRe, (rdquo,)), + (doubleQuoteSetsRe, (ldquo + lsquo,)), + (singleQuoteSetsRe, (lsquo + ldquo,)), + (decadeAbbrRe, (rsquo,)), + (openingSingleQuotesRegex, (1, lsquo)), + (closingSingleQuotesRegex, (rsquo,)), + (closingSingleQuotesRegex2, (rsquo, 1)), + (remainingSingleQuotesRegex, (lsquo,)), + (openingDoubleQuotesRegex, (1, ldquo)), + (closingDoubleQuotesRegex, (rdquo,)), + (closingDoubleQuotesRegex2, (rdquo,)), + (remainingDoubleQuotesRegex, (ldquo,)) + ) + self._addPatterns(md, patterns, 'quotes', 30) + + def extendMarkdown(self, md): + configs = self.getConfigs() + self.inlinePatterns: Registry[HtmlInlineProcessor] = Registry() + if configs['smart_ellipses']: + self.educateEllipses(md) + if configs['smart_quotes']: + self.educateQuotes(md) + if configs['smart_angled_quotes']: + self.educateAngledQuotes(md) + # Override `HTML_RE` from `inlinepatterns.py` so that it does not + # process tags with duplicate closing quotes. + md.inlinePatterns.register(HtmlInlineProcessor(HTML_STRICT_RE, md), 'html', 90) + if configs['smart_dashes']: + self.educateDashes(md) + inlineProcessor = InlineProcessor(md) + inlineProcessor.inlinePatterns = self.inlinePatterns + md.treeprocessors.register(inlineProcessor, 'smarty', 2) + md.ESCAPED_CHARS.extend(['"', "'"]) + + +def makeExtension(**kwargs): # pragma: no cover + return SmartyExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/tables.py b/plugins/markdown_preview/markdown/extensions/tables.py new file mode 100644 index 0000000..a9e5f13 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/tables.py @@ -0,0 +1,243 @@ +# Tables Extension for Python-Markdown +# ==================================== + +# Added parsing of tables to Python-Markdown. + +# See https://Python-Markdown.github.io/extensions/tables +# for documentation. + +# Original code Copyright 2009 [Waylan Limberg](http://achinghead.com) + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Added parsing of tables to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/tables) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..blockprocessors import BlockProcessor +import xml.etree.ElementTree as etree +import re +PIPE_NONE = 0 +PIPE_LEFT = 1 +PIPE_RIGHT = 2 + + +class TableProcessor(BlockProcessor): + """ Process Tables. """ + + RE_CODE_PIPES = re.compile(r'(?:(\\\\)|(\\`+)|(`+)|(\\\|)|(\|))') + RE_END_BORDER = re.compile(r'(?<!\\)(?:\\\\)*\|$') + + def __init__(self, parser, config): + self.border = False + self.separator = '' + self.config = config + + super().__init__(parser) + + def test(self, parent, block): + """ + Ensure first two rows (column header and separator row) are valid table rows. + + Keep border check and separator row do avoid repeating the work. + """ + is_table = False + rows = [row.strip(' ') for row in block.split('\n')] + if len(rows) > 1: + header0 = rows[0] + self.border = PIPE_NONE + if header0.startswith('|'): + self.border |= PIPE_LEFT + if self.RE_END_BORDER.search(header0) is not None: + self.border |= PIPE_RIGHT + row = self._split_row(header0) + row0_len = len(row) + is_table = row0_len > 1 + + # Each row in a single column table needs at least one pipe. + if not is_table and row0_len == 1 and self.border: + for index in range(1, len(rows)): + is_table = rows[index].startswith('|') + if not is_table: + is_table = self.RE_END_BORDER.search(rows[index]) is not None + if not is_table: + break + + if is_table: + row = self._split_row(rows[1]) + is_table = (len(row) == row0_len) and set(''.join(row)) <= set('|:- ') + if is_table: + self.separator = row + + return is_table + + def run(self, parent, blocks): + """ Parse a table block and build table. """ + block = blocks.pop(0).split('\n') + header = block[0].strip(' ') + rows = [] if len(block) < 3 else block[2:] + + # Get alignment of columns + align = [] + for c in self.separator: + c = c.strip(' ') + if c.startswith(':') and c.endswith(':'): + align.append('center') + elif c.startswith(':'): + align.append('left') + elif c.endswith(':'): + align.append('right') + else: + align.append(None) + + # Build table + table = etree.SubElement(parent, 'table') + thead = etree.SubElement(table, 'thead') + self._build_row(header, thead, align) + tbody = etree.SubElement(table, 'tbody') + if len(rows) == 0: + # Handle empty table + self._build_empty_row(tbody, align) + else: + for row in rows: + self._build_row(row.strip(' '), tbody, align) + + def _build_empty_row(self, parent, align): + """Build an empty row.""" + tr = etree.SubElement(parent, 'tr') + count = len(align) + while count: + etree.SubElement(tr, 'td') + count -= 1 + + def _build_row(self, row, parent, align): + """ Given a row of text, build table cells. """ + tr = etree.SubElement(parent, 'tr') + tag = 'td' + if parent.tag == 'thead': + tag = 'th' + cells = self._split_row(row) + # We use align here rather than cells to ensure every row + # contains the same number of columns. + for i, a in enumerate(align): + c = etree.SubElement(tr, tag) + try: + c.text = cells[i].strip(' ') + except IndexError: # pragma: no cover + c.text = "" + if a: + if self.config['use_align_attribute']: + c.set('align', a) + else: + c.set('style', f'text-align: {a};') + + def _split_row(self, row): + """ split a row of text into list of cells. """ + if self.border: + if row.startswith('|'): + row = row[1:] + row = self.RE_END_BORDER.sub('', row) + return self._split(row) + + def _split(self, row): + """ split a row of text with some code into a list of cells. """ + elements = [] + pipes = [] + tics = [] + tic_points = [] + tic_region = [] + good_pipes = [] + + # Parse row + # Throw out \\, and \| + for m in self.RE_CODE_PIPES.finditer(row): + # Store ` data (len, start_pos, end_pos) + if m.group(2): + # \`+ + # Store length of each tic group: subtract \ + tics.append(len(m.group(2)) - 1) + # Store start of group, end of group, and escape length + tic_points.append((m.start(2), m.end(2) - 1, 1)) + elif m.group(3): + # `+ + # Store length of each tic group + tics.append(len(m.group(3))) + # Store start of group, end of group, and escape length + tic_points.append((m.start(3), m.end(3) - 1, 0)) + # Store pipe location + elif m.group(5): + pipes.append(m.start(5)) + + # Pair up tics according to size if possible + # Subtract the escape length *only* from the opening. + # Walk through tic list and see if tic has a close. + # Store the tic region (start of region, end of region). + pos = 0 + tic_len = len(tics) + while pos < tic_len: + try: + tic_size = tics[pos] - tic_points[pos][2] + if tic_size == 0: + raise ValueError + index = tics[pos + 1:].index(tic_size) + 1 + tic_region.append((tic_points[pos][0], tic_points[pos + index][1])) + pos += index + 1 + except ValueError: + pos += 1 + + # Resolve pipes. Check if they are within a tic pair region. + # Walk through pipes comparing them to each region. + # - If pipe position is less that a region, it isn't in a region + # - If it is within a region, we don't want it, so throw it out + # - If we didn't throw it out, it must be a table pipe + for pipe in pipes: + throw_out = False + for region in tic_region: + if pipe < region[0]: + # Pipe is not in a region + break + elif region[0] <= pipe <= region[1]: + # Pipe is within a code region. Throw it out. + throw_out = True + break + if not throw_out: + good_pipes.append(pipe) + + # Split row according to table delimiters. + pos = 0 + for pipe in good_pipes: + elements.append(row[pos:pipe]) + pos = pipe + 1 + elements.append(row[pos:]) + return elements + + +class TableExtension(Extension): + """ Add tables to Markdown. """ + + def __init__(self, **kwargs): + self.config = { + 'use_align_attribute': [False, 'True to use align attribute instead of style.'], + } + """ Default configuration options. """ + + super().__init__(**kwargs) + + def extendMarkdown(self, md): + """ Add an instance of `TableProcessor` to `BlockParser`. """ + if '|' not in md.ESCAPED_CHARS: + md.ESCAPED_CHARS.append('|') + processor = TableProcessor(md.parser, self.getConfigs()) + md.parser.blockprocessors.register(processor, 'table', 75) + + +def makeExtension(**kwargs): # pragma: no cover + return TableExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/toc.py b/plugins/markdown_preview/markdown/extensions/toc.py new file mode 100644 index 0000000..64c20c8 --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/toc.py @@ -0,0 +1,408 @@ +# Table of Contents Extension for Python-Markdown +# =============================================== + +# See https://Python-Markdown.github.io/extensions/toc +# for documentation. + +# Original code Copyright 2008 [Jack Miller](https://codezen.org/) + +# All changes Copyright 2008-2014 The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Add table of contents support to Python-Markdown. + +See the [documentation](https://Python-Markdown.github.io/extensions/toc) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..treeprocessors import Treeprocessor +from ..util import code_escape, parseBoolValue, AMP_SUBSTITUTE, HTML_PLACEHOLDER_RE, AtomicString +from ..treeprocessors import UnescapeTreeprocessor +import re +import html +import unicodedata +import xml.etree.ElementTree as etree + + +def slugify(value, separator, unicode=False): + """ Slugify a string, to make it URL friendly. """ + if not unicode: + # Replace Extended Latin characters with ASCII, i.e. `žlutý` => `zluty` + value = unicodedata.normalize('NFKD', value) + value = value.encode('ascii', 'ignore').decode('ascii') + value = re.sub(r'[^\w\s-]', '', value).strip().lower() + return re.sub(r'[{}\s]+'.format(separator), separator, value) + + +def slugify_unicode(value, separator): + """ Slugify a string, to make it URL friendly while preserving Unicode characters. """ + return slugify(value, separator, unicode=True) + + +IDCOUNT_RE = re.compile(r'^(.*)_([0-9]+)$') + + +def unique(id, ids): + """ Ensure id is unique in set of ids. Append '_1', '_2'... if not """ + while id in ids or not id: + m = IDCOUNT_RE.match(id) + if m: + id = '%s_%d' % (m.group(1), int(m.group(2))+1) + else: + id = '%s_%d' % (id, 1) + ids.add(id) + return id + + +def get_name(el): + """Get title name.""" + + text = [] + for c in el.itertext(): + if isinstance(c, AtomicString): + text.append(html.unescape(c)) + else: + text.append(c) + return ''.join(text).strip() + + +def stashedHTML2text(text, md, strip_entities: bool = True): + """ Extract raw HTML from stash, reduce to plain text and swap with placeholder. """ + def _html_sub(m): + """ Substitute raw html with plain text. """ + try: + raw = md.htmlStash.rawHtmlBlocks[int(m.group(1))] + except (IndexError, TypeError): # pragma: no cover + return m.group(0) + # Strip out tags and/or entities - leaving text + res = re.sub(r'(<[^>]+>)', '', raw) + if strip_entities: + res = re.sub(r'(&[\#a-zA-Z0-9]+;)', '', res) + return res + + return HTML_PLACEHOLDER_RE.sub(_html_sub, text) + + +def unescape(text): + """ Unescape escaped text. """ + c = UnescapeTreeprocessor() + return c.unescape(text) + + +def nest_toc_tokens(toc_list): + """Given an unsorted list with errors and skips, return a nested one. + + [{'level': 1}, {'level': 2}] + => + [{'level': 1, 'children': [{'level': 2, 'children': []}]}] + + A wrong list is also converted: + + [{'level': 2}, {'level': 1}] + => + [{'level': 2, 'children': []}, {'level': 1, 'children': []}] + """ + + ordered_list = [] + if len(toc_list): + # Initialize everything by processing the first entry + last = toc_list.pop(0) + last['children'] = [] + levels = [last['level']] + ordered_list.append(last) + parents = [] + + # Walk the rest nesting the entries properly + while toc_list: + t = toc_list.pop(0) + current_level = t['level'] + t['children'] = [] + + # Reduce depth if current level < last item's level + if current_level < levels[-1]: + # Pop last level since we know we are less than it + levels.pop() + + # Pop parents and levels we are less than or equal to + to_pop = 0 + for p in reversed(parents): + if current_level <= p['level']: + to_pop += 1 + else: # pragma: no cover + break + if to_pop: + levels = levels[:-to_pop] + parents = parents[:-to_pop] + + # Note current level as last + levels.append(current_level) + + # Level is the same, so append to + # the current parent (if available) + if current_level == levels[-1]: + (parents[-1]['children'] if parents + else ordered_list).append(t) + + # Current level is > last item's level, + # So make last item a parent and append current as child + else: + last['children'].append(t) + parents.append(last) + levels.append(current_level) + last = t + + return ordered_list + + +class TocTreeprocessor(Treeprocessor): + """ Step through document and build TOC. """ + + def __init__(self, md, config): + super().__init__(md) + + self.marker = config["marker"] + self.title = config["title"] + self.base_level = int(config["baselevel"]) - 1 + self.slugify = config["slugify"] + self.sep = config["separator"] + self.toc_class = config["toc_class"] + self.title_class = config["title_class"] + self.use_anchors = parseBoolValue(config["anchorlink"]) + self.anchorlink_class = config["anchorlink_class"] + self.use_permalinks = parseBoolValue(config["permalink"], False) + if self.use_permalinks is None: + self.use_permalinks = config["permalink"] + self.permalink_class = config["permalink_class"] + self.permalink_title = config["permalink_title"] + self.permalink_leading = parseBoolValue(config["permalink_leading"], False) + self.header_rgx = re.compile("[Hh][123456]") + if isinstance(config["toc_depth"], str) and '-' in config["toc_depth"]: + self.toc_top, self.toc_bottom = [int(x) for x in config["toc_depth"].split('-')] + else: + self.toc_top = 1 + self.toc_bottom = int(config["toc_depth"]) + + def iterparent(self, node): + """ Iterator wrapper to get allowed parent and child all at once. """ + + # We do not allow the marker inside a header as that + # would causes an endless loop of placing a new TOC + # inside previously generated TOC. + for child in node: + if not self.header_rgx.match(child.tag) and child.tag not in ['pre', 'code']: + yield node, child + yield from self.iterparent(child) + + def replace_marker(self, root, elem) -> None: + """ Replace marker with elem. """ + for (p, c) in self.iterparent(root): + text = ''.join(c.itertext()).strip() + if not text: + continue + + # To keep the output from screwing up the + # validation by putting a `<div>` inside of a `<p>` + # we actually replace the `<p>` in its entirety. + + # The `<p>` element may contain more than a single text content + # (`nl2br` can introduce a `<br>`). In this situation, `c.text` returns + # the very first content, ignore children contents or tail content. + # `len(c) == 0` is here to ensure there is only text in the `<p>`. + if c.text and c.text.strip() == self.marker and len(c) == 0: + for i in range(len(p)): + if p[i] == c: + p[i] = elem + break + + def set_level(self, elem) -> None: + """ Adjust header level according to base level. """ + level = int(elem.tag[-1]) + self.base_level + if level > 6: + level = 6 + elem.tag = 'h%d' % level + + def add_anchor(self, c, elem_id) -> None: + anchor = etree.Element("a") + anchor.text = c.text + anchor.attrib["href"] = "#" + elem_id + anchor.attrib["class"] = self.anchorlink_class + c.text = "" + for elem in c: + anchor.append(elem) + while len(c): + c.remove(c[0]) + c.append(anchor) + + def add_permalink(self, c, elem_id) -> None: + permalink = etree.Element("a") + permalink.text = ("%spara;" % AMP_SUBSTITUTE + if self.use_permalinks is True + else self.use_permalinks) + permalink.attrib["href"] = "#" + elem_id + permalink.attrib["class"] = self.permalink_class + if self.permalink_title: + permalink.attrib["title"] = self.permalink_title + if self.permalink_leading: + permalink.tail = c.text + c.text = "" + c.insert(0, permalink) + else: + c.append(permalink) + + def build_toc_div(self, toc_list): + """ Return a string div given a toc list. """ + div = etree.Element("div") + div.attrib["class"] = self.toc_class + + # Add title to the div + if self.title: + header = etree.SubElement(div, "span") + if self.title_class: + header.attrib["class"] = self.title_class + header.text = self.title + + def build_etree_ul(toc_list, parent): + ul = etree.SubElement(parent, "ul") + for item in toc_list: + # List item link, to be inserted into the toc div + li = etree.SubElement(ul, "li") + link = etree.SubElement(li, "a") + link.text = item.get('name', '') + link.attrib["href"] = '#' + item.get('id', '') + if item['children']: + build_etree_ul(item['children'], li) + return ul + + build_etree_ul(toc_list, div) + + if 'prettify' in self.md.treeprocessors: + self.md.treeprocessors['prettify'].run(div) + + return div + + def run(self, doc): + # Get a list of id attributes + used_ids = set() + for el in doc.iter(): + if "id" in el.attrib: + used_ids.add(el.attrib["id"]) + + toc_tokens = [] + for el in doc.iter(): + if isinstance(el.tag, str) and self.header_rgx.match(el.tag): + self.set_level(el) + text = get_name(el) + + # Do not override pre-existing ids + if "id" not in el.attrib: + innertext = unescape(stashedHTML2text(text, self.md)) + el.attrib["id"] = unique(self.slugify(innertext, self.sep), used_ids) + + if int(el.tag[-1]) >= self.toc_top and int(el.tag[-1]) <= self.toc_bottom: + toc_tokens.append({ + 'level': int(el.tag[-1]), + 'id': el.attrib["id"], + 'name': unescape(stashedHTML2text( + code_escape(el.attrib.get('data-toc-label', text)), + self.md, strip_entities=False + )) + }) + + # Remove the data-toc-label attribute as it is no longer needed + if 'data-toc-label' in el.attrib: + del el.attrib['data-toc-label'] + + if self.use_anchors: + self.add_anchor(el, el.attrib["id"]) + if self.use_permalinks not in [False, None]: + self.add_permalink(el, el.attrib["id"]) + + toc_tokens = nest_toc_tokens(toc_tokens) + div = self.build_toc_div(toc_tokens) + if self.marker: + self.replace_marker(doc, div) + + # serialize and attach to markdown instance. + toc = self.md.serializer(div) + for pp in self.md.postprocessors: + toc = pp.run(toc) + self.md.toc_tokens = toc_tokens + self.md.toc = toc + + +class TocExtension(Extension): + + TreeProcessorClass = TocTreeprocessor + + def __init__(self, **kwargs): + self.config = { + 'marker': [ + '[TOC]', + 'Text to find and replace with Table of Contents. Set to an empty string to disable. ' + 'Default: `[TOC]`.' + ], + 'title': [ + '', 'Title to insert into TOC `<div>`. Default: an empty string.' + ], + 'title_class': [ + 'toctitle', 'CSS class used for the title. Default: `toctitle`.' + ], + 'toc_class': [ + 'toc', 'CSS class(es) used for the link. Default: `toclink`.' + ], + 'anchorlink': [ + False, 'True if header should be a self link. Default: `False`.' + ], + 'anchorlink_class': [ + 'toclink', 'CSS class(es) used for the link. Defaults: `toclink`.' + ], + 'permalink': [ + 0, 'True or link text if a Sphinx-style permalink should be added. Default: `False`.' + ], + 'permalink_class': [ + 'headerlink', 'CSS class(es) used for the link. Default: `headerlink`.' + ], + 'permalink_title': [ + 'Permanent link', 'Title attribute of the permalink. Default: `Permanent link`.' + ], + 'permalink_leading': [ + False, + 'True if permalinks should be placed at start of the header, rather than end. Default: False.' + ], + 'baselevel': ['1', 'Base level for headers. Default: `1`.'], + 'slugify': [ + slugify, 'Function to generate anchors based on header text. Default: `slugify`.' + ], + 'separator': ['-', 'Word separator. Default: `-`.'], + 'toc_depth': [ + 6, + 'Define the range of section levels to include in the Table of Contents. A single integer ' + '(b) defines the bottom section level (<h1>..<hb>) only. A string consisting of two digits ' + 'separated by a hyphen in between (`2-5`) defines the top (t) and the bottom (b) (<ht>..<hb>). ' + 'Default: `6` (bottom).' + ], + } + """ Default configuration options. """ + + super().__init__(**kwargs) + + def extendMarkdown(self, md): + """ Add TOC tree processor to Markdown. """ + md.registerExtension(self) + self.md = md + self.reset() + tocext = self.TreeProcessorClass(md, self.getConfigs()) + md.treeprocessors.register(tocext, 'toc', 5) + + def reset(self) -> None: + self.md.toc = '' + self.md.toc_tokens = [] + + +def makeExtension(**kwargs): # pragma: no cover + return TocExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/extensions/wikilinks.py b/plugins/markdown_preview/markdown/extensions/wikilinks.py new file mode 100644 index 0000000..9d5acfa --- /dev/null +++ b/plugins/markdown_preview/markdown/extensions/wikilinks.py @@ -0,0 +1,96 @@ +# WikiLinks Extension for Python-Markdown +# ====================================== + +# Converts [[WikiLinks]] to relative links. + +# See https://Python-Markdown.github.io/extensions/wikilinks +# for documentation. + +# Original code Copyright [Waylan Limberg](http://achinghead.com/). + +# All changes Copyright The Python Markdown Project + +# License: [BSD](https://opensource.org/licenses/bsd-license.php) + +""" +Converts `[[WikiLinks]]` to relative links. + +See the [documentation](https://Python-Markdown.github.io/extensions/wikilinks) +for details. +""" + +from __future__ import annotations + +from . import Extension +from ..inlinepatterns import InlineProcessor +import xml.etree.ElementTree as etree +import re + + +def build_url(label, base, end): + """ Build a URL from the label, a base, and an end. """ + clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label) + return '{}{}{}'.format(base, clean_label, end) + + +class WikiLinkExtension(Extension): + """ Add inline processor to Markdown. """ + + def __init__(self, **kwargs): + self.config = { + 'base_url': ['/', 'String to append to beginning or URL.'], + 'end_url': ['/', 'String to append to end of URL.'], + 'html_class': ['wikilink', 'CSS hook. Leave blank for none.'], + 'build_url': [build_url, 'Callable formats URL from label.'], + } + """ Default configuration options. """ + super().__init__(**kwargs) + + def extendMarkdown(self, md): + self.md = md + + # append to end of inline patterns + WIKILINK_RE = r'\[\[([\w0-9_ -]+)\]\]' + wikilinkPattern = WikiLinksInlineProcessor(WIKILINK_RE, self.getConfigs()) + wikilinkPattern.md = md + md.inlinePatterns.register(wikilinkPattern, 'wikilink', 75) + + +class WikiLinksInlineProcessor(InlineProcessor): + """ Build link from `wikilink`. """ + + def __init__(self, pattern, config): + super().__init__(pattern) + self.config = config + + def handleMatch(self, m, data): + if m.group(1).strip(): + base_url, end_url, html_class = self._getMeta() + label = m.group(1).strip() + url = self.config['build_url'](label, base_url, end_url) + a = etree.Element('a') + a.text = label + a.set('href', url) + if html_class: + a.set('class', html_class) + else: + a = '' + return a, m.start(0), m.end(0) + + def _getMeta(self): + """ Return meta data or `config` data. """ + base_url = self.config['base_url'] + end_url = self.config['end_url'] + html_class = self.config['html_class'] + if hasattr(self.md, 'Meta'): + if 'wiki_base_url' in self.md.Meta: + base_url = self.md.Meta['wiki_base_url'][0] + if 'wiki_end_url' in self.md.Meta: + end_url = self.md.Meta['wiki_end_url'][0] + if 'wiki_html_class' in self.md.Meta: + html_class = self.md.Meta['wiki_html_class'][0] + return base_url, end_url, html_class + + +def makeExtension(**kwargs): # pragma: no cover + return WikiLinkExtension(**kwargs) diff --git a/plugins/markdown_preview/markdown/htmlparser.py b/plugins/markdown_preview/markdown/htmlparser.py new file mode 100644 index 0000000..29e2300 --- /dev/null +++ b/plugins/markdown_preview/markdown/htmlparser.py @@ -0,0 +1,334 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +This module imports a copy of [`html.parser.HTMLParser`][] and modifies it heavily through monkey-patches. +A copy is imported rather than the module being directly imported as this ensures that the user can import +and use the unmodified library for their own needs. +""" + +from __future__ import annotations + +import re +import importlib.util +import sys + + +# Import a copy of the html.parser lib as `htmlparser` so we can monkeypatch it. +# Users can still do `from html import parser` and get the default behavior. +spec = importlib.util.find_spec('html.parser') +htmlparser = importlib.util.module_from_spec(spec) +spec.loader.exec_module(htmlparser) +sys.modules['htmlparser'] = htmlparser + +# Monkeypatch `HTMLParser` to only accept `?>` to close Processing Instructions. +htmlparser.piclose = re.compile(r'\?>') +# Monkeypatch `HTMLParser` to only recognize entity references with a closing semicolon. +htmlparser.entityref = re.compile(r'&([a-zA-Z][-.a-zA-Z0-9]*);') +# Monkeypatch `HTMLParser` to no longer support partial entities. We are always feeding a complete block, +# so the 'incomplete' functionality is unnecessary. As the `entityref` regex is run right before incomplete, +# and the two regex are the same, then incomplete will simply never match and we avoid the logic within. +htmlparser.incomplete = htmlparser.entityref +# Monkeypatch `HTMLParser` to not accept a backtick in a tag name, attribute name, or bare value. +htmlparser.locatestarttagend_tolerant = re.compile(r""" + <[a-zA-Z][^`\t\n\r\f />\x00]* # tag name <= added backtick here + (?:[\s/]* # optional whitespace before attribute name + (?:(?<=['"\s/])[^`\s/>][^\s/=>]* # attribute name <= added backtick here + (?:\s*=+\s* # value indicator + (?:'[^']*' # LITA-enclosed value + |"[^"]*" # LIT-enclosed value + |(?!['"])[^`>\s]* # bare value <= added backtick here + ) + (?:\s*,)* # possibly followed by a comma + )?(?:\s|/(?!>))* + )* + )? + \s* # trailing whitespace +""", re.VERBOSE) + +# Match a blank line at the start of a block of text (two newlines). +# The newlines may be preceded by additional whitespace. +blank_line_re = re.compile(r'^([ ]*\n){2}') + + +class HTMLExtractor(htmlparser.HTMLParser): + """ + Extract raw HTML from text. + + The raw HTML is stored in the [`htmlStash`][markdown.util.HtmlStash] of the + [`Markdown`][markdown.Markdown] instance passed to `md` and the remaining text + is stored in `cleandoc` as a list of strings. + """ + + def __init__(self, md, *args, **kwargs): + if 'convert_charrefs' not in kwargs: + kwargs['convert_charrefs'] = False + + # Block tags that should contain no content (self closing) + self.empty_tags = set(['hr']) + + self.lineno_start_cache = [0] + + # This calls self.reset + super().__init__(*args, **kwargs) + self.md = md + + def reset(self): + """Reset this instance. Loses all unprocessed data.""" + self.inraw = False + self.intail = False + self.stack = [] # When `inraw==True`, stack contains a list of tags + self._cache = [] + self.cleandoc = [] + self.lineno_start_cache = [0] + + super().reset() + + def close(self): + """Handle any buffered data.""" + super().close() + if len(self.rawdata): + # Temp fix for https://bugs.python.org/issue41989 + # TODO: remove this when the bug is fixed in all supported Python versions. + if self.convert_charrefs and not self.cdata_elem: # pragma: no cover + self.handle_data(htmlparser.unescape(self.rawdata)) + else: + self.handle_data(self.rawdata) + # Handle any unclosed tags. + if len(self._cache): + self.cleandoc.append(self.md.htmlStash.store(''.join(self._cache))) + self._cache = [] + + @property + def line_offset(self) -> int: + """Returns char index in `self.rawdata` for the start of the current line. """ + for ii in range(len(self.lineno_start_cache)-1, self.lineno-1): + last_line_start_pos = self.lineno_start_cache[ii] + lf_pos = self.rawdata.find('\n', last_line_start_pos) + if lf_pos == -1: + # No more newlines found. Use end of raw data as start of line beyond end. + lf_pos = len(self.rawdata) + self.lineno_start_cache.append(lf_pos+1) + + return self.lineno_start_cache[self.lineno-1] + + def at_line_start(self) -> bool: + """ + Returns True if current position is at start of line. + + Allows for up to three blank spaces at start of line. + """ + if self.offset == 0: + return True + if self.offset > 3: + return False + # Confirm up to first 3 chars are whitespace + return self.rawdata[self.line_offset:self.line_offset + self.offset].strip() == '' + + def get_endtag_text(self, tag: str) -> str: + """ + Returns the text of the end tag. + + If it fails to extract the actual text from the raw data, it builds a closing tag with `tag`. + """ + # Attempt to extract actual tag from raw source text + start = self.line_offset + self.offset + m = htmlparser.endendtag.search(self.rawdata, start) + if m: + return self.rawdata[start:m.end()] + else: # pragma: no cover + # Failed to extract from raw data. Assume well formed and lowercase. + return '</{}>'.format(tag) + + def handle_starttag(self, tag: str, attrs: list[tuple[str, str]]): + # Handle tags that should always be empty and do not specify a closing tag + if tag in self.empty_tags: + self.handle_startendtag(tag, attrs) + return + + if self.md.is_block_level(tag) and (self.intail or (self.at_line_start() and not self.inraw)): + # Started a new raw block. Prepare stack. + self.inraw = True + self.cleandoc.append('\n') + + text = self.get_starttag_text() + if self.inraw: + self.stack.append(tag) + self._cache.append(text) + else: + self.cleandoc.append(text) + if tag in self.CDATA_CONTENT_ELEMENTS: + # This is presumably a standalone tag in a code span (see #1036). + self.clear_cdata_mode() + + def handle_endtag(self, tag: str): + text = self.get_endtag_text(tag) + + if self.inraw: + self._cache.append(text) + if tag in self.stack: + # Remove tag from stack + while self.stack: + if self.stack.pop() == tag: + break + if len(self.stack) == 0: + # End of raw block. + if blank_line_re.match(self.rawdata[self.line_offset + self.offset + len(text):]): + # Preserve blank line and end of raw block. + self._cache.append('\n') + else: + # More content exists after `endtag`. + self.intail = True + # Reset stack. + self.inraw = False + self.cleandoc.append(self.md.htmlStash.store(''.join(self._cache))) + # Insert blank line between this and next line. + self.cleandoc.append('\n\n') + self._cache = [] + else: + self.cleandoc.append(text) + + def handle_data(self, data: str): + if self.intail and '\n' in data: + self.intail = False + if self.inraw: + self._cache.append(data) + else: + self.cleandoc.append(data) + + def handle_empty_tag(self, data: str, is_block: bool): + """ Handle empty tags (`<data>`). """ + if self.inraw or self.intail: + # Append this to the existing raw block + self._cache.append(data) + elif self.at_line_start() and is_block: + # Handle this as a standalone raw block + if blank_line_re.match(self.rawdata[self.line_offset + self.offset + len(data):]): + # Preserve blank line after tag in raw block. + data += '\n' + else: + # More content exists after tag. + self.intail = True + item = self.cleandoc[-1] if self.cleandoc else '' + # If we only have one newline before block element, add another + if not item.endswith('\n\n') and item.endswith('\n'): + self.cleandoc.append('\n') + self.cleandoc.append(self.md.htmlStash.store(data)) + # Insert blank line between this and next line. + self.cleandoc.append('\n\n') + else: + self.cleandoc.append(data) + + def handle_startendtag(self, tag: str, attrs: list[tuple[str, str]]): + self.handle_empty_tag(self.get_starttag_text(), is_block=self.md.is_block_level(tag)) + + def handle_charref(self, name: str): + self.handle_empty_tag('&#{};'.format(name), is_block=False) + + def handle_entityref(self, name: str): + self.handle_empty_tag('&{};'.format(name), is_block=False) + + def handle_comment(self, data: str): + self.handle_empty_tag('<!--{}-->'.format(data), is_block=True) + + def handle_decl(self, data: str): + self.handle_empty_tag('<!{}>'.format(data), is_block=True) + + def handle_pi(self, data: str): + self.handle_empty_tag('<?{}?>'.format(data), is_block=True) + + def unknown_decl(self, data: str): + end = ']]>' if data.startswith('CDATA[') else ']>' + self.handle_empty_tag('<![{}{}'.format(data, end), is_block=True) + + def parse_pi(self, i: int) -> int: + if self.at_line_start() or self.intail: + return super().parse_pi(i) + # This is not the beginning of a raw block so treat as plain data + # and avoid consuming any tags which may follow (see #1066). + self.handle_data('<?') + return i + 2 + + def parse_html_declaration(self, i: int) -> int: + if self.at_line_start() or self.intail: + return super().parse_html_declaration(i) + # This is not the beginning of a raw block so treat as plain data + # and avoid consuming any tags which may follow (see #1066). + self.handle_data('<!') + return i + 2 + + # The rest has been copied from base class in standard lib to address #1036. + # As `__startag_text` is private, all references to it must be in this subclass. + # The last few lines of `parse_starttag` are reversed so that `handle_starttag` + # can override `cdata_mode` in certain situations (in a code span). + __starttag_text: str | None = None + + def get_starttag_text(self) -> str: + """Return full source of start tag: `<...>`.""" + return self.__starttag_text + + def parse_starttag(self, i: int) -> int: # pragma: no cover + self.__starttag_text = None + endpos = self.check_for_whole_start_tag(i) + if endpos < 0: + return endpos + rawdata = self.rawdata + self.__starttag_text = rawdata[i:endpos] + + # Now parse the data between `i+1` and `j` into a tag and `attrs` + attrs = [] + match = htmlparser.tagfind_tolerant.match(rawdata, i+1) + assert match, 'unexpected call to parse_starttag()' + k = match.end() + self.lasttag = tag = match.group(1).lower() + while k < endpos: + m = htmlparser.attrfind_tolerant.match(rawdata, k) + if not m: + break + attrname, rest, attrvalue = m.group(1, 2, 3) + if not rest: + attrvalue = None + elif attrvalue[:1] == '\'' == attrvalue[-1:] or \ + attrvalue[:1] == '"' == attrvalue[-1:]: # noqa: E127 + attrvalue = attrvalue[1:-1] + if attrvalue: + attrvalue = htmlparser.unescape(attrvalue) + attrs.append((attrname.lower(), attrvalue)) + k = m.end() + + end = rawdata[k:endpos].strip() + if end not in (">", "/>"): + lineno, offset = self.getpos() + if "\n" in self.__starttag_text: + lineno = lineno + self.__starttag_text.count("\n") + offset = len(self.__starttag_text) \ + - self.__starttag_text.rfind("\n") # noqa: E127 + else: + offset = offset + len(self.__starttag_text) + self.handle_data(rawdata[i:endpos]) + return endpos + if end.endswith('/>'): + # XHTML-style empty tag: `<span attr="value" />` + self.handle_startendtag(tag, attrs) + else: + # *** set `cdata_mode` first so we can override it in `handle_starttag` (see #1036) *** + if tag in self.CDATA_CONTENT_ELEMENTS: + self.set_cdata_mode(tag) + self.handle_starttag(tag, attrs) + return endpos diff --git a/plugins/markdown_preview/markdown/inlinepatterns.py b/plugins/markdown_preview/markdown/inlinepatterns.py new file mode 100644 index 0000000..296ab83 --- /dev/null +++ b/plugins/markdown_preview/markdown/inlinepatterns.py @@ -0,0 +1,992 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +In version 3.0, a new, more flexible inline processor was added, [`markdown.inlinepatterns.InlineProcessor`][]. The +original inline patterns, which inherit from [`markdown.inlinepatterns.Pattern`][] or one of its children are still +supported, though users are encouraged to migrate. + +The new `InlineProcessor` provides two major enhancements to `Patterns`: + +1. Inline Processors no longer need to match the entire block, so regular expressions no longer need to start with + `r'^(.*?)'` and end with `r'(.*?)%'`. This runs faster. The returned [`Match`][re.Match] object will only contain + what is explicitly matched in the pattern, and extension pattern groups now start with `m.group(1)`. + +2. The `handleMatch` method now takes an additional input called `data`, which is the entire block under analysis, + not just what is matched with the specified pattern. The method now returns the element *and* the indexes relative + to `data` that the return element is replacing (usually `m.start(0)` and `m.end(0)`). If the boundaries are + returned as `None`, it is assumed that the match did not take place, and nothing will be altered in `data`. + + This allows handling of more complex constructs than regular expressions can handle, e.g., matching nested + brackets, and explicit control of the span "consumed" by the processor. + +""" + +from __future__ import annotations + +from . import util +from typing import TYPE_CHECKING, Any, Collection, NamedTuple +import re +import xml.etree.ElementTree as etree +try: # pragma: no cover + from html import entities +except ImportError: # pragma: no cover + import htmlentitydefs as entities + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + + +def build_inlinepatterns(md: Markdown, **kwargs: Any) -> util.Registry[InlineProcessor]: + """ + Build the default set of inline patterns for Markdown. + + The order in which processors and/or patterns are applied is very important - e.g. if we first replace + `http://.../` links with `<a>` tags and _then_ try to replace inline HTML, we would end up with a mess. So, we + apply the expressions in the following order: + + * backticks and escaped characters have to be handled before everything else so that we can preempt any markdown + patterns by escaping them; + + * then we handle the various types of links (auto-links must be handled before inline HTML); + + * then we handle inline HTML. At this point we will simply replace all inline HTML strings with a placeholder + and add the actual HTML to a stash; + + * finally we apply strong, emphasis, etc. + + """ + inlinePatterns = util.Registry() + inlinePatterns.register(BacktickInlineProcessor(BACKTICK_RE), 'backtick', 190) + inlinePatterns.register(EscapeInlineProcessor(ESCAPE_RE, md), 'escape', 180) + inlinePatterns.register(ReferenceInlineProcessor(REFERENCE_RE, md), 'reference', 170) + inlinePatterns.register(LinkInlineProcessor(LINK_RE, md), 'link', 160) + inlinePatterns.register(ImageInlineProcessor(IMAGE_LINK_RE, md), 'image_link', 150) + inlinePatterns.register( + ImageReferenceInlineProcessor(IMAGE_REFERENCE_RE, md), 'image_reference', 140 + ) + inlinePatterns.register( + ShortReferenceInlineProcessor(REFERENCE_RE, md), 'short_reference', 130 + ) + inlinePatterns.register( + ShortImageReferenceInlineProcessor(IMAGE_REFERENCE_RE, md), 'short_image_ref', 125 + ) + inlinePatterns.register(AutolinkInlineProcessor(AUTOLINK_RE, md), 'autolink', 120) + inlinePatterns.register(AutomailInlineProcessor(AUTOMAIL_RE, md), 'automail', 110) + inlinePatterns.register(SubstituteTagInlineProcessor(LINE_BREAK_RE, 'br'), 'linebreak', 100) + inlinePatterns.register(HtmlInlineProcessor(HTML_RE, md), 'html', 90) + inlinePatterns.register(HtmlInlineProcessor(ENTITY_RE, md), 'entity', 80) + inlinePatterns.register(SimpleTextInlineProcessor(NOT_STRONG_RE), 'not_strong', 70) + inlinePatterns.register(AsteriskProcessor(r'\*'), 'em_strong', 60) + inlinePatterns.register(UnderscoreProcessor(r'_'), 'em_strong2', 50) + return inlinePatterns + + +# The actual regular expressions for patterns +# ----------------------------------------------------------------------------- + +NOIMG = r'(?<!\!)' +""" Match not an image. Partial regular expression which matches if not preceded by `!`. """ + +BACKTICK_RE = r'(?:(?<!\\)((?:\\{2})+)(?=`+)|(?<!\\)(`+)(.+?)(?<!`)\2(?!`))' +""" Match backtick quoted string (`` `e=f()` `` or ``` ``e=f("`")`` ```). """ + +ESCAPE_RE = r'\\(.)' +""" Match a backslash escaped character (`\\<` or `\\*`). """ + +EMPHASIS_RE = r'(\*)([^\*]+)\1' +""" Match emphasis with an asterisk (`*emphasis*`). """ + +STRONG_RE = r'(\*{2})(.+?)\1' +""" Match strong with an asterisk (`**strong**`). """ + +SMART_STRONG_RE = r'(?<!\w)(_{2})(?!_)(.+?)(?<!_)\1(?!\w)' +""" Match strong with underscore while ignoring middle word underscores (`__smart__strong__`). """ + +SMART_EMPHASIS_RE = r'(?<!\w)(_)(?!_)(.+?)(?<!_)\1(?!\w)' +""" Match emphasis with underscore while ignoring middle word underscores (`_smart_emphasis_`). """ + +SMART_STRONG_EM_RE = r'(?<!\w)(\_)\1(?!\1)(.+?)(?<!\w)\1(?!\1)(.+?)\1{3}(?!\w)' +""" Match strong emphasis with underscores (`__strong _em__`). """ + +EM_STRONG_RE = r'(\*)\1{2}(.+?)\1(.*?)\1{2}' +""" Match emphasis strong with asterisk (`***strongem***` or `***em*strong**`). """ + +EM_STRONG2_RE = r'(_)\1{2}(.+?)\1(.*?)\1{2}' +""" Match emphasis strong with underscores (`___emstrong___` or `___em_strong__`). """ + +STRONG_EM_RE = r'(\*)\1{2}(.+?)\1{2}(.*?)\1' +""" Match strong emphasis with asterisk (`***strong**em*`). """ + +STRONG_EM2_RE = r'(_)\1{2}(.+?)\1{2}(.*?)\1' +""" Match strong emphasis with underscores (`___strong__em_`). """ + +STRONG_EM3_RE = r'(\*)\1(?!\1)([^*]+?)\1(?!\1)(.+?)\1{3}' +""" Match strong emphasis with asterisk (`**strong*em***`). """ + +LINK_RE = NOIMG + r'\[' +""" Match start of in-line link (`[text](url)` or `[text](<url>)` or `[text](url "title")`). """ + +IMAGE_LINK_RE = r'\!\[' +""" Match start of in-line image link (`![alttxt](url)` or `![alttxt](<url>)`). """ + +REFERENCE_RE = LINK_RE +""" Match start of reference link (`[Label][3]`). """ + +IMAGE_REFERENCE_RE = IMAGE_LINK_RE +""" Match start of image reference (`![alt text][2]`). """ + +NOT_STRONG_RE = r'((^|(?<=\s))(\*{1,3}|_{1,3})(?=\s|$))' +""" Match a stand-alone `*` or `_`. """ + +AUTOLINK_RE = r'<((?:[Ff]|[Hh][Tt])[Tt][Pp][Ss]?://[^<>]*)>' +""" Match an automatic link (`<http://www.example.com>`). """ + +AUTOMAIL_RE = r'<([^<> !]+@[^@<> ]+)>' +""" Match an automatic email link (`<me@example.com>`). """ + +HTML_RE = r'(<(\/?[a-zA-Z][^<>@ ]*( [^<>]*)?|!--(?:(?!<!--|-->).)*--)>)' +""" Match an HTML tag (`<...>`). """ + +ENTITY_RE = r'(&(?:\#[0-9]+|\#x[0-9a-fA-F]+|[a-zA-Z0-9]+);)' +""" Match an HTML entity (`&` (decimal) or `&` (hex) or `&` (named)). """ + +LINE_BREAK_RE = r' \n' +""" Match two spaces at end of line. """ + + +def dequote(string: str) -> str: + """Remove quotes from around a string.""" + if ((string.startswith('"') and string.endswith('"')) or + (string.startswith("'") and string.endswith("'"))): + return string[1:-1] + else: + return string + + +class EmStrongItem(NamedTuple): + """Emphasis/strong pattern item.""" + pattern: re.Pattern[str] + builder: str + tags: str + + +# The pattern classes +# ----------------------------------------------------------------------------- + + +class Pattern: # pragma: no cover + """ + Base class that inline patterns subclass. + + Inline patterns are handled by means of `Pattern` subclasses, one per regular expression. + Each pattern object uses a single regular expression and must support the following methods: + [`getCompiledRegExp`][markdown.inlinepatterns.Pattern.getCompiledRegExp] and + [`handleMatch`][markdown.inlinepatterns.Pattern.handleMatch]. + + All the regular expressions used by `Pattern` subclasses must capture the whole block. For this + reason, they all start with `^(.*)` and end with `(.*)!`. When passing a regular expression on + class initialization, the `^(.*)` and `(.*)!` are added automatically and the regular expression + is pre-compiled. + + It is strongly suggested that the newer style [`markdown.inlinepatterns.InlineProcessor`][] that + use a more efficient and flexible search approach be used instead. However, the older style + `Pattern` remains for backward compatibility with many existing third-party extensions. + + """ + + ANCESTOR_EXCLUDES: Collection[str] = tuple() + """ + A collection of elements which are undesirable ancestors. The processor will be skipped if it + would cause the content to be a descendant of one of the listed tag names. + """ + + def __init__(self, pattern: str, md: Markdown | None = None): + """ + Create an instant of an inline pattern. + + Arguments: + pattern: A regular expression that matches a pattern. + md: An optional pointer to the instance of `markdown.Markdown` and is available as + `self.md` on the class instance. + + + """ + self.pattern = pattern + self.compiled_re = re.compile(r"^(.*?)%s(.*)$" % pattern, + re.DOTALL | re.UNICODE) + + self.md = md + + def getCompiledRegExp(self) -> re.Pattern: + """ Return a compiled regular expression. """ + return self.compiled_re + + def handleMatch(self, m: re.Match[str]) -> etree.Element | str: + """Return a ElementTree element from the given match. + + Subclasses should override this method. + + Arguments: + m: A match object containing a match of the pattern. + + Returns: An ElementTree Element object. + + """ + pass # pragma: no cover + + def type(self) -> str: + """ Return class name, to define pattern type """ + return self.__class__.__name__ + + def unescape(self, text: str) -> str: + """ Return unescaped text given text with an inline placeholder. """ + try: + stash = self.md.treeprocessors['inline'].stashed_nodes + except KeyError: # pragma: no cover + return text + + def get_stash(m): + id = m.group(1) + if id in stash: + value = stash.get(id) + if isinstance(value, str): + return value + else: + # An `etree` Element - return text content only + return ''.join(value.itertext()) + return util.INLINE_PLACEHOLDER_RE.sub(get_stash, text) + + +class InlineProcessor(Pattern): + """ + Base class that inline processors subclass. + + This is the newer style inline processor that uses a more + efficient and flexible search approach. + + """ + + def __init__(self, pattern: str, md: Markdown | None = None): + """ + Create an instant of an inline processor. + + Arguments: + pattern: A regular expression that matches a pattern. + md: An optional pointer to the instance of `markdown.Markdown` and is available as + `self.md` on the class instance. + + """ + self.pattern = pattern + self.compiled_re = re.compile(pattern, re.DOTALL | re.UNICODE) + + # API for Markdown to pass `safe_mode` into instance + self.safe_mode = False + self.md = md + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | str | None, int | None, int | None]: + """Return a ElementTree element from the given match and the + start and end index of the matched text. + + If `start` and/or `end` are returned as `None`, it will be + assumed that the processor did not find a valid region of text. + + Subclasses should override this method. + + Arguments: + m: A re match object containing a match of the pattern. + data: The buffer currently under analysis. + + Returns: + el: The ElementTree element, text or None. + start: The start of the region that has been matched or None. + end: The end of the region that has been matched or None. + + """ + pass # pragma: no cover + + +class SimpleTextPattern(Pattern): # pragma: no cover + """ Return a simple text of `group(2)` of a Pattern. """ + def handleMatch(self, m: re.Match[str]) -> str: + """ Return string content of `group(2)` of a matching pattern. """ + return m.group(2) + + +class SimpleTextInlineProcessor(InlineProcessor): + """ Return a simple text of `group(1)` of a Pattern. """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[str, int, int]: + """ Return string content of `group(1)` of a matching pattern. """ + return m.group(1), m.start(0), m.end(0) + + +class EscapeInlineProcessor(InlineProcessor): + """ Return an escaped character. """ + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[str | None, int, int]: + """ + If the character matched by `group(1)` of a pattern is in [`ESCAPED_CHARS`][markdown.Markdown.ESCAPED_CHARS] + then return the integer representing the character's Unicode code point (as returned by [`ord`][]) wrapped + in [`util.STX`][markdown.util.STX] and [`util.ETX`][markdown.util.ETX]. + + If the matched character is not in [`ESCAPED_CHARS`][markdown.Markdown.ESCAPED_CHARS], then return `None`. + """ + + char = m.group(1) + if char in self.md.ESCAPED_CHARS: + return '{}{}{}'.format(util.STX, ord(char), util.ETX), m.start(0), m.end(0) + else: + return None, m.start(0), m.end(0) + + +class SimpleTagPattern(Pattern): # pragma: no cover + """ + Return element of type `tag` with a text attribute of `group(3)` + of a Pattern. + + """ + def __init__(self, pattern: str, tag: str): + """ + Create an instant of an simple tag pattern. + + Arguments: + pattern: A regular expression that matches a pattern. + tag: Tag of element. + + """ + Pattern.__init__(self, pattern) + self.tag = tag + """ The tag of the rendered element. """ + + def handleMatch(self, m: re.Match[str]) -> etree.Element: + """ + Return [`Element`][xml.etree.ElementTree.Element] of type `tag` with the string in `group(3)` of a + matching pattern as the Element's text. + """ + el = etree.Element(self.tag) + el.text = m.group(3) + return el + + +class SimpleTagInlineProcessor(InlineProcessor): + """ + Return element of type `tag` with a text attribute of `group(2)` + of a Pattern. + + """ + def __init__(self, pattern: str, tag: str): + """ + Create an instant of an simple tag processor. + + Arguments: + pattern: A regular expression that matches a pattern. + tag: Tag of element. + + """ + InlineProcessor.__init__(self, pattern) + self.tag = tag + """ The tag of the rendered element. """ + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element, int, int]: # pragma: no cover + """ + Return [`Element`][xml.etree.ElementTree.Element] of type `tag` with the string in `group(2)` of a + matching pattern as the Element's text. + """ + el = etree.Element(self.tag) + el.text = m.group(2) + return el, m.start(0), m.end(0) + + +class SubstituteTagPattern(SimpleTagPattern): # pragma: no cover + """ Return an element of type `tag` with no children. """ + def handleMatch(self, m: re.Match[str]) -> etree.Element: + """ Return empty [`Element`][xml.etree.ElementTree.Element] of type `tag`. """ + return etree.Element(self.tag) + + +class SubstituteTagInlineProcessor(SimpleTagInlineProcessor): + """ Return an element of type `tag` with no children. """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element, int, int]: + """ Return empty [`Element`][xml.etree.ElementTree.Element] of type `tag`. """ + return etree.Element(self.tag), m.start(0), m.end(0) + + +class BacktickInlineProcessor(InlineProcessor): + """ Return a `<code>` element containing the escaped matching text. """ + def __init__(self, pattern): + InlineProcessor.__init__(self, pattern) + self.ESCAPED_BSLASH = '{}{}{}'.format(util.STX, ord('\\'), util.ETX) + self.tag = 'code' + """ The tag of the rendered element. """ + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | str, int, int]: + """ + If the match contains `group(3)` of a pattern, then return a `code` + [`Element`][xml.etree.ElementTree.Element] which contains HTML escaped text (with + [`code_escape`][markdown.util.code_escape]) as an [`AtomicString`][markdown.util.AtomicString]. + + If the match does not contain `group(3)` then return the text of `group(1)` backslash escaped. + + """ + if m.group(3): + el = etree.Element(self.tag) + el.text = util.AtomicString(util.code_escape(m.group(3).strip())) + return el, m.start(0), m.end(0) + else: + return m.group(1).replace('\\\\', self.ESCAPED_BSLASH), m.start(0), m.end(0) + + +class DoubleTagPattern(SimpleTagPattern): # pragma: no cover + """Return a ElementTree element nested in tag2 nested in tag1. + + Useful for strong emphasis etc. + + """ + def handleMatch(self, m: re.Match[str]) -> etree.Element: + """ + Return [`Element`][xml.etree.ElementTree.Element] in following format: + `<tag1><tag2>group(3)</tag2>group(4)</tag2>` where `group(4)` is optional. + + """ + tag1, tag2 = self.tag.split(",") + el1 = etree.Element(tag1) + el2 = etree.SubElement(el1, tag2) + el2.text = m.group(3) + if len(m.groups()) == 5: + el2.tail = m.group(4) + return el1 + + +class DoubleTagInlineProcessor(SimpleTagInlineProcessor): + """Return a ElementTree element nested in tag2 nested in tag1. + + Useful for strong emphasis etc. + + """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element, int, int]: # pragma: no cover + """ + Return [`Element`][xml.etree.ElementTree.Element] in following format: + `<tag1><tag2>group(2)</tag2>group(3)</tag2>` where `group(3)` is optional. + + """ + tag1, tag2 = self.tag.split(",") + el1 = etree.Element(tag1) + el2 = etree.SubElement(el1, tag2) + el2.text = m.group(2) + if len(m.groups()) == 3: + el2.tail = m.group(3) + return el1, m.start(0), m.end(0) + + +class HtmlInlineProcessor(InlineProcessor): + """ Store raw inline html and return a placeholder. """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[str, int, int]: + """ Store the text of `group(1)` of a pattern and return a placeholder string. """ + rawhtml = self.backslash_unescape(self.unescape(m.group(1))) + place_holder = self.md.htmlStash.store(rawhtml) + return place_holder, m.start(0), m.end(0) + + def unescape(self, text): + """ Return unescaped text given text with an inline placeholder. """ + try: + stash = self.md.treeprocessors['inline'].stashed_nodes + except KeyError: # pragma: no cover + return text + + def get_stash(m): + id = m.group(1) + value = stash.get(id) + if value is not None: + try: + return self.md.serializer(value) + except Exception: + return r'\%s' % value + + return util.INLINE_PLACEHOLDER_RE.sub(get_stash, text) + + def backslash_unescape(self, text): + """ Return text with backslash escapes undone (backslashes are restored). """ + try: + RE = self.md.treeprocessors['unescape'].RE + except KeyError: # pragma: no cover + return text + + def _unescape(m): + return chr(int(m.group(1))) + + return RE.sub(_unescape, text) + + +class AsteriskProcessor(InlineProcessor): + """Emphasis processor for handling strong and em matches inside asterisks.""" + + PATTERNS = [ + EmStrongItem(re.compile(EM_STRONG_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'), + EmStrongItem(re.compile(STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'), + EmStrongItem(re.compile(STRONG_EM3_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'), + EmStrongItem(re.compile(STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'), + EmStrongItem(re.compile(EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em') + ] + """ The various strong and emphasis patterns handled by this processor. """ + + def build_single(self, m, tag, idx): + """Return single tag.""" + el1 = etree.Element(tag) + text = m.group(2) + self.parse_sub_patterns(text, el1, None, idx) + return el1 + + def build_double(self, m, tags, idx): + """Return double tag.""" + + tag1, tag2 = tags.split(",") + el1 = etree.Element(tag1) + el2 = etree.Element(tag2) + text = m.group(2) + self.parse_sub_patterns(text, el2, None, idx) + el1.append(el2) + if len(m.groups()) == 3: + text = m.group(3) + self.parse_sub_patterns(text, el1, el2, idx) + return el1 + + def build_double2(self, m, tags, idx): + """Return double tags (variant 2): `<strong>text <em>text</em></strong>`.""" + + tag1, tag2 = tags.split(",") + el1 = etree.Element(tag1) + el2 = etree.Element(tag2) + text = m.group(2) + self.parse_sub_patterns(text, el1, None, idx) + text = m.group(3) + el1.append(el2) + self.parse_sub_patterns(text, el2, None, idx) + return el1 + + def parse_sub_patterns(self, data, parent, last, idx) -> None: + """ + Parses sub patterns. + + `data` (`str`): + text to evaluate. + + `parent` (`etree.Element`): + Parent to attach text and sub elements to. + + `last` (`etree.Element`): + Last appended child to parent. Can also be None if parent has no children. + + `idx` (`int`): + Current pattern index that was used to evaluate the parent. + + """ + + offset = 0 + pos = 0 + + length = len(data) + while pos < length: + # Find the start of potential emphasis or strong tokens + if self.compiled_re.match(data, pos): + matched = False + # See if the we can match an emphasis/strong pattern + for index, item in enumerate(self.PATTERNS): + # Only evaluate patterns that are after what was used on the parent + if index <= idx: + continue + m = item.pattern.match(data, pos) + if m: + # Append child nodes to parent + # Text nodes should be appended to the last + # child if present, and if not, it should + # be added as the parent's text node. + text = data[offset:m.start(0)] + if text: + if last is not None: + last.tail = text + else: + parent.text = text + el = self.build_element(m, item.builder, item.tags, index) + parent.append(el) + last = el + # Move our position past the matched hunk + offset = pos = m.end(0) + matched = True + if not matched: + # We matched nothing, move on to the next character + pos += 1 + else: + # Increment position as no potential emphasis start was found. + pos += 1 + + # Append any leftover text as a text node. + text = data[offset:] + if text: + if last is not None: + last.tail = text + else: + parent.text = text + + def build_element(self, m, builder, tags, index): + """Element builder.""" + + if builder == 'double2': + return self.build_double2(m, tags, index) + elif builder == 'double': + return self.build_double(m, tags, index) + else: + return self.build_single(m, tags, index) + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | None, int | None, int | None]: + """Parse patterns.""" + + el = None + start = None + end = None + + for index, item in enumerate(self.PATTERNS): + m1 = item.pattern.match(data, m.start(0)) + if m1: + start = m1.start(0) + end = m1.end(0) + el = self.build_element(m1, item.builder, item.tags, index) + break + return el, start, end + + +class UnderscoreProcessor(AsteriskProcessor): + """Emphasis processor for handling strong and em matches inside underscores.""" + + PATTERNS = [ + EmStrongItem(re.compile(EM_STRONG2_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'), + EmStrongItem(re.compile(STRONG_EM2_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'), + EmStrongItem(re.compile(SMART_STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'), + EmStrongItem(re.compile(SMART_STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'), + EmStrongItem(re.compile(SMART_EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em') + ] + """ The various strong and emphasis patterns handled by this processor. """ + + +class LinkInlineProcessor(InlineProcessor): + """ Return a link element from the given match. """ + RE_LINK = re.compile(r'''\(\s*(?:(<[^<>]*>)\s*(?:('[^']*'|"[^"]*")\s*)?\))?''', re.DOTALL | re.UNICODE) + RE_TITLE_CLEAN = re.compile(r'\s') + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | None, int | None, int | None]: + """ Return an `a` [`Element`][xml.etree.ElementTree.Element] or `(None, None, None)`. """ + text, index, handled = self.getText(data, m.end(0)) + + if not handled: + return None, None, None + + href, title, index, handled = self.getLink(data, index) + if not handled: + return None, None, None + + el = etree.Element("a") + el.text = text + + el.set("href", href) + + if title is not None: + el.set("title", title) + + return el, m.start(0), index + + def getLink(self, data, index): + """Parse data between `()` of `[Text]()` allowing recursive `()`. """ + + href = '' + title = None + handled = False + + m = self.RE_LINK.match(data, pos=index) + if m and m.group(1): + # Matches [Text](<link> "title") + href = m.group(1)[1:-1].strip() + if m.group(2): + title = m.group(2)[1:-1] + index = m.end(0) + handled = True + elif m: + # Track bracket nesting and index in string + bracket_count = 1 + backtrack_count = 1 + start_index = m.end() + index = start_index + last_bracket = -1 + + # Primary (first found) quote tracking. + quote = None + start_quote = -1 + exit_quote = -1 + ignore_matches = False + + # Secondary (second found) quote tracking. + alt_quote = None + start_alt_quote = -1 + exit_alt_quote = -1 + + # Track last character + last = '' + + for pos in range(index, len(data)): + c = data[pos] + if c == '(': + # Count nested ( + # Don't increment the bracket count if we are sure we're in a title. + if not ignore_matches: + bracket_count += 1 + elif backtrack_count > 0: + backtrack_count -= 1 + elif c == ')': + # Match nested ) to ( + # Don't decrement if we are sure we are in a title that is unclosed. + if ((exit_quote != -1 and quote == last) or (exit_alt_quote != -1 and alt_quote == last)): + bracket_count = 0 + elif not ignore_matches: + bracket_count -= 1 + elif backtrack_count > 0: + backtrack_count -= 1 + # We've found our backup end location if the title doesn't resolve. + if backtrack_count == 0: + last_bracket = index + 1 + + elif c in ("'", '"'): + # Quote has started + if not quote: + # We'll assume we are now in a title. + # Brackets are quoted, so no need to match them (except for the final one). + ignore_matches = True + backtrack_count = bracket_count + bracket_count = 1 + start_quote = index + 1 + quote = c + # Secondary quote (in case the first doesn't resolve): [text](link'"title") + elif c != quote and not alt_quote: + start_alt_quote = index + 1 + alt_quote = c + # Update primary quote match + elif c == quote: + exit_quote = index + 1 + # Update secondary quote match + elif alt_quote and c == alt_quote: + exit_alt_quote = index + 1 + + index += 1 + + # Link is closed, so let's break out of the loop + if bracket_count == 0: + # Get the title if we closed a title string right before link closed + if exit_quote >= 0 and quote == last: + href = data[start_index:start_quote - 1] + title = ''.join(data[start_quote:exit_quote - 1]) + elif exit_alt_quote >= 0 and alt_quote == last: + href = data[start_index:start_alt_quote - 1] + title = ''.join(data[start_alt_quote:exit_alt_quote - 1]) + else: + href = data[start_index:index - 1] + break + + if c != ' ': + last = c + + # We have a scenario: `[test](link"notitle)` + # When we enter a string, we stop tracking bracket resolution in the main counter, + # but we do keep a backup counter up until we discover where we might resolve all brackets + # if the title string fails to resolve. + if bracket_count != 0 and backtrack_count == 0: + href = data[start_index:last_bracket - 1] + index = last_bracket + bracket_count = 0 + + handled = bracket_count == 0 + + if title is not None: + title = self.RE_TITLE_CLEAN.sub(' ', dequote(self.unescape(title.strip()))) + + href = self.unescape(href).strip() + + return href, title, index, handled + + def getText(self, data, index): + """Parse the content between `[]` of the start of an image or link + resolving nested square brackets. + + """ + bracket_count = 1 + text = [] + for pos in range(index, len(data)): + c = data[pos] + if c == ']': + bracket_count -= 1 + elif c == '[': + bracket_count += 1 + index += 1 + if bracket_count == 0: + break + text.append(c) + return ''.join(text), index, bracket_count == 0 + + +class ImageInlineProcessor(LinkInlineProcessor): + """ Return a `img` element from the given match. """ + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | None, int | None, int | None]: + """ Return an `img` [`Element`][xml.etree.ElementTree.Element] or `(None, None, None)`. """ + text, index, handled = self.getText(data, m.end(0)) + if not handled: + return None, None, None + + src, title, index, handled = self.getLink(data, index) + if not handled: + return None, None, None + + el = etree.Element("img") + + el.set("src", src) + + if title is not None: + el.set("title", title) + + el.set('alt', self.unescape(text)) + return el, m.start(0), index + + +class ReferenceInlineProcessor(LinkInlineProcessor): + """ Match to a stored reference and return link element. """ + NEWLINE_CLEANUP_RE = re.compile(r'\s+', re.MULTILINE) + + RE_LINK = re.compile(r'\s?\[([^\]]*)\]', re.DOTALL | re.UNICODE) + + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | None, int | None, int | None]: + """ + Return [`Element`][xml.etree.ElementTree.Element] returned by `makeTag` method or `(None, None, None)`. + + """ + text, index, handled = self.getText(data, m.end(0)) + if not handled: + return None, None, None + + id, end, handled = self.evalId(data, index, text) + if not handled: + return None, None, None + + # Clean up line breaks in id + id = self.NEWLINE_CLEANUP_RE.sub(' ', id) + if id not in self.md.references: # ignore undefined refs + return None, m.start(0), end + + href, title = self.md.references[id] + + return self.makeTag(href, title, text), m.start(0), end + + def evalId(self, data, index, text): + """ + Evaluate the id portion of `[ref][id]`. + + If `[ref][]` use `[ref]`. + """ + m = self.RE_LINK.match(data, pos=index) + if not m: + return None, index, False + else: + id = m.group(1).lower() + end = m.end(0) + if not id: + id = text.lower() + return id, end, True + + def makeTag(self, href: str, title: str, text: str) -> etree.Element: + """ Return an `a` [`Element`][xml.etree.ElementTree.Element]. """ + el = etree.Element('a') + + el.set('href', href) + if title: + el.set('title', title) + + el.text = text + return el + + +class ShortReferenceInlineProcessor(ReferenceInlineProcessor): + """Short form of reference: `[google]`. """ + def evalId(self, data, index, text): + """Evaluate the id of `[ref]`. """ + + return text.lower(), index, True + + +class ImageReferenceInlineProcessor(ReferenceInlineProcessor): + """ Match to a stored reference and return `img` element. """ + def makeTag(self, href: str, title: str, text: str) -> etree.Element: + """ Return an `img` [`Element`][xml.etree.ElementTree.Element]. """ + el = etree.Element("img") + el.set("src", href) + if title: + el.set("title", title) + el.set("alt", self.unescape(text)) + return el + + +class ShortImageReferenceInlineProcessor(ImageReferenceInlineProcessor): + """ Short form of image reference: `![ref]`. """ + def evalId(self, data, index, text): + """Evaluate the id of `[ref]`. """ + + return text.lower(), index, True + + +class AutolinkInlineProcessor(InlineProcessor): + """ Return a link Element given an auto-link (`<http://example/com>`). """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element, int, int]: + """ Return an `a` [`Element`][xml.etree.ElementTree.Element] of `group(1)`. """ + el = etree.Element("a") + el.set('href', self.unescape(m.group(1))) + el.text = util.AtomicString(m.group(1)) + return el, m.start(0), m.end(0) + + +class AutomailInlineProcessor(InlineProcessor): + """ + Return a `mailto` link Element given an auto-mail link (`<foo@example.com>`). + """ + def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element, int, int]: + """ Return an [`Element`][xml.etree.ElementTree.Element] containing a `mailto` link of `group(1)`. """ + el = etree.Element('a') + email = self.unescape(m.group(1)) + if email.startswith("mailto:"): + email = email[len("mailto:"):] + + def codepoint2name(code): + """Return entity definition by code, or the code if not defined.""" + entity = entities.codepoint2name.get(code) + if entity: + return "{}{};".format(util.AMP_SUBSTITUTE, entity) + else: + return "%s#%d;" % (util.AMP_SUBSTITUTE, code) + + letters = [codepoint2name(ord(letter)) for letter in email] + el.text = util.AtomicString(''.join(letters)) + + mailto = "mailto:" + email + mailto = "".join([util.AMP_SUBSTITUTE + '#%d;' % + ord(letter) for letter in mailto]) + el.set('href', mailto) + return el, m.start(0), m.end(0) diff --git a/plugins/markdown_preview/markdown/postprocessors.py b/plugins/markdown_preview/markdown/postprocessors.py new file mode 100644 index 0000000..3da5ee1 --- /dev/null +++ b/plugins/markdown_preview/markdown/postprocessors.py @@ -0,0 +1,143 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" + +Post-processors run on the text of the entire document after is has been serialized into a string. +Postprocessors should be used to work with the text just before output. Usually, they are used add +back sections that were extracted in a preprocessor, fix up outgoing encodings, or wrap the whole +document. + +""" + +from __future__ import annotations + +from collections import OrderedDict +from typing import TYPE_CHECKING, Any +from . import util +import re + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + + +def build_postprocessors(md: Markdown, **kwargs: Any) -> util.Registry[Postprocessor]: + """ Build the default postprocessors for Markdown. """ + postprocessors = util.Registry() + postprocessors.register(RawHtmlPostprocessor(md), 'raw_html', 30) + postprocessors.register(AndSubstitutePostprocessor(), 'amp_substitute', 20) + return postprocessors + + +class Postprocessor(util.Processor): + """ + Postprocessors are run after the ElementTree it converted back into text. + + Each Postprocessor implements a `run` method that takes a pointer to a + text string, modifies it as necessary and returns a text string. + + Postprocessors must extend `Postprocessor`. + + """ + + def run(self, text: str) -> str: + """ + Subclasses of `Postprocessor` should implement a `run` method, which + takes the html document as a single text string and returns a + (possibly modified) string. + + """ + pass # pragma: no cover + + +class RawHtmlPostprocessor(Postprocessor): + """ Restore raw html to the document. """ + + BLOCK_LEVEL_REGEX = re.compile(r'^\<\/?([^ >]+)') + + def run(self, text: str): + """ Iterate over html stash and restore html. """ + replacements = OrderedDict() + for i in range(self.md.htmlStash.html_counter): + html = self.stash_to_string(self.md.htmlStash.rawHtmlBlocks[i]) + if self.isblocklevel(html): + replacements["<p>{}</p>".format( + self.md.htmlStash.get_placeholder(i))] = html + replacements[self.md.htmlStash.get_placeholder(i)] = html + + def substitute_match(m): + key = m.group(0) + + if key not in replacements: + if key[3:-4] in replacements: + return f'<p>{ replacements[key[3:-4]] }</p>' + else: + return key + + return replacements[key] + + if replacements: + base_placeholder = util.HTML_PLACEHOLDER % r'([0-9]+)' + pattern = re.compile(f'<p>{ base_placeholder }</p>|{ base_placeholder }') + processed_text = pattern.sub(substitute_match, text) + else: + return text + + if processed_text == text: + return processed_text + else: + return self.run(processed_text) + + def isblocklevel(self, html: str) -> bool: + """ Check is block of HTML is block-level. """ + m = self.BLOCK_LEVEL_REGEX.match(html) + if m: + if m.group(1)[0] in ('!', '?', '@', '%'): + # Comment, PHP etc... + return True + return self.md.is_block_level(m.group(1)) + return False + + def stash_to_string(self, text: str) -> str: + """ Convert a stashed object to a string. """ + return str(text) + + +class AndSubstitutePostprocessor(Postprocessor): + """ Restore valid entities """ + + def run(self, text): + text = text.replace(util.AMP_SUBSTITUTE, "&") + return text + + +@util.deprecated( + "This class is deprecated and will be removed in the future; " + "use [`UnescapeTreeprocessor`][markdown.treeprocessors.UnescapeTreeprocessor] instead." +) +class UnescapePostprocessor(Postprocessor): + """ Restore escaped chars. """ + + RE = re.compile(r'{}(\d+){}'.format(util.STX, util.ETX)) + + def unescape(self, m): + return chr(int(m.group(1))) + + def run(self, text): + return self.RE.sub(self.unescape, text) diff --git a/plugins/markdown_preview/markdown/preprocessors.py b/plugins/markdown_preview/markdown/preprocessors.py new file mode 100644 index 0000000..0f63cdd --- /dev/null +++ b/plugins/markdown_preview/markdown/preprocessors.py @@ -0,0 +1,91 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +Preprocessors work on source text before it is broken down into its individual parts. +This is an excellent place to clean up bad characters or to extract portions for later +processing that the parser may otherwise choke on. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any +from . import util +from .htmlparser import HTMLExtractor +import re + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + + +def build_preprocessors(md: Markdown, **kwargs: Any) -> util.Registry[Preprocessor]: + """ Build and return the default set of preprocessors used by Markdown. """ + preprocessors = util.Registry() + preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30) + preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20) + return preprocessors + + +class Preprocessor(util.Processor): + """ + Preprocessors are run after the text is broken into lines. + + Each preprocessor implements a `run` method that takes a pointer to a + list of lines of the document, modifies it as necessary and returns + either the same pointer or a pointer to a new list. + + Preprocessors must extend `Preprocessor`. + + """ + def run(self, lines: list[str]) -> list[str]: + """ + Each subclass of `Preprocessor` should override the `run` method, which + takes the document as a list of strings split by newlines and returns + the (possibly modified) list of lines. + + """ + pass # pragma: no cover + + +class NormalizeWhitespace(Preprocessor): + """ Normalize whitespace for consistent parsing. """ + + def run(self, lines: list[str]) -> list[str]: + source = '\n'.join(lines) + source = source.replace(util.STX, "").replace(util.ETX, "") + source = source.replace("\r\n", "\n").replace("\r", "\n") + "\n\n" + source = source.expandtabs(self.md.tab_length) + source = re.sub(r'(?<=\n) +\n', '\n', source) + return source.split('\n') + + +class HtmlBlockPreprocessor(Preprocessor): + """ + Remove html blocks from the text and store them for later retrieval. + + The raw HTML is stored in the [`htmlStash`][markdown.util.HtmlStash] of the + [`Markdown`][markdown.Markdown] instance. + """ + + def run(self, lines: list[str]) -> list[str]: + source = '\n'.join(lines) + parser = HTMLExtractor(self.md) + parser.feed(source) + parser.close() + return ''.join(parser.cleandoc).split('\n') diff --git a/plugins/markdown_preview/markdown/serializers.py b/plugins/markdown_preview/markdown/serializers.py new file mode 100644 index 0000000..5a8818e --- /dev/null +++ b/plugins/markdown_preview/markdown/serializers.py @@ -0,0 +1,193 @@ +# Add x/html serialization to `Elementree` +# Taken from ElementTree 1.3 preview with slight modifications +# +# Copyright (c) 1999-2007 by Fredrik Lundh. All rights reserved. +# +# fredrik@pythonware.com +# https://www.pythonware.com/ +# +# -------------------------------------------------------------------- +# The ElementTree toolkit is +# +# Copyright (c) 1999-2007 by Fredrik Lundh +# +# By obtaining, using, and/or copying this software and/or its +# associated documentation, you agree that you have read, understood, +# and will comply with the following terms and conditions: +# +# Permission to use, copy, modify, and distribute this software and +# its associated documentation for any purpose and without fee is +# hereby granted, provided that the above copyright notice appears in +# all copies, and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of +# Secret Labs AB or the author not be used in advertising or publicity +# pertaining to distribution of the software without specific, written +# prior permission. +# +# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD +# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT- +# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR +# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# -------------------------------------------------------------------- + +""" +Python-Markdown provides two serializers which render [`ElementTree.Element`][xml.etree.ElementTree.Element] +objects to a string of HTML. Both functions wrap the same underlying code with only a few minor +differences as outlined below: + +1. Empty (self-closing) tags are rendered as `<tag>` for HTML and as `<tag />` for XHTML. +2. Boolean attributes are rendered as `attrname` for HTML and as `attrname="attrname"` for XHTML. +""" + +from __future__ import annotations + +from xml.etree.ElementTree import ProcessingInstruction +from xml.etree.ElementTree import Comment, ElementTree, Element, QName, HTML_EMPTY +import re + +__all__ = ['to_html_string', 'to_xhtml_string'] + +RE_AMP = re.compile(r'&(?!(?:\#[0-9]+|\#x[0-9a-f]+|[0-9a-z]+);)', re.I) + + +def _raise_serialization_error(text): # pragma: no cover + raise TypeError( + "cannot serialize {!r} (type {})".format(text, type(text).__name__) + ) + + +def _escape_cdata(text): + # escape character data + try: + # it's worth avoiding do-nothing calls for strings that are + # shorter than 500 character, or so. assume that's, by far, + # the most common case in most applications. + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _escape_attrib(text): + # escape attribute value + try: + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + if "\n" in text: + text = text.replace("\n", " ") + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _escape_attrib_html(text): + # escape attribute value + try: + if "&" in text: + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + if "\"" in text: + text = text.replace("\"", """) + return text + except (TypeError, AttributeError): # pragma: no cover + _raise_serialization_error(text) + + +def _serialize_html(write, elem, format): + tag = elem.tag + text = elem.text + if tag is Comment: + write("<!--%s-->" % _escape_cdata(text)) + elif tag is ProcessingInstruction: + write("<?%s?>" % _escape_cdata(text)) + elif tag is None: + if text: + write(_escape_cdata(text)) + for e in elem: + _serialize_html(write, e, format) + else: + namespace_uri = None + if isinstance(tag, QName): + # `QNAME` objects store their data as a string: `{uri}tag` + if tag.text[:1] == "{": + namespace_uri, tag = tag.text[1:].split("}", 1) + else: + raise ValueError('QName objects must define a tag.') + write("<" + tag) + items = elem.items() + if items: + items = sorted(items) # lexical order + for k, v in items: + if isinstance(k, QName): + # Assume a text only `QName` + k = k.text + if isinstance(v, QName): + # Assume a text only `QName` + v = v.text + else: + v = _escape_attrib_html(v) + if k == v and format == 'html': + # handle boolean attributes + write(" %s" % v) + else: + write(' {}="{}"'.format(k, v)) + if namespace_uri: + write(' xmlns="%s"' % (_escape_attrib(namespace_uri))) + if format == "xhtml" and tag.lower() in HTML_EMPTY: + write(" />") + else: + write(">") + if text: + if tag.lower() in ["script", "style"]: + write(text) + else: + write(_escape_cdata(text)) + for e in elem: + _serialize_html(write, e, format) + if tag.lower() not in HTML_EMPTY: + write("</" + tag + ">") + if elem.tail: + write(_escape_cdata(elem.tail)) + + +def _write_html(root, format="html"): + assert root is not None + data = [] + write = data.append + _serialize_html(write, root, format) + return "".join(data) + + +# -------------------------------------------------------------------- +# public functions + + +def to_html_string(element: Element) -> str: + """ Serialize element and its children to a string of HTML5. """ + return _write_html(ElementTree(element).getroot(), format="html") + + +def to_xhtml_string(element: Element) -> str: + """ Serialize element and its children to a string of XHTML. """ + return _write_html(ElementTree(element).getroot(), format="xhtml") diff --git a/plugins/markdown_preview/markdown/test_tools.py b/plugins/markdown_preview/markdown/test_tools.py new file mode 100644 index 0000000..895e44e --- /dev/null +++ b/plugins/markdown_preview/markdown/test_tools.py @@ -0,0 +1,224 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" A collection of tools for testing the Markdown code base and extensions. """ + +from __future__ import annotations + +import os +import sys +import unittest +import textwrap +from typing import Any +from . import markdown, Markdown, util + +try: + import tidylib +except ImportError: + tidylib = None + +__all__ = ['TestCase', 'LegacyTestCase', 'Kwargs'] + + +class TestCase(unittest.TestCase): + """ + A [`unittest.TestCase`][] subclass with helpers for testing Markdown output. + + Define `default_kwargs` as a `dict` of keywords to pass to Markdown for each + test. The defaults can be overridden on individual tests. + + The `assertMarkdownRenders` method accepts the source text, the expected + output, and any keywords to pass to Markdown. The `default_kwargs` are used + except where overridden by `kwargs`. The output and expected output are passed + to `TestCase.assertMultiLineEqual`. An `AssertionError` is raised with a diff + if the actual output does not equal the expected output. + + The `dedent` method is available to dedent triple-quoted strings if + necessary. + + In all other respects, behaves as `unittest.TestCase`. + """ + + default_kwargs: dict[str, Any] = {} + """ Default options to pass to Markdown for each test. """ + + def assertMarkdownRenders(self, source, expected, expected_attrs=None, **kwargs): + """ + Test that source Markdown text renders to expected output with given keywords. + + `expected_attrs` accepts a `dict`. Each key should be the name of an attribute + on the `Markdown` instance and the value should be the expected value after + the source text is parsed by Markdown. After the expected output is tested, + the expected value for each attribute is compared against the actual + attribute of the `Markdown` instance using `TestCase.assertEqual`. + """ + + expected_attrs = expected_attrs or {} + kws = self.default_kwargs.copy() + kws.update(kwargs) + md = Markdown(**kws) + output = md.convert(source) + self.assertMultiLineEqual(output, expected) + for key, value in expected_attrs.items(): + self.assertEqual(getattr(md, key), value) + + def dedent(self, text): + """ + Dedent text. + """ + + # TODO: If/when actual output ends with a newline, then use: + # return textwrap.dedent(text.strip('/n')) + return textwrap.dedent(text).strip() + + +class recursionlimit: + """ + A context manager which temporarily modifies the Python recursion limit. + + The testing framework, coverage, etc. may add an arbitrary number of levels to the depth. To maintain consistency + in the tests, the current stack depth is determined when called, then added to the provided limit. + + Example usage: + + ``` python + with recursionlimit(20): + # test code here + ``` + + See <https://stackoverflow.com/a/50120316/866026>. + """ + + def __init__(self, limit): + self.limit = util._get_stack_depth() + limit + self.old_limit = sys.getrecursionlimit() + + def __enter__(self): + sys.setrecursionlimit(self.limit) + + def __exit__(self, type, value, tb): + sys.setrecursionlimit(self.old_limit) + + +######################### +# Legacy Test Framework # +######################### + + +class Kwargs(dict): + """ A `dict` like class for holding keyword arguments. """ + pass + + +def _normalize_whitespace(text): + """ Normalize whitespace for a string of HTML using `tidylib`. """ + output, errors = tidylib.tidy_fragment(text, options={ + 'drop_empty_paras': 0, + 'fix_backslash': 0, + 'fix_bad_comments': 0, + 'fix_uri': 0, + 'join_styles': 0, + 'lower_literals': 0, + 'merge_divs': 0, + 'output_xhtml': 1, + 'quote_ampersand': 0, + 'newline': 'LF' + }) + return output + + +class LegacyTestMeta(type): + def __new__(cls, name, bases, dct): + + def generate_test(infile, outfile, normalize, kwargs): + def test(self): + with open(infile, encoding="utf-8") as f: + input = f.read() + with open(outfile, encoding="utf-8") as f: + # Normalize line endings + # (on Windows, git may have altered line endings). + expected = f.read().replace("\r\n", "\n") + output = markdown(input, **kwargs) + if tidylib and normalize: + try: + expected = _normalize_whitespace(expected) + output = _normalize_whitespace(output) + except OSError: + self.skipTest("Tidylib's c library not available.") + elif normalize: + self.skipTest('Tidylib not available.') + self.assertMultiLineEqual(output, expected) + return test + + location = dct.get('location', '') + exclude = dct.get('exclude', []) + normalize = dct.get('normalize', False) + input_ext = dct.get('input_ext', '.txt') + output_ext = dct.get('output_ext', '.html') + kwargs = dct.get('default_kwargs', Kwargs()) + + if os.path.isdir(location): + for file in os.listdir(location): + infile = os.path.join(location, file) + if os.path.isfile(infile): + tname, ext = os.path.splitext(file) + if ext == input_ext: + outfile = os.path.join(location, tname + output_ext) + tname = tname.replace(' ', '_').replace('-', '_') + kws = kwargs.copy() + if tname in dct: + kws.update(dct[tname]) + test_name = 'test_%s' % tname + if tname not in exclude: + dct[test_name] = generate_test(infile, outfile, normalize, kws) + else: + dct[test_name] = unittest.skip('Excluded')(lambda: None) + + return type.__new__(cls, name, bases, dct) + + +class LegacyTestCase(unittest.TestCase, metaclass=LegacyTestMeta): + """ + A [`unittest.TestCase`][] subclass for running Markdown's legacy file-based tests. + + A subclass should define various properties which point to a directory of + text-based test files and define various behaviors/defaults for those tests. + The following properties are supported: + + Attributes: + location (str): A path to the directory of test files. An absolute path is preferred. + exclude (list[str]): A list of tests to exclude. Each test name should comprise the filename + without an extension. + normalize (bool): A boolean value indicating if the HTML should be normalized. Default: `False`. + input_ext (str): A string containing the file extension of input files. Default: `.txt`. + output_ext (str): A string containing the file extension of expected output files. Default: `html`. + default_kwargs (Kwargs[str, Any]): The default set of keyword arguments for all test files in the directory. + + In addition, properties can be defined for each individual set of test files within + the directory. The property should be given the name of the file without the file + extension. Any spaces and dashes in the filename should be replaced with + underscores. The value of the property should be a `Kwargs` instance which + contains the keyword arguments that should be passed to `Markdown` for that + test file. The keyword arguments will "update" the `default_kwargs`. + + When the class instance is created, it will walk the given directory and create + a separate `Unitttest` for each set of test files using the naming scheme: + `test_filename`. One `Unittest` will be run for each set of input and output files. + """ + pass diff --git a/plugins/markdown_preview/markdown/treeprocessors.py b/plugins/markdown_preview/markdown/treeprocessors.py new file mode 100644 index 0000000..59a3eb3 --- /dev/null +++ b/plugins/markdown_preview/markdown/treeprocessors.py @@ -0,0 +1,476 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +Tree processors manipulate the tree created by block processors. They can even create an entirely +new `ElementTree` object. This is an excellent place for creating summaries, adding collected +references, or last minute adjustments. + +""" + +from __future__ import annotations + +import re +import xml.etree.ElementTree as etree +from typing import TYPE_CHECKING, Any +from . import util +from . import inlinepatterns + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + + +def build_treeprocessors(md: Markdown, **kwargs: Any) -> util.Registry[Treeprocessor]: + """ Build the default `treeprocessors` for Markdown. """ + treeprocessors = util.Registry() + treeprocessors.register(InlineProcessor(md), 'inline', 20) + treeprocessors.register(PrettifyTreeprocessor(md), 'prettify', 10) + treeprocessors.register(UnescapeTreeprocessor(md), 'unescape', 0) + return treeprocessors + + +def isString(s: Any) -> bool: + """ Return `True` if object is a string but not an [`AtomicString`][markdown.util.AtomicString]. """ + if not isinstance(s, util.AtomicString): + return isinstance(s, str) + return False + + +class Treeprocessor(util.Processor): + """ + `Treeprocessor`s are run on the `ElementTree` object before serialization. + + Each `Treeprocessor` implements a `run` method that takes a pointer to an + `Element` and modifies it as necessary. + + `Treeprocessors` must extend `markdown.Treeprocessor`. + + """ + def run(self, root: etree.Element) -> etree.Element | None: + """ + Subclasses of `Treeprocessor` should implement a `run` method, which + takes a root `Element`. This method can return another `Element` + object, and the existing root `Element` will be replaced, or it can + modify the current tree and return `None`. + """ + pass # pragma: no cover + + +class InlineProcessor(Treeprocessor): + """ + A `Treeprocessor` that traverses a tree, applying inline patterns. + """ + + def __init__(self, md): + self.__placeholder_prefix = util.INLINE_PLACEHOLDER_PREFIX + self.__placeholder_suffix = util.ETX + self.__placeholder_length = 4 + len(self.__placeholder_prefix) \ + + len(self.__placeholder_suffix) + self.__placeholder_re = util.INLINE_PLACEHOLDER_RE + self.md = md + self.inlinePatterns = md.inlinePatterns + self.ancestors = [] + + def __makePlaceholder(self, type) -> tuple[str, str]: + """ Generate a placeholder """ + id = "%04d" % len(self.stashed_nodes) + hash = util.INLINE_PLACEHOLDER % id + return hash, id + + def __findPlaceholder(self, data: str, index: int) -> tuple[str | None, int]: + """ + Extract id from data string, start from index. + + Arguments: + data: String. + index: Index, from which we start search. + + Returns: + Placeholder id and string index, after the found placeholder. + + """ + m = self.__placeholder_re.search(data, index) + if m: + return m.group(1), m.end() + else: + return None, index + 1 + + def __stashNode(self, node, type) -> str: + """ Add node to stash. """ + placeholder, id = self.__makePlaceholder(type) + self.stashed_nodes[id] = node + return placeholder + + def __handleInline(self, data: str, patternIndex: int = 0) -> str: + """ + Process string with inline patterns and replace it with placeholders. + + Arguments: + data: A line of Markdown text. + patternIndex: The index of the `inlinePattern` to start with. + + Returns: + String with placeholders. + + """ + if not isinstance(data, util.AtomicString): + startIndex = 0 + count = len(self.inlinePatterns) + while patternIndex < count: + data, matched, startIndex = self.__applyPattern( + self.inlinePatterns[patternIndex], data, patternIndex, startIndex + ) + if not matched: + patternIndex += 1 + return data + + def __processElementText(self, node: etree.Element, subnode: etree.Element, isText: bool = True): + """ + Process placeholders in `Element.text` or `Element.tail` + of Elements popped from `self.stashed_nodes`. + + Arguments: + node: Parent node. + subnode: Processing node. + isText: Boolean variable, True - it's text, False - it's a tail. + + """ + if isText: + text = subnode.text + subnode.text = None + else: + text = subnode.tail + subnode.tail = None + + childResult = self.__processPlaceholders(text, subnode, isText) + + if not isText and node is not subnode: + pos = list(node).index(subnode) + 1 + else: + pos = 0 + + childResult.reverse() + for newChild in childResult: + node.insert(pos, newChild[0]) + + def __processPlaceholders( + self, + data: str, + parent: etree.Element, + isText: bool = True + ) -> list[tuple[etree.Element, Any]]: + """ + Process string with placeholders and generate `ElementTree` tree. + + Arguments: + data: String with placeholders instead of `ElementTree` elements. + parent: Element, which contains processing inline data. + isText: Boolean variable, True - it's text, False - it's a tail. + + Returns: + List with `ElementTree` elements with applied inline patterns. + + """ + def linkText(text): + if text: + if result: + if result[-1][0].tail: + result[-1][0].tail += text + else: + result[-1][0].tail = text + elif not isText: + if parent.tail: + parent.tail += text + else: + parent.tail = text + else: + if parent.text: + parent.text += text + else: + parent.text = text + result = [] + strartIndex = 0 + while data: + index = data.find(self.__placeholder_prefix, strartIndex) + if index != -1: + id, phEndIndex = self.__findPlaceholder(data, index) + + if id in self.stashed_nodes: + node = self.stashed_nodes.get(id) + + if index > 0: + text = data[strartIndex:index] + linkText(text) + + if not isString(node): # it's Element + for child in [node] + list(node): + if child.tail: + if child.tail.strip(): + self.__processElementText( + node, child, False + ) + if child.text: + if child.text.strip(): + self.__processElementText(child, child) + else: # it's just a string + linkText(node) + strartIndex = phEndIndex + continue + + strartIndex = phEndIndex + result.append((node, self.ancestors[:])) + + else: # wrong placeholder + end = index + len(self.__placeholder_prefix) + linkText(data[strartIndex:end]) + strartIndex = end + else: + text = data[strartIndex:] + if isinstance(data, util.AtomicString): + # We don't want to loose the `AtomicString` + text = util.AtomicString(text) + linkText(text) + data = "" + + return result + + def __applyPattern( + self, + pattern: inlinepatterns.Pattern, + data: str, + patternIndex: int, + startIndex: int = 0 + ) -> tuple[str, bool, int]: + """ + Check if the line fits the pattern, create the necessary + elements, add it to `stashed_nodes`. + + Arguments: + data: The text to be processed. + pattern: The pattern to be checked. + patternIndex: Index of current pattern. + startIndex: String index, from which we start searching. + + Returns: + String with placeholders instead of `ElementTree` elements. + + """ + new_style = isinstance(pattern, inlinepatterns.InlineProcessor) + + for exclude in pattern.ANCESTOR_EXCLUDES: + if exclude.lower() in self.ancestors: + return data, False, 0 + + if new_style: + match = None + # Since `handleMatch` may reject our first match, + # we iterate over the buffer looking for matches + # until we can't find any more. + for match in pattern.getCompiledRegExp().finditer(data, startIndex): + node, start, end = pattern.handleMatch(match, data) + if start is None or end is None: + startIndex += match.end(0) + match = None + continue + break + else: # pragma: no cover + match = pattern.getCompiledRegExp().match(data[startIndex:]) + leftData = data[:startIndex] + + if not match: + return data, False, 0 + + if not new_style: # pragma: no cover + node = pattern.handleMatch(match) + start = match.start(0) + end = match.end(0) + + if node is None: + return data, True, end + + if not isString(node): + if not isinstance(node.text, util.AtomicString): + # We need to process current node too + for child in [node] + list(node): + if not isString(node): + if child.text: + self.ancestors.append(child.tag.lower()) + child.text = self.__handleInline( + child.text, patternIndex + 1 + ) + self.ancestors.pop() + if child.tail: + child.tail = self.__handleInline( + child.tail, patternIndex + ) + + placeholder = self.__stashNode(node, pattern.type()) + + if new_style: + return "{}{}{}".format(data[:start], + placeholder, data[end:]), True, 0 + else: # pragma: no cover + return "{}{}{}{}".format(leftData, + match.group(1), + placeholder, match.groups()[-1]), True, 0 + + def __build_ancestors(self, parent, parents): + """Build the ancestor list.""" + ancestors = [] + while parent is not None: + if parent is not None: + ancestors.append(parent.tag.lower()) + parent = self.parent_map.get(parent) + ancestors.reverse() + parents.extend(ancestors) + + def run(self, tree: etree.Element, ancestors: list[str] | None = None) -> etree.Element: + """Apply inline patterns to a parsed Markdown tree. + + Iterate over `Element`, find elements with inline tag, apply inline + patterns and append newly created Elements to tree. To avoid further + processing of string with inline patterns, instead of normal string, + use subclass [`AtomicString`][markdown.util.AtomicString]: + + node.text = markdown.util.AtomicString("This will not be processed.") + + Arguments: + tree: `Element` object, representing Markdown tree. + ancestors: List of parent tag names that precede the tree node (if needed). + + Returns: + An element tree object with applied inline patterns. + + """ + self.stashed_nodes: dict[str, etree.Element] = {} + + # Ensure a valid parent list, but copy passed in lists + # to ensure we don't have the user accidentally change it on us. + tree_parents = [] if ancestors is None else ancestors[:] + + self.parent_map = {c: p for p in tree.iter() for c in p} + stack = [(tree, tree_parents)] + + while stack: + currElement, parents = stack.pop() + + self.ancestors = parents + self.__build_ancestors(currElement, self.ancestors) + + insertQueue = [] + for child in currElement: + if child.text and not isinstance( + child.text, util.AtomicString + ): + self.ancestors.append(child.tag.lower()) + text = child.text + child.text = None + lst = self.__processPlaceholders( + self.__handleInline(text), child + ) + for item in lst: + self.parent_map[item[0]] = child + stack += lst + insertQueue.append((child, lst)) + self.ancestors.pop() + if child.tail: + tail = self.__handleInline(child.tail) + dumby = etree.Element('d') + child.tail = None + tailResult = self.__processPlaceholders(tail, dumby, False) + if dumby.tail: + child.tail = dumby.tail + pos = list(currElement).index(child) + 1 + tailResult.reverse() + for newChild in tailResult: + self.parent_map[newChild[0]] = currElement + currElement.insert(pos, newChild[0]) + if len(child): + self.parent_map[child] = currElement + stack.append((child, self.ancestors[:])) + + for element, lst in insertQueue: + for i, obj in enumerate(lst): + newChild = obj[0] + element.insert(i, newChild) + return tree + + +class PrettifyTreeprocessor(Treeprocessor): + """ Add line breaks to the html document. """ + + def _prettifyETree(self, elem): + """ Recursively add line breaks to `ElementTree` children. """ + + i = "\n" + if self.md.is_block_level(elem.tag) and elem.tag not in ['code', 'pre']: + if (not elem.text or not elem.text.strip()) \ + and len(elem) and self.md.is_block_level(elem[0].tag): + elem.text = i + for e in elem: + if self.md.is_block_level(e.tag): + self._prettifyETree(e) + if not elem.tail or not elem.tail.strip(): + elem.tail = i + + def run(self, root: etree.Element) -> None: + """ Add line breaks to `Element` object and its children. """ + + self._prettifyETree(root) + # Do `<br />`'s separately as they are often in the middle of + # inline content and missed by `_prettifyETree`. + brs = root.iter('br') + for br in brs: + if not br.tail or not br.tail.strip(): + br.tail = '\n' + else: + br.tail = '\n%s' % br.tail + # Clean up extra empty lines at end of code blocks. + pres = root.iter('pre') + for pre in pres: + if len(pre) and pre[0].tag == 'code': + code = pre[0] + # Only prettify code containing text only + if not len(code) and code.text is not None: + code.text = util.AtomicString(code.text.rstrip() + '\n') + + +class UnescapeTreeprocessor(Treeprocessor): + """ Restore escaped chars """ + + RE = re.compile(r'{}(\d+){}'.format(util.STX, util.ETX)) + + def _unescape(self, m): + return chr(int(m.group(1))) + + def unescape(self, text: str) -> str: + return self.RE.sub(self._unescape, text) + + def run(self, root): + """ Loop over all elements and unescape all text. """ + for elem in root.iter(): + # Unescape text content + if elem.text and not elem.tag == 'code': + elem.text = self.unescape(elem.text) + # Unescape tail content + if elem.tail: + elem.tail = self.unescape(elem.tail) + # Unescape attribute values + for key, value in elem.items(): + elem.set(key, self.unescape(value)) diff --git a/plugins/markdown_preview/markdown/util.py b/plugins/markdown_preview/markdown/util.py new file mode 100644 index 0000000..827befd --- /dev/null +++ b/plugins/markdown_preview/markdown/util.py @@ -0,0 +1,399 @@ +# Python Markdown + +# A Python implementation of John Gruber's Markdown. + +# Documentation: https://python-markdown.github.io/ +# GitHub: https://github.com/Python-Markdown/markdown/ +# PyPI: https://pypi.org/project/Markdown/ + +# Started by Manfred Stienstra (http://www.dwerg.net/). +# Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org). +# Currently maintained by Waylan Limberg (https://github.com/waylan), +# Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser). + +# Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later) +# Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b) +# Copyright 2004 Manfred Stienstra (the original version) + +# License: BSD (see LICENSE.md for details). + +""" +This module contains various contacts, classes and functions which get referenced and used +throughout the code base. +""" + +from __future__ import annotations + +import re +import sys +import warnings +from functools import wraps, lru_cache +from itertools import count +from typing import TYPE_CHECKING, Generic, Iterator, NamedTuple, TypeVar, overload + +if TYPE_CHECKING: # pragma: no cover + from markdown import Markdown + +_T = TypeVar('_T') + + +""" +Constants you might want to modify +----------------------------------------------------------------------------- +""" + + +BLOCK_LEVEL_ELEMENTS: list[str] = [ + # Elements which are invalid to wrap in a `<p>` tag. + # See https://w3c.github.io/html/grouping-content.html#the-p-element + 'address', 'article', 'aside', 'blockquote', 'details', 'div', 'dl', + 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', + 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr', 'main', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul', + # Other elements which Markdown should not be mucking up the contents of. + 'canvas', 'colgroup', 'dd', 'body', 'dt', 'group', 'html', 'iframe', 'li', 'legend', + 'math', 'map', 'noscript', 'output', 'object', 'option', 'progress', 'script', + 'style', 'summary', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'tr', 'video' +] +""" +List of HTML tags which get treated as block-level elements. Same as the `block_level_elements` +attribute of the [`Markdown`][markdown.Markdown] class. Generally one should use the +attribute on the class. This remains for compatibility with older extensions. +""" + +# Placeholders +STX = '\u0002' +""" "Start of Text" marker for placeholder templates. """ +ETX = '\u0003' +""" "End of Text" marker for placeholder templates. """ +INLINE_PLACEHOLDER_PREFIX = STX+"klzzwxh:" +""" Prefix for inline placeholder template. """ +INLINE_PLACEHOLDER = INLINE_PLACEHOLDER_PREFIX + "%s" + ETX +""" Placeholder template for stashed inline text. """ +INLINE_PLACEHOLDER_RE = re.compile(INLINE_PLACEHOLDER % r'([0-9]+)') +""" Regular Expression which matches inline placeholders. """ +AMP_SUBSTITUTE = STX+"amp"+ETX +""" Placeholder template for HTML entities. """ +HTML_PLACEHOLDER = STX + "wzxhzdk:%s" + ETX +""" Placeholder template for raw HTML. """ +HTML_PLACEHOLDER_RE = re.compile(HTML_PLACEHOLDER % r'([0-9]+)') +""" Regular expression which matches HTML placeholders. """ +TAG_PLACEHOLDER = STX + "hzzhzkh:%s" + ETX +""" Placeholder template for tags. """ + + +# Constants you probably do not need to change +# ----------------------------------------------------------------------------- + +RTL_BIDI_RANGES = ( + ('\u0590', '\u07FF'), + # Hebrew (0590-05FF), Arabic (0600-06FF), + # Syriac (0700-074F), Arabic supplement (0750-077F), + # Thaana (0780-07BF), Nko (07C0-07FF). + ('\u2D30', '\u2D7F') # Tifinagh +) + + +# AUXILIARY GLOBAL FUNCTIONS +# ============================================================================= + + +@lru_cache(maxsize=None) +def get_installed_extensions(): + """ Return all entry_points in the `markdown.extensions` group. """ + if sys.version_info >= (3, 10): + from importlib import metadata + else: # `<PY310` use backport + import importlib_metadata as metadata + # Only load extension entry_points once. + return metadata.entry_points(group='markdown.extensions') + + +def deprecated(message: str, stacklevel: int = 2): + """ + Raise a [`DeprecationWarning`][] when wrapped function/method is called. + + Usage: + + ```python + @deprecated("This method will be removed in version X; use Y instead.") + def some_method(): + pass + ``` + """ + def wrapper(func): + @wraps(func) + def deprecated_func(*args, **kwargs): + warnings.warn( + f"'{func.__name__}' is deprecated. {message}", + category=DeprecationWarning, + stacklevel=stacklevel + ) + return func(*args, **kwargs) + return deprecated_func + return wrapper + + +def parseBoolValue(value: str | None, fail_on_errors: bool = True, preserve_none: bool = False) -> bool | None: + """Parses a string representing a boolean value. If parsing was successful, + returns `True` or `False`. If `preserve_none=True`, returns `True`, `False`, + or `None`. If parsing was not successful, raises `ValueError`, or, if + `fail_on_errors=False`, returns `None`.""" + if not isinstance(value, str): + if preserve_none and value is None: + return value + return bool(value) + elif preserve_none and value.lower() == 'none': + return None + elif value.lower() in ('true', 'yes', 'y', 'on', '1'): + return True + elif value.lower() in ('false', 'no', 'n', 'off', '0', 'none'): + return False + elif fail_on_errors: + raise ValueError('Cannot parse bool value: %r' % value) + + +def code_escape(text: str) -> str: + """HTML escape a string of code.""" + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + + +def _get_stack_depth(size=2): + """Get current stack depth, performantly. + """ + frame = sys._getframe(size) + + for size in count(size): + frame = frame.f_back + if not frame: + return size + + +def nearing_recursion_limit() -> bool: + """Return true if current stack depth is within 100 of maximum limit.""" + return sys.getrecursionlimit() - _get_stack_depth() < 100 + + +# MISC AUXILIARY CLASSES +# ============================================================================= + + +class AtomicString(str): + """A string which should not be further processed.""" + pass + + +class Processor: + """ The base class for all processors. + + Attributes: + Processor.md: The `Markdown` instance passed in an initialization. + + Arguments: + md: The `Markdown` instance this processor is a part of. + + """ + def __init__(self, md: Markdown | None = None): + self.md = md + + +class HtmlStash: + """ + This class is used for stashing HTML objects that we extract + in the beginning and replace with place-holders. + """ + + def __init__(self): + """ Create an `HtmlStash`. """ + self.html_counter = 0 # for counting inline html segments + self.rawHtmlBlocks = [] + self.tag_counter = 0 + self.tag_data = [] # list of dictionaries in the order tags appear + + def store(self, html: str) -> str: + """ + Saves an HTML segment for later reinsertion. Returns a + placeholder string that needs to be inserted into the + document. + + Keyword arguments: + html: An html segment. + + Returns: + A placeholder string. + + """ + self.rawHtmlBlocks.append(html) + placeholder = self.get_placeholder(self.html_counter) + self.html_counter += 1 + return placeholder + + def reset(self) -> None: + """ Clear the stash. """ + self.html_counter = 0 + self.rawHtmlBlocks = [] + + def get_placeholder(self, key: int) -> str: + return HTML_PLACEHOLDER % key + + def store_tag(self, tag: str, attrs: list, left_index: int, right_index: int) -> str: + """Store tag data and return a placeholder.""" + self.tag_data.append({'tag': tag, 'attrs': attrs, + 'left_index': left_index, + 'right_index': right_index}) + placeholder = TAG_PLACEHOLDER % str(self.tag_counter) + self.tag_counter += 1 # equal to the tag's index in `self.tag_data` + return placeholder + + +# Used internally by `Registry` for each item in its sorted list. +# Provides an easier to read API when editing the code later. +# For example, `item.name` is more clear than `item[0]`. +class _PriorityItem(NamedTuple): + name: str + priority: float + + +class Registry(Generic[_T]): + """ + A priority sorted registry. + + A `Registry` instance provides two public methods to alter the data of the + registry: `register` and `deregister`. Use `register` to add items and + `deregister` to remove items. See each method for specifics. + + When registering an item, a "name" and a "priority" must be provided. All + items are automatically sorted by "priority" from highest to lowest. The + "name" is used to remove ("deregister") and get items. + + A `Registry` instance it like a list (which maintains order) when reading + data. You may iterate over the items, get an item and get a count (length) + of all items. You may also check that the registry contains an item. + + When getting an item you may use either the index of the item or the + string-based "name". For example: + + registry = Registry() + registry.register(SomeItem(), 'itemname', 20) + # Get the item by index + item = registry[0] + # Get the item by name + item = registry['itemname'] + + When checking that the registry contains an item, you may use either the + string-based "name", or a reference to the actual item. For example: + + someitem = SomeItem() + registry.register(someitem, 'itemname', 20) + # Contains the name + assert 'itemname' in registry + # Contains the item instance + assert someitem in registry + + The method `get_index_for_name` is also available to obtain the index of + an item using that item's assigned "name". + """ + + def __init__(self): + self._data: dict[str, _T] = {} + self._priority = [] + self._is_sorted = False + + def __contains__(self, item: str | _T) -> bool: + if isinstance(item, str): + # Check if an item exists by this name. + return item in self._data.keys() + # Check if this instance exists. + return item in self._data.values() + + def __iter__(self) -> Iterator[_T]: + self._sort() + return iter([self._data[k] for k, p in self._priority]) + + @overload + def __getitem__(self, key: str | int) -> _T: # pragma: no cover + ... + + @overload + def __getitem__(self, key: slice) -> Registry[_T]: # pragma: no cover + ... + + def __getitem__(self, key: str | int | slice) -> _T | Registry[_T]: + self._sort() + if isinstance(key, slice): + data: Registry[_T] = Registry() + for k, p in self._priority[key]: + data.register(self._data[k], k, p) + return data + if isinstance(key, int): + return self._data[self._priority[key].name] + return self._data[key] + + def __len__(self) -> int: + return len(self._priority) + + def __repr__(self): + return '<{}({})>'.format(self.__class__.__name__, list(self)) + + def get_index_for_name(self, name: str) -> int: + """ + Return the index of the given name. + """ + if name in self: + self._sort() + return self._priority.index( + [x for x in self._priority if x.name == name][0] + ) + raise ValueError('No item named "{}" exists.'.format(name)) + + def register(self, item: _T, name: str, priority: float) -> None: + """ + Add an item to the registry with the given name and priority. + + Arguments: + item: The item being registered. + name: A string used to reference the item. + priority: An integer or float used to sort against all items. + + If an item is registered with a "name" which already exists, the + existing item is replaced with the new item. Treat carefully as the + old item is lost with no way to recover it. The new item will be + sorted according to its priority and will **not** retain the position + of the old item. + """ + if name in self: + # Remove existing item of same name first + self.deregister(name) + self._is_sorted = False + self._data[name] = item + self._priority.append(_PriorityItem(name, priority)) + + def deregister(self, name: str, strict: bool = True) -> None: + """ + Remove an item from the registry. + + Set `strict=False` to fail silently. Otherwise a [`ValueError`][] is raised for an unknown `name`. + """ + try: + index = self.get_index_for_name(name) + del self._priority[index] + del self._data[name] + except ValueError: + if strict: + raise + + def _sort(self): + """ + Sort the registry by priority from highest to lowest. + + This method is called internally and should never be explicitly called. + """ + if not self._is_sorted: + self._priority.sort(key=lambda item: item.priority, reverse=True) + self._is_sorted = True diff --git a/plugins/markdown_preview/markdown_preview.glade b/plugins/markdown_preview/markdown_preview.glade new file mode 100644 index 0000000..68a45f0 --- /dev/null +++ b/plugins/markdown_preview/markdown_preview.glade @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.40.0 --> +<interface> + <requires lib="gtk+" version="3.24"/> + <requires lib="webkit2gtk" version="2.28"/> + <object class="GtkImage" id="settings_img"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="stock">gtk-justify-fill</property> + </object> + <object class="WebKitSettings" type-func="webkit_settings_get_type" id="web_view_settings"> + <property name="enable-offline-web-application-cache">False</property> + <property name="enable-html5-local-storage">False</property> + <property name="enable-html5-database">False</property> + <property name="enable-xss-auditor">False</property> + <property name="enable-hyperlink-auditing">False</property> + <property name="enable-tabs-to-links">False</property> + <property name="enable-fullscreen">False</property> + <property name="print-backgrounds">False</property> + <property name="enable-webaudio">False</property> + <property name="enable-page-cache">False</property> + <property name="user-agent">Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15</property> + <property name="enable-accelerated-2d-canvas">True</property> + <property name="allow-file-access-from-file-urls">True</property> + <property name="allow-universal-access-from-file-urls">True</property> + <property name="enable-webrtc">True</property> + </object> + <object class="GtkPopover" id="markdown_preview_dialog"> + <property name="width-request">620</property> + <property name="height-request">480</property> + <property name="can-focus">False</property> + <property name="vexpand">True</property> + <property name="position">left</property> + <property name="modal">False</property> + <property name="transitions-enabled">False</property> + <property name="constrain-to">none</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="hexpand">True</property> + <property name="vexpand">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkButtonBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkToggleButton"> + <property name="label">gtk-media-pause</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="use-stock">True</property> + <property name="always-show-image">True</property> + <signal name="toggled" handler="_tggle_preview_updates" swapped="no"/> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <property name="image">settings_img</property> + <signal name="clicked" handler="_handle_settings" swapped="no"/> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="shadow-type">in</property> + <child> + <object class="GtkViewport"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <child> + <object class="WebKitWebView" type-func="webkit_web_view_get_type" id="markdown_view"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="settings">web_view_settings</property> + <property name="is-ephemeral">True</property> + <property name="is-muted">True</property> + <property name="default-content-security-policy">*</property> + <child> + <placeholder/> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> +</interface> diff --git a/plugins/markdown_preview/markdown_template_mixin.py b/plugins/markdown_preview/markdown_template_mixin.py new file mode 100644 index 0000000..710db12 --- /dev/null +++ b/plugins/markdown_preview/markdown_template_mixin.py @@ -0,0 +1,42 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class MarkdownTemplateMixin: + def wrap_html_to_body(self, html): + return f"""\ +<!DOCTYPE html> +<html lang="en" dir="ltr"> +<head> + <meta charset="utf-8"> + <title>Markdown View + + + + {html} + + + +""" \ No newline at end of file diff --git a/plugins/markdown_preview/plugin.py b/plugins/markdown_preview/plugin.py new file mode 100644 index 0000000..b363acb --- /dev/null +++ b/plugins/markdown_preview/plugin.py @@ -0,0 +1,114 @@ +# Python imports +import os + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +gi.require_version('WebKit2', '4.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import WebKit2 + +# Application imports +from . import markdown +from .markdown_template_mixin import MarkdownTemplateMixin +from plugins.plugin_base import PluginBase + + + +class Plugin(MarkdownTemplateMixin, PluginBase): + def __init__(self): + super().__init__() + + self.name = "Markdown Preview" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + self.path = os.path.dirname(os.path.realpath(__file__)) + self._GLADE_FILE = f"{self.path}/markdown_preview.glade" + + self.is_preview_paused = False + self.is_md_file = False + + + def run(self): + WebKit2.WebView() # Need one initialized for webview to work from glade file + + self._builder = Gtk.Builder() + self._builder.add_from_file(self._GLADE_FILE) + self._connect_builder_signals(self, self._builder) + + separator_right = self._ui_objects[0] + self._markdown_dialog = self._builder.get_object("markdown_preview_dialog") + self._markdown_view = self._builder.get_object("markdown_view") + self._web_view_settings = self._builder.get_object("web_view_settings") + + self._markdown_dialog.set_relative_to(separator_right) + self._markdown_view.set_settings(self._web_view_settings) + self._markdown_view.set_background_color(Gdk.RGBA(0, 0, 0, 0.0)) + + + def generate_reference_ui_element(self): + ... + + def subscribe_to_events(self): + self._event_system.subscribe("tggle_markdown_preview", self._tggle_markdown_preview) + self._event_system.subscribe("set_active_src_view", self._set_active_src_view) + self._event_system.subscribe("buffer_changed", self._do_markdown_translate) + + def _buffer_changed_first_load(self, buffer): + self._buffer = buffer + + self._do_markdown_translate(buffer) + + def _set_active_src_view(self, source_view): + self._active_src_view = source_view + self._buffer = self._active_src_view.get_buffer() + + self._do_markdown_translate(self._buffer) + + def _handle_settings(self, widget = None, eve = None): + ... + + def _tggle_preview_updates(self, widget = None, eve = None): + self.is_preview_paused = not self.is_preview_paused + widget.set_active(self.is_preview_paused) + + if not self.is_preview_paused: + self._do_markdown_translate(self._buffer) + + def _tggle_markdown_preview(self, widget = None, eve = None): + if not self._active_src_view: return + + is_visible = self._markdown_dialog.is_visible() + buffer = self._active_src_view.get_buffer() + data = None + + if not is_visible: + self._markdown_dialog.popup(); + self._do_markdown_translate(buffer) + elif not data and is_visible: + self._markdown_dialog.popdown() + + def _do_markdown_translate(self, buffer): + if self.is_preview_paused: return + + self.is_markdown_check() + is_visible = self._markdown_dialog.is_visible() + if not is_visible or not self.is_md_file: return + self.render_markdown(buffer) + + def render_markdown(self, buffer): + start_iter = buffer.get_start_iter() + end_iter = buffer.get_end_iter() + text = buffer.get_text(start_iter, end_iter, include_hidden_chars = False) + html = markdown.markdown(text) + + path = self._active_src_view.get_current_file().get_parent().get_path() + data = self.wrap_html_to_body(html) + self._markdown_view.load_html(content = data, base_uri = f"file://{path}/") + + def is_markdown_check(self): + self.is_md_file = self._active_src_view.get_filetype() == "markdown" + if not self.is_md_file: + data = self.wrap_html_to_body("

Not a Markdown file...

") + self._markdown_view.load_html(content = data, base_uri = None) \ No newline at end of file diff --git a/plugins/search_replace/__init__.py b/plugins/search_replace/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/search_replace/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/search_replace/__main__.py b/plugins/search_replace/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/search_replace/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/search_replace/manifest.json b/plugins/search_replace/manifest.json new file mode 100644 index 0000000..e89dc50 --- /dev/null +++ b/plugins/search_replace/manifest.json @@ -0,0 +1,12 @@ +{ + "name": "Search/Replace", + "author": "ITDominator", + "version": "0.0.1", + "support": "", + "requests": { + "pass_events": true, + "pass_ui_objects": ["separator_botton"], + "bind_keys": ["Search/Replace||tggl_search_replace:f"] + + } +} diff --git a/plugins/search_replace/plugin.py b/plugins/search_replace/plugin.py new file mode 100644 index 0000000..b387f07 --- /dev/null +++ b/plugins/search_replace/plugin.py @@ -0,0 +1,221 @@ +# Python imports +import os +import re +import threading + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib + +# Application imports +from plugins.plugin_base import PluginBase +from .styling_mixin import StylingMixin +from .replace_mixin import ReplaceMixin + + + +class Plugin(StylingMixin, ReplaceMixin, PluginBase): + def __init__(self): + super().__init__() + + self.name = "Search/Replace" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + self.path = os.path.dirname(os.path.realpath(__file__)) + self._GLADE_FILE = f"{self.path}/search_replace.glade" + + self._search_replace_dialog = None + self._find_entry = None + self._replace_entry = None + self._active_src_view = None + self._buffer = None + self._tag_table = None + + self.use_regex = False + self.use_case_sensitive = False + self.search_only_in_selection = False + self.use_whole_word_search = False + + self.timer = None + self.search_time = 0.35 + self.find_text = "" + self.search_tag = "search_tag" + self.highlight_color = "#FBF719" + self.text_color = "#000000" + self.alpha_num_under = re.compile(r"[a-zA-Z0-9_]") + + + def run(self): + self._builder = Gtk.Builder() + self._builder.add_from_file(self._GLADE_FILE) + self._connect_builder_signals(self, self._builder) + + separator_botton = self._ui_objects[0] + self._search_replace_dialog = self._builder.get_object("search_replace_dialog") + self._find_status_lbl = self._builder.get_object("find_status_lbl") + self._find_options_lbl = self._builder.get_object("find_options_lbl") + + self._find_entry = self._builder.get_object("find_entry") + self._replace_entry = self._builder.get_object("replace_entry") + + self._search_replace_dialog.set_relative_to(separator_botton) + self._search_replace_dialog.set_hexpand(True) + + def generate_reference_ui_element(self): + ... + + def subscribe_to_events(self): + self._event_system.subscribe("tggl_search_replace", self._tggl_search_replace) + self._event_system.subscribe("set_active_src_view", self._set_active_src_view) + + def _set_active_src_view(self, source_view): + self._active_src_view = source_view + self._buffer = self._active_src_view.get_buffer() + self._tag_table = self._buffer.get_tag_table() + self.search_for_string(self._find_entry) + + def _show_search_replace(self, widget = None, eve = None): + self._search_replace_dialog.popup() + + def _tggl_search_replace(self, widget = None, eve = None): + is_visible = self._search_replace_dialog.is_visible() + buffer = self._active_src_view.get_buffer() + data = None + + if buffer.get_has_selection(): + start, end = buffer.get_selection_bounds() + data = buffer.get_text(start, end, include_hidden_chars = False) + + if data: + self._find_entry.set_text(data) + + if not is_visible: + self._search_replace_dialog.popup(); + self._find_entry.grab_focus() + elif not data and is_visible: + self._search_replace_dialog.popdown() + self._find_entry.set_text("") + else: + self._find_entry.grab_focus() + + + def get_search_tag(self, buffer): + tag_table = buffer.get_tag_table() + search_tag = tag_table.lookup(self.search_tag) + if not search_tag: + search_tag = buffer.create_tag(self.search_tag, background = self.highlight_color, foreground = self.text_color) + + buffer.remove_tag_by_name(self.search_tag, buffer.get_start_iter(), buffer.get_end_iter()) + return search_tag + + + def cancel_timer(self): + if self.timer: + self.timer.cancel() + GLib.idle_remove_by_data(None) + + def delay_search_glib(self): + GLib.idle_add(self._do_highlight) + + def delay_search(self): + wait_time = self.search_time / len(self.find_text) + wait_time = max(wait_time, 0.05) + + self.timer = threading.Timer(wait_time, self.delay_search_glib) + self.timer.daemon = True + self.timer.start() + + + def on_enter_search(self, widget, eve): + text = widget.get_text() + if not text: return + + keyname = Gdk.keyval_name(eve.keyval) + if keyname == "Return": + self.find_next(widget) + + def search_for_string(self, widget): + self.cancel_timer() + + self.find_text = widget.get_text() + if len(self.find_text) > 0 and len(self.find_text) < 5: + self.delay_search() + else: + self._do_highlight(self.find_text) + + + def _do_highlight(self, query = None): + query = self.find_text if not query else query + buffer = self._active_src_view.get_buffer() + # Also clears tag from buffer so if no query we're clean in ui + search_tag = self.get_search_tag(buffer) + + self.update_style(1) + if not query: + self._find_status_lbl.set_label(f"Find in current buffer") + self.update_style(0) + return + + start_itr = buffer.get_start_iter() + end_itr = buffer.get_end_iter() + + results, total_count = self.search(start_itr, query) + self._update_status_lbl(total_count, query) + for start, end in results: + buffer.apply_tag(search_tag, start, end) + + def search(self, start_itr = None, query = None, limit = None): + if not start_itr or not query: return None, None + + flags = Gtk.TextSearchFlags.VISIBLE_ONLY | Gtk.TextSearchFlags.TEXT_ONLY + if not self.use_case_sensitive: + flags = flags | Gtk.TextSearchFlags.CASE_INSENSITIVE + + if self.search_only_in_selection and self._buffer.get_has_selection(): + start_itr, limit = self._buffer.get_selection_bounds() + + _results = [] + while True: + result = start_itr.forward_search(query, flags, limit) + if not result: break + + _results.append(result) + start_itr = result[1] + + results = self.apply_filters(_results, query) + return results, len(results) + + def apply_filters(self, _results, query): + results = [] + for start, end in _results: + text = self._buffer.get_slice(start, end, include_hidden_chars = False) + if self.use_whole_word_search: + if not self.is_whole_word(start, end): + continue + + results.append([start, end]) + + return results + + def find_next(self, widget, eve = None, use_data = None): + mark = self._buffer.get_insert() + iter = self._buffer.get_iter_at_mark(mark) + iter.forward_line() + + search_tag = self._tag_table.lookup(self.search_tag) + next_tag_found = iter.forward_to_tag_toggle(search_tag) + if not next_tag_found: + self._buffer.place_cursor( self._buffer.get_start_iter() ) + mark = self._buffer.get_insert() + iter = self._buffer.get_iter_at_mark(mark) + iter.forward_to_tag_toggle(search_tag) + + self._buffer.place_cursor(iter) + self._active_src_view.scroll_to_mark( self._buffer.get_insert(), 0.0, True, 0.0, 0.0 ) + + + def find_all(self, widget): + ... \ No newline at end of file diff --git a/plugins/search_replace/replace_mixin.py b/plugins/search_replace/replace_mixin.py new file mode 100644 index 0000000..9d5a2f0 --- /dev/null +++ b/plugins/search_replace/replace_mixin.py @@ -0,0 +1,94 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class ReplaceMixin: + def replace(self, widget): + replace_text = self._replace_entry.get_text() + if self.find_text and replace_text: + self._buffer.begin_user_action() + + iter = self._buffer.get_start_iter() + search_tag = self._tag_table.lookup(self.search_tag) + + iter.forward_to_tag_toggle(search_tag) + self._do_replace(iter, replace_text) + self._active_src_view.scroll_to_iter( iter, 0.0, True, 0.0, 0.0 ) + + self._buffer.end_user_action() + + def replace_all(self, widget): + replace_text = self._replace_entry.get_text() + if self.find_text: + self._buffer.begin_user_action() + + mark = self._buffer.get_insert() + iter = self._buffer.get_start_iter() + search_tag = self._tag_table.lookup(self.search_tag) + + while iter.forward_to_tag_toggle(search_tag): + self._do_replace(iter, replace_text) + iter = self._buffer.get_start_iter() + + self._buffer.end_user_action() + + + def _do_replace(self, iter, text): + start, end = self.get_start_end(iter) + self.replace_in_buffer(start, end, text) + + def replace_in_buffer(self, start, end, text): + pos_mark = self._buffer.create_mark("find-replace", end, True) + self._buffer.delete(start, end) + replace_iter = self._buffer.get_iter_at_mark(pos_mark) + self._buffer.insert(replace_iter, text) + + def get_start_end(self, iter): + start = iter.copy() + end = None + + while True: + iter.forward_char() + tags = iter.get_tags() + valid = False + for tag in tags: + if tag.props.name and self.search_tag in tag.props.name: + valid = True + break + + if valid: + continue + + end = iter.copy() + break + + return start, end + + # NOTE: Below, lovingly taken from Hamad Al Marri's Gamma text editor. + # Link: https://gitlab.com/hamadmarri/gamma-text-editor + def is_whole_word(self, match_start, match_end): + is_prev_a_char = True + is_next_a_char = True + + prev_iter = match_start.copy() + next_iter = match_end.copy() + if not prev_iter.backward_char(): + is_prev_a_char = False + else: + c = prev_iter.get_char() + is_prev_a_char = (c.isalpha() or c.isdigit()) + + if not next_iter: + is_next_a_char = False + else: + c = next_iter.get_char() + is_next_a_char = (c.isalpha() or c.isdigit()) + + is_word = (not is_prev_a_char and not is_next_a_char) + + # Note: Both must be false to be a word... + return is_word diff --git a/plugins/search_replace/search_replace.glade b/plugins/search_replace/search_replace.glade new file mode 100644 index 0000000..ccab6c8 --- /dev/null +++ b/plugins/search_replace/search_replace.glade @@ -0,0 +1,299 @@ + + + + + + True + False + gtk-close + + + True + False + ../../icons/only-in-selection.png + + + True + False + ../../icons/whole-word.png + + + False + False + False + none + + + True + False + vertical + + + True + False + + + True + False + 5 + Find in Current Buffer + 0 + + + True + True + 0 + + + + + True + False + + + True + False + 20 + Finding with Options: Case Insensitive + 0 + + + False + True + 0 + + + + + True + False + start + + + .* + True + False + True + False + True + Use Regex + + + + True + True + 0 + + + + + Aa + True + True + False + True + Match Case + + + + True + True + 1 + + + + + True + True + False + True + Only In Selection + only-in-selection + True + + + + True + True + 2 + + + + + True + True + False + True + Whole Word + whole-word + True + + + + True + True + 3 + + + + + True + True + False + True + Close Panel + close_img + True + + + + True + True + 4 + + + + + False + True + 1 + + + + + False + True + 1 + + + + + False + True + 0 + + + + + + True + False + True + + + Replace All + True + True + False + True + Replace All + 5 + 5 + 5 + 5 + + + + 9 + 1 + + + + + Replace + True + True + False + True + Replace Next + 5 + 10 + 5 + 5 + + + + 8 + 1 + + + + + Find All + True + True + False + True + 5 + 5 + 5 + 5 + + + + 9 + 0 + + + + + Find + True + True + False + True + 5 + 5 + 5 + 5 + + + + 8 + 0 + + + + + True + True + edit-find-symbolic + False + False + Find in current buffer + + + + + 0 + 0 + 8 + + + + + True + True + edit-find-symbolic + False + False + Replace in current buffer + + + 0 + 1 + 8 + + + + + False + True + 10 + 3 + + + + + + diff --git a/plugins/search_replace/styling_mixin.py b/plugins/search_replace/styling_mixin.py new file mode 100644 index 0000000..3336bec --- /dev/null +++ b/plugins/search_replace/styling_mixin.py @@ -0,0 +1,66 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class StylingMixin: + def tggle_regex(self, widget): + self.use_regex = not widget.get_active() + self._set_find_options_lbl() + self.search_for_string(self._find_entry) + + def tggle_case_sensitive(self, widget): + self.use_case_sensitive = widget.get_active() + self._set_find_options_lbl() + self.search_for_string(self._find_entry) + + def tggle_selection_only_scan(self, widget): + self.search_only_in_selection = widget.get_active() + self._set_find_options_lbl() + self.search_for_string(self._find_entry) + + def tggle_whole_word_search(self, widget): + self.use_whole_word_search = widget.get_active() + self._set_find_options_lbl() + self.search_for_string(self._find_entry) + + def _set_find_options_lbl(self): + find_options = "Finding with Options: " + + if self.use_regex: + find_options += "Regex" + + find_options += ", " if self.use_regex else "" + find_options += "Case Sensitive" if self.use_case_sensitive else "Case Inensitive" + + if self.search_only_in_selection: + find_options += ", Within Current Selection" + + if self.use_whole_word_search: + find_options += ", Whole Word" + + self._find_options_lbl.set_label(find_options) + + def update_style(self, state): + self._find_entry.get_style_context().remove_class("searching") + self._find_entry.get_style_context().remove_class("search_success") + self._find_entry.get_style_context().remove_class("search_fail") + + if state == 0: + self._find_entry.get_style_context().add_class("searching") + elif state == 1: + self._find_entry.get_style_context().add_class("search_success") + elif state == 2: + self._find_entry.get_style_context().add_class("search_fail") + + def _update_status_lbl(self, total_count: int = 0, query: str = None): + if not query: return + + count = total_count if total_count > 0 else "No" + plural = "s" if total_count > 1 else "" + + if total_count == 0: self.update_style(2) + self._find_status_lbl.set_label(f"{count} result{plural} found for '{query}'") diff --git a/plugins/template/__init__.py b/plugins/template/__init__.py new file mode 100644 index 0000000..d36fa8c --- /dev/null +++ b/plugins/template/__init__.py @@ -0,0 +1,3 @@ +""" + Pligin Module +""" diff --git a/plugins/template/__main__.py b/plugins/template/__main__.py new file mode 100644 index 0000000..a576329 --- /dev/null +++ b/plugins/template/__main__.py @@ -0,0 +1,3 @@ +""" + Pligin Package +""" diff --git a/plugins/template/manifest.json b/plugins/template/manifest.json new file mode 100644 index 0000000..5e128e9 --- /dev/null +++ b/plugins/template/manifest.json @@ -0,0 +1,11 @@ +{ + "name": "Example Plugin", + "author": "John Doe", + "version": "0.0.1", + "support": "", + "requests": { + "ui_target": "plugin_control_list", + "pass_events": true, + "bind_keys": ["Example Plugin||send_message:f"] + } +} diff --git a/plugins/template/plugin.py b/plugins/template/plugin.py new file mode 100644 index 0000000..c52c0ff --- /dev/null +++ b/plugins/template/plugin.py @@ -0,0 +1,51 @@ +# Python imports +import os +import threading +import subprocess +import time + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from plugins.plugin_base import PluginBase + + + + +# NOTE: Threads WILL NOT die with parent's destruction. +def threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() + return wrapper + +# NOTE: Threads WILL die with parent's destruction. +def daemon_threaded(fn): + def wrapper(*args, **kwargs): + threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() + return wrapper + + + + +class Plugin(PluginBase): + def __init__(self): + super().__init__() + + self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + + + def generate_reference_ui_element(self): + button = Gtk.Button(label=self.name) + button.connect("button-release-event", self.send_message) + return button + + def run(self): + ... + + def send_message(self, widget=None, eve=None): + message = "Hello, World!" + event_system.emit("display_message", ("warning", message, None)) diff --git a/pyrightconfig.json b/pyrightconfig.json new file mode 100644 index 0000000..4d8b8ec --- /dev/null +++ b/pyrightconfig.json @@ -0,0 +1,13 @@ +{ + "reportUndefinedVariable": false, + "reportUnusedVariable": false, + "reportUnusedImport": true, + "reportDuplicateImport": true, + "executionEnvironments": [ + { + "root": "./src/versions/solarfm-0.0.1/solarfm" + } + ], + "venvPath": ".", + "venv": ".venv" +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c055f2b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +PyGObject==3.40.1 +pygobject-stubs --no-cache-dir --config-settings=config=Gtk3,Gdk3,Soup2 +setproctitle==1.2.2 +pyxdg==0.27 +psutil==5.8.0 +pycryptodome==3.20.0 +sqlmodel==0.0.19 diff --git a/src/__builtins__.py b/src/__builtins__.py new file mode 100644 index 0000000..7f5491d --- /dev/null +++ b/src/__builtins__.py @@ -0,0 +1,79 @@ +# Python imports +import builtins +import traceback +import threading +import sys + +# Lib imports + +# Application imports +# from libs.db import DB +from libs.event_system import EventSystem +from libs.endpoint_registry import EndpointRegistry +from libs.keybindings import Keybindings +from libs.logger import Logger +from libs.settings.manager import SettingsManager + + + +# NOTE: Threads WILL NOT die with parent's destruction. +def threaded_wrapper(fn): + def wrapper(*args, **kwargs): + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = False) + thread.start() + return thread + return wrapper + +# NOTE: Threads WILL die with parent's destruction. +def daemon_threaded_wrapper(fn): + def wrapper(*args, **kwargs): + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = True) + thread.start() + return thread + return wrapper + +def call_chain_wrapper(fn): + def wrapper(*args, **kwargs): + print() + print() + for line in traceback.format_stack(): + print( line.strip() ) + print() + print() + + return fn(*args, **kwargs) + return wrapper + + +# NOTE: Just reminding myself we can add to builtins two different ways... +# __builtins__.update({"event_system": Builtins()}) +builtins.APP_NAME = "Newton" + +builtins.keybindings = Keybindings() +builtins.event_system = EventSystem() +builtins.endpoint_registry = EndpointRegistry() +builtins.settings_manager = SettingsManager() +# builtins.db = DB() + +settings_manager.load_settings() + +builtins.logger = Logger( + settings_manager.path_manager.get_home_config_path(), \ + _ch_log_lvl = settings_manager.settings.debugging.ch_log_lvl, \ + _fh_log_lvl = settings_manager.settings.debugging.fh_log_lvl + ).get_logger() + +builtins.threaded = threaded_wrapper +builtins.daemon_threaded = daemon_threaded_wrapper +builtins.call_chain = call_chain_wrapper + + + +# def custom_except_hook(exc_type, exc_value, exc_traceback): +# if issubclass(exc_type, KeyboardInterrupt): +# sys.__excepthook__(exc_type, exc_value, exc_traceback) +# return + +# logger.error("Uncaught exception", exc_info = (exc_type, exc_value, exc_traceback)) + +# sys.excepthook = custom_except_hook diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..6de34b8 --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,3 @@ +""" + Src Package. +""" \ No newline at end of file diff --git a/src/__main__.py b/src/__main__.py new file mode 100644 index 0000000..b30240b --- /dev/null +++ b/src/__main__.py @@ -0,0 +1,58 @@ +#!/usr/bin/python3 + +# Python imports +import argparse +import faulthandler +import traceback +from setproctitle import setproctitle + +import tracemalloc +tracemalloc.start() + +# Lib imports + +# Application imports +from __builtins__ import * +from app import Application + + + +def main(): + setproctitle(f'{APP_NAME}') + settings_manager.set_start_load_time() + + if args.debug == "true": + settings_manager.set_debug(True) + + if args.trace_debug == "true": + settings_manager.set_trace_debug(True) + + settings_manager.do_dirty_start_check() + + app = Application() + app.run() + + + +if __name__ == "__main__": + ''' Set process title, get arguments, and create GTK main thread. ''' + + parser = argparse.ArgumentParser() + # Add long and short arguments + parser.add_argument("--debug", "-d", default = "false", help = "Do extra console messaging.") + parser.add_argument("--trace-debug", "-td", default = "false", help = "Disable saves, ignore IPC lock, do extra console messaging.") + parser.add_argument("--no-plugins", "-np", default = "false", help = "Do not load plugins.") + + parser.add_argument("--new-tab", "-nt", default = "false", help = "Opens a 'New Tab' if a handler is set for it.") + parser.add_argument("--file", "-f", default = "default", help = "JUST SOME FILE ARG.") + + # Read arguments (If any...) + args, unknownargs = parser.parse_known_args() + settings_manager.set_starting_args( args, unknownargs ) + + try: + faulthandler.enable() # For better debug info + main() + except Exception as e: + traceback.print_exc() + quit() \ No newline at end of file diff --git a/src/app.py b/src/app.py new file mode 100644 index 0000000..94a0bf3 --- /dev/null +++ b/src/app.py @@ -0,0 +1,72 @@ +# Python imports +from contextlib import suppress +import signal +import os + +# Lib imports + +# Application imports +from libs.debugging import debug_signal_handler +from libs.ipc_server import IPCServer +from core.window import Window + + + +class AppLaunchException(Exception): + ... + + + +class Application: + """ docstring for Application. """ + + def __init__(self): + super(Application, self).__init__() + + self.setup_debug_hook() + + + def run(self): + if not settings_manager.is_trace_debug(): + if not self.load_ipc(): + return + + win = Window() + win.start() + + def load_ipc(self): + args, \ + unknownargs = settings_manager.get_starting_args() + ipc_server = IPCServer() + + self.ipc_realization_check(ipc_server) + if ipc_server.is_ipc_alive: + return True + + logger.warning(f"{app_name} IPC Server Exists: Have sent path(s) to it and closing...") + for arg in unknownargs + [args.new_tab,]: + if os.path.isfile(arg): + message = f"FILE|{arg}" + ipc_server.send_ipc_message(message) + + if os.path.isdir(arg): + message = f"DIR|{arg}" + ipc_server.send_ipc_message(message) + + return False + + def ipc_realization_check(self, ipc_server): + try: + ipc_server.create_ipc_listener() + except Exception: + ipc_server.send_test_ipc_message() + + def setup_debug_hook(self): + # Typically: ValueError: signal only works in main thread + with suppress(ValueError): + # kill -SIGUSR2 from Linux/Unix or SIGBREAK signal from Windows + signal.signal( + vars(signal).get("SIGBREAK") or vars(signal).get("SIGUSR2"), + debug_signal_handler + ) + diff --git a/src/core/__init__.py b/src/core/__init__.py new file mode 100644 index 0000000..6c4fff7 --- /dev/null +++ b/src/core/__init__.py @@ -0,0 +1,3 @@ +""" + Core Package +""" \ No newline at end of file diff --git a/src/core/builder_wrapper.py b/src/core/builder_wrapper.py new file mode 100644 index 0000000..9245da9 --- /dev/null +++ b/src/core/builder_wrapper.py @@ -0,0 +1,33 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class BuilderWrapper(Gtk.Builder): + """docstring for BuilderWrapper.""" + + def __init__(self): + super(BuilderWrapper, self).__init__() + + self.objects = {} + + def get_object(self, id: str, use_gtk: bool = True) -> any: + if not use_gtk: + return self.objects[id] + + return super(BuilderWrapper, self).get_object(id) + + def expose_object(self, id: str, object: any, use_gtk: bool = True) -> None: + if not use_gtk: + self.objects[id] = object + else: + super(BuilderWrapper, self).expose_object(id, object) + + def dereference_object(self, id: str) -> None: + del self.objects[id] diff --git a/src/core/containers/base_container.py b/src/core/containers/base_container.py new file mode 100644 index 0000000..c383216 --- /dev/null +++ b/src/core/containers/base_container.py @@ -0,0 +1,49 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from .header_container import HeaderContainer +from .body_container import BodyContainer +from .footer_container import FooterContainer + + + +class BaseContainer(Gtk.Box): + def __init__(self): + super(BaseContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("base-container") + + self.set_orientation(Gtk.Orientation.VERTICAL) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe("update-transparency", self._update_transparency) + event_system.subscribe("remove-transparency", self._remove_transparency) + + def _load_widgets(self): + self.add( HeaderContainer() ) + self.add( BodyContainer() ) + self.add( FooterContainer() ) + + def _update_transparency(self): + self.ctx.add_class(f"mw_transparency_{settings_manager.settings.theming.transparency}") + + def _remove_transparency(self): + self.ctx.remove_class(f"mw_transparency_{settings_manager.settings.theming.transparency}") diff --git a/src/core/containers/body_container.py b/src/core/containers/body_container.py new file mode 100644 index 0000000..2d1fbff --- /dev/null +++ b/src/core/containers/body_container.py @@ -0,0 +1,42 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from .left_container import LeftContainer +from .center_container import CenterContainer +from .right_container import RightContainer + + + +class BodyContainer(Gtk.Box): + def __init__(self): + super(BodyContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("body-container") + + self.set_orientation(Gtk.Orientation.HORIZONTAL) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self.add( LeftContainer() ) + self.add( CenterContainer() ) + self.add( RightContainer() ) \ No newline at end of file diff --git a/src/core/containers/center_container.py b/src/core/containers/center_container.py new file mode 100644 index 0000000..37cc58b --- /dev/null +++ b/src/core/containers/center_container.py @@ -0,0 +1,48 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ..widgets.code.general_info_widget import GeneralInfoWidget +from .code.code_container import CodeContainer +from ..widgets.save_file_dialog import SaveFileDialog +from ..widgets.controls.open_files_button import OpenFilesButton + + + +class CenterContainer(Gtk.Box): + def __init__(self): + super(CenterContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("center-container") + + self.set_orientation(Gtk.Orientation.VERTICAL) + self.set_hexpand(True) + self.set_vexpand(True) + + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + SaveFileDialog() + OpenFilesButton() + + self.add( GeneralInfoWidget() ) + self.add( CodeContainer() ) diff --git a/src/core/containers/code/__init__.py b/src/core/containers/code/__init__.py new file mode 100644 index 0000000..c59e952 --- /dev/null +++ b/src/core/containers/code/__init__.py @@ -0,0 +1,3 @@ +""" + Containers Package +""" \ No newline at end of file diff --git a/src/core/containers/code/code_container.py b/src/core/containers/code/code_container.py new file mode 100644 index 0000000..16771c8 --- /dev/null +++ b/src/core/containers/code/code_container.py @@ -0,0 +1,38 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ...widgets.code.tabs_widget import TabsWidget + +from .editors_container import EditorsContainer + + + +class CodeContainer(Gtk.Box): + def __init__(self): + super(CodeContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_orientation(Gtk.Orientation.VERTICAL) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self.add( TabsWidget() ) + self.add( EditorsContainer() ) diff --git a/src/core/containers/code/editors_container.py b/src/core/containers/code/editors_container.py new file mode 100644 index 0000000..55fe8f3 --- /dev/null +++ b/src/core/containers/code/editors_container.py @@ -0,0 +1,38 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ...widgets.separator_widget import Separator +from ...widgets.code.miniview_widget import MiniViewWidget +from .paned_editors_container import PanedEditorsContainer + + + +class EditorsContainer(Gtk.Box): + def __init__(self): + super(EditorsContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + ... + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self.add( Separator("separator_left") ) + self.add( PanedEditorsContainer() ) + self.add( Separator("separator_right") ) + self.add( MiniViewWidget() ) \ No newline at end of file diff --git a/src/core/containers/code/paned_editors_container.py b/src/core/containers/code/paned_editors_container.py new file mode 100644 index 0000000..0ae64bb --- /dev/null +++ b/src/core/containers/code/paned_editors_container.py @@ -0,0 +1,69 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import GLib + +# Application imports +from ...widgets.code.view import SourceView + + + +class PanedEditorsContainer(Gtk.Paned): + def __init__(self): + super(PanedEditorsContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("paned-editors-container") + + self.set_hexpand(True) + self.set_vexpand(True) + # self.set_homogeneous(True) + self.set_wide_handle(True) + + def _setup_signals(self): + self.map_id = self.connect("map", self._init_map) + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + scrolled_win1 = Gtk.ScrolledWindow() + scrolled_win2 = Gtk.ScrolledWindow() + source_view1 = SourceView() + source_view2 = SourceView() + + source_view1.sibling_right = source_view2 + source_view2.sibling_left = source_view1 + + scrolled_win1.add( source_view1 ) + scrolled_win2.add( source_view2 ) + + self.add1(scrolled_win1) + self.add2(scrolled_win2) + + def _init_map(self, view): + def _first_show_init(): + self.disconnect(self.map_id) + del self.map_id + + self._handle_first_show() + + return False + + GLib.timeout_add(250, _first_show_init) + + def _handle_first_show(self): + self.set_position( + self.get_allocated_width() / 2 + ) + diff --git a/src/core/containers/footer_container.py b/src/core/containers/footer_container.py new file mode 100644 index 0000000..8efadc2 --- /dev/null +++ b/src/core/containers/footer_container.py @@ -0,0 +1,43 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ..widgets.vte_widget import VteWidget + + + +class FooterContainer(Gtk.Box): + def __init__(self): + super(FooterContainer, self).__init__() + + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("footer-container") + + self.set_orientation(Gtk.Orientation.HORIZONTAL) + self.set_hexpand(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + vte_widget = VteWidget() + + vte_widget.hide() + self.add( vte_widget ) diff --git a/src/core/containers/header_container.py b/src/core/containers/header_container.py new file mode 100644 index 0000000..7f3b56d --- /dev/null +++ b/src/core/containers/header_container.py @@ -0,0 +1,40 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ..widgets.controls.transparency_scale import TransparencyScale + + + +class HeaderContainer(Gtk.Box): + def __init__(self): + super(HeaderContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("header-container") + + self.set_orientation(Gtk.Orientation.VERTICAL) + self.set_hexpand(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe("tggl-top-main-menubar", self.tggl_top_main_menubar) + + def _load_widgets(self): + self.add( TransparencyScale() ) + + def tggl_top_main_menubar(self): + self.hide() if self.is_visible() else self.show_all() \ No newline at end of file diff --git a/src/core/containers/left_container.py b/src/core/containers/left_container.py new file mode 100644 index 0000000..7e1c73f --- /dev/null +++ b/src/core/containers/left_container.py @@ -0,0 +1,39 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from ..widgets.code.miniview_widget import MiniViewWidget + + + +class LeftContainer(Gtk.Box): + def __init__(self): + super(LeftContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("left-container") + + self.set_orientation(Gtk.Orientation.VERTICAL) + self.set_vexpand(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + ... diff --git a/src/core/containers/right_container.py b/src/core/containers/right_container.py new file mode 100644 index 0000000..deff136 --- /dev/null +++ b/src/core/containers/right_container.py @@ -0,0 +1,38 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class RightContainer(Gtk.Box): + def __init__(self): + super(RightContainer, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + self.ctx = self.get_style_context() + self.ctx.add_class("right-container") + + self.set_orientation(Gtk.Orientation.VERTICAL) + self.set_vexpand(True) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + ... diff --git a/src/core/controllers/__init__.py b/src/core/controllers/__init__.py new file mode 100644 index 0000000..0f53a83 --- /dev/null +++ b/src/core/controllers/__init__.py @@ -0,0 +1,3 @@ +""" + Controllers Package +""" \ No newline at end of file diff --git a/src/core/controllers/base_controller.py b/src/core/controllers/base_controller.py new file mode 100644 index 0000000..977edcc --- /dev/null +++ b/src/core/controllers/base_controller.py @@ -0,0 +1,71 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from libs.mixins.ipc_signals_mixin import IPCSignalsMixin +from libs.mixins.keyboard_signals_mixin import KeyboardSignalsMixin + +from ..containers.base_container import BaseContainer + +from .base_controller_data import BaseControllerData +from .bridge_controller import BridgeController + + + +class BaseController(IPCSignalsMixin, KeyboardSignalsMixin, BaseControllerData): + """ docstring for BaseController. """ + + def __init__(self): + + self._setup_controller_data() + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_controllers() + self._load_plugins_and_files() + + logger.info(f"Made it past {self.__class__} loading...") + settings_manager.set_end_load_time() + settings_manager.log_load_time() + + + def _setup_styling(self): + ... + + def _setup_signals(self): + # self.window.connect("focus-out-event", self.unset_keys_and_data) + # self.window.connect("key-press-event", self.on_global_key_press_controller) + # self.window.connect("key-release-event", self.on_global_key_release_controller) + ... + + def _subscribe_to_events(self): + event_system.subscribe("shutting-down", lambda: print("Shutting down...")) + event_system.subscribe("handle-file-from-ipc", self.handle_file_from_ipc) + event_system.subscribe("handle-dir-from-ipc", self.handle_dir_from_ipc) + event_system.subscribe("tggl-top-main-menubar", self._tggl_top_main_menubar) + + def _load_controllers(self): + BridgeController() + + def _load_plugins_and_files(self): + args, unknownargs = settings_manager.get_starting_args() + + if args.no_plugins == "false": + self.plugins_controller.pre_launch_plugins() + self.plugins_controller.post_launch_plugins() + + def _tggl_top_main_menubar(self): + logger.debug("_tggl_top_main_menubar > stub...") + + def _load_glade_file(self): + self.builder.add_from_file( settings_manager.path_manager.get_glade_file() ) + self.builder.expose_object("main_window", self.window) + + settings_manager.set_builder(self.builder) + self.base_container = BaseContainer() + + settings_manager.register_signals_to_builder([self, self.base_container]) \ No newline at end of file diff --git a/src/core/controllers/base_controller_data.py b/src/core/controllers/base_controller_data.py new file mode 100644 index 0000000..8b85498 --- /dev/null +++ b/src/core/controllers/base_controller_data.py @@ -0,0 +1,107 @@ +# Python imports +import os +import subprocess +from shutil import which + +# Lib imports + +# Application imports +from plugins.plugins_controller import PluginsController +from ..builder_wrapper import BuilderWrapper + + + +class BaseControllerData: + ''' BaseControllerData contains most of the state of the app at ay given time. It also has some support methods. ''' + + def _setup_controller_data(self) -> None: + self.window = settings_manager.get_main_window() + self.builder = BuilderWrapper() + self.plugins_controller = PluginsController() + + self.base_container = None + self.was_midified_key = False + self.ctrl_down = False + self.shift_down = False + self.alt_down = False + + self._collect_files_dirs() + self._load_glade_file() + + + def _collect_files_dirs(self): + args, \ + unknownargs = settings_manager.get_starting_args() + files = [] + + for arg in unknownargs + [args.new_tab,]: + if os.path.isdir( arg.replace("file://", "") ): + files.append( f"DIR|{arg.replace('file://', '')}" ) + continue + + # NOTE: If passing line number with file split against : + if os.path.isfile( arg.replace("file://", "").split(":")[0] ): + files.append( f"FILE|{arg.replace('file://', '')}" ) + continue + + logger.info(f"Not a File: {arg}") + + if len(files) == 0: return + + settings_manager.set_is_starting_with_file(True) + settings_manager.set_starting_files(files) + + def get_base_container(self): + return self.base_container + + def clear_console(self) -> None: + ''' Clears the terminal screen. ''' + os.system('cls' if os.name == 'nt' else 'clear') + + def call_method(self, _method_name: str, data: type) -> type: + ''' + Calls a method from scope of class. + + Parameters: + a (obj): self + b (str): method name to be called + c (*): Data (if any) to be passed to the method. + Note: It must be structured according to the given methods requirements. + + Returns: + Return data is that which the calling method gives. + ''' + method_name = str(_method_name) + method = getattr(self, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}") + return method(*data) if data else method() + + def has_method(self, obj: type, method: type) -> type: + ''' Checks if a given method exists. ''' + return callable(getattr(obj, method, None)) + + def clear_children(self, widget: type) -> None: + ''' Clear children of a gtk widget. ''' + for child in widget.get_children(): + widget.remove(child) + + def get_clipboard_data(self, encoding = "utf-8") -> str: + if not which("xclip"): + logger.info('xclip not found...') + return + + command = ['xclip','-selection','clipboard'] + proc = subprocess.Popen(['xclip','-selection', 'clipboard', '-o'], stdout = subprocess.PIPE) + retcode = proc.wait() + data = proc.stdout.read() + return data.decode(encoding).strip() + + def set_clipboard_data(self, data: type, encoding = "utf-8") -> None: + if not which("xclip"): + logger.info('xclip not found...') + return + + command = ['xclip','-selection','clipboard'] + proc = subprocess.Popen(command, stdin = subprocess.PIPE) + proc.stdin.write(data.encode(encoding)) + proc.stdin.close() + retcode = proc.wait() diff --git a/src/core/controllers/bridge_controller.py b/src/core/controllers/bridge_controller.py new file mode 100644 index 0000000..bc2c542 --- /dev/null +++ b/src/core/controllers/bridge_controller.py @@ -0,0 +1,41 @@ +# Python imports +import base64 + +# Lib imports + +# Application imports + + + +class BridgeController: + def __init__(self): + + self._setup_signals() + self._subscribe_to_events() + + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe("handle-bridge-event", self.handle_bridge_event) + + + def handle_bridge_event(self, event): + match event.topic: + case "save": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "close": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "load_buffer": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "load_file": + event_system.emit(f"handle-file-event-{event.originator}", (event,)) + case "alert": + content = base64.b64decode( event.content.encode() ).decode("utf-8") + logger.info(f"\nMessage Topic: {event.topic}\nMessage Content: {content}") + case "error": + content = base64.b64decode( event.content.encode() ).decode("utf-8") + logger.info(content) + case _: + ... \ No newline at end of file diff --git a/src/core/widgets/__init__.py b/src/core/widgets/__init__.py new file mode 100644 index 0000000..a379fc5 --- /dev/null +++ b/src/core/widgets/__init__.py @@ -0,0 +1,3 @@ +""" + Widgets Package +""" \ No newline at end of file diff --git a/src/core/widgets/code/__init__.py b/src/core/widgets/code/__init__.py new file mode 100644 index 0000000..24809ae --- /dev/null +++ b/src/core/widgets/code/__init__.py @@ -0,0 +1,3 @@ +""" + Code Package +""" \ No newline at end of file diff --git a/src/core/widgets/code/command_system.py b/src/core/widgets/code/command_system.py new file mode 100644 index 0000000..3f234c9 --- /dev/null +++ b/src/core/widgets/code/command_system.py @@ -0,0 +1,34 @@ +# Python imports + +# Lib imports + +# Application imports +from . import commands + + + +class CommandSystem: + def __init__(self): + super(CommandSystem, self).__init__() + + self.data: list = () + + + def set_data(self, *args, **kwargs): + self.data = (args, kwargs) + + def exec(self, command: str) -> any: + if not hasattr(commands, command): return + method = getattr(commands, command) + + args, kwargs = self.data + if kwargs: + return method.execute(*args, kwargs) + else: + return method.execute(*args) + + def exec_with_args(self, command: str, args: list) -> any: + if not hasattr(commands, command): return + + method = getattr(commands, command) + return method.execute(*args) diff --git a/src/core/widgets/code/commands/__init__.py b/src/core/widgets/code/commands/__init__.py new file mode 100644 index 0000000..c646d94 --- /dev/null +++ b/src/core/widgets/code/commands/__init__.py @@ -0,0 +1,16 @@ +""" + Commands Package +""" + +import pkgutil +import importlib + +__all__ = [] + +for loader, module_name, is_pkg in pkgutil.walk_packages(__path__): + module = importlib.import_module(f"{__name__}.{module_name}") + globals()[module_name] = module # Add module to package namespace + __all__.append(module_name) + +del pkgutil +del importlib diff --git a/src/core/widgets/code/commands/buffer_redo.py b/src/core/widgets/code/commands/buffer_redo.py new file mode 100644 index 0000000..b0c738f --- /dev/null +++ b/src/core/widgets/code/commands/buffer_redo.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Buffer Redo Command") + + buffer = view.get_buffer() + undo_manager = buffer.get_undo_manager() + + if undo_manager.can_redo(): + buffer.redo() diff --git a/src/core/widgets/code/commands/buffer_undo.py b/src/core/widgets/code/commands/buffer_undo.py new file mode 100644 index 0000000..87688e2 --- /dev/null +++ b/src/core/widgets/code/commands/buffer_undo.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Buffer Undo Command") + + buffer = view.get_buffer() + undo_manager = buffer.get_undo_manager() + + if undo_manager.can_undo(): + buffer.undo() diff --git a/src/core/widgets/code/commands/close_file.py b/src/core/widgets/code/commands/close_file.py new file mode 100644 index 0000000..5af1140 --- /dev/null +++ b/src/core/widgets/code/commands/close_file.py @@ -0,0 +1,26 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Close File Command") + buffer = view.get_buffer() + + next_file = view.files_manager.remove_file(buffer) + if not next_file: + view.command.exec("new_file") + else: + view.set_buffer(next_file.buffer) + + view.command.exec("update_info_bar") diff --git a/src/core/widgets/code/commands/cut_to_temp_buffer.py b/src/core/widgets/code/commands/cut_to_temp_buffer.py new file mode 100644 index 0000000..572e190 --- /dev/null +++ b/src/core/widgets/code/commands/cut_to_temp_buffer.py @@ -0,0 +1,36 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Cut to Temp Buffer Command") + + view.clear_temp_cut_buffer_delayed() + + buffer = view.get_buffer() + itr = buffer.get_iter_at_mark( buffer.get_insert() ) + start_itr = itr.copy() + end_itr = itr.copy() + start_line = itr.get_line() + 1 + start_char = itr.get_line_offset() + + start_itr.backward_visible_line() + start_itr.forward_line() + end_itr.forward_line() + + line_str = buffer.get_slice(start_itr, end_itr, True) + view._cut_buffer += f"{line_str}" + buffer.delete(start_itr, end_itr) + + view.set_temp_cut_buffer_delayed() diff --git a/src/core/widgets/code/commands/dnd_load_file_to_buffer.py b/src/core/widgets/code/commands/dnd_load_file_to_buffer.py new file mode 100644 index 0000000..cc7e537 --- /dev/null +++ b/src/core/widgets/code/commands/dnd_load_file_to_buffer.py @@ -0,0 +1,35 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports + + + +def execute( + view: GtkSource.View, + uri: str +): + logger.debug("DnD Load File To Buffer Command") + + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + + if not file.ftype == "buffer": + file = view.command.exec("new_file") + + gfile = Gio.File.new_for_uri(uri) + view.command.exec_with_args( + "load_file", + (view, gfile, file) + ) + + has_focus = view.command.exec("has_focus") + if has_focus: + view.command.exec("update_info_bar") diff --git a/src/core/widgets/code/commands/dnd_load_files.py b/src/core/widgets/code/commands/dnd_load_files.py new file mode 100644 index 0000000..0b063a7 --- /dev/null +++ b/src/core/widgets/code/commands/dnd_load_files.py @@ -0,0 +1,27 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, + uris: list = [] +): + logger.debug("DnD Load Files Command") + for uri in uris: + try: + gfile = Gio.File.new_for_uri(uri) + except Exception as e: + gfile = Gio.File.new_for_path(uri) + + view.command.exec_with_args("load_file", (view, gfile)) \ No newline at end of file diff --git a/src/core/widgets/code/commands/duplicate_line.py b/src/core/widgets/code/commands/duplicate_line.py new file mode 100644 index 0000000..10e89d9 --- /dev/null +++ b/src/core/widgets/code/commands/duplicate_line.py @@ -0,0 +1,53 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Duplicate Line Command") + + buffer = view.get_buffer() + + if not buffer.get_has_selection(): + had_selection = False + itr = buffer.get_iter_at_mark( buffer.get_insert() ) + start_itr = itr.copy() + end_itr = itr.copy() + start_line = itr.get_line() + 1 + start_char = itr.get_line_offset() + else: + had_selection = True + start_itr, end_itr = buffer.get_selection_bounds() + sline = start_itr.get_line() + eline = end_itr.get_line() + start_line = eline + 1 + start_char = start_itr.get_line_offset() + end_char = end_itr.get_line_offset() + range_line_size = eline - sline + + start_itr.backward_visible_line() + start_itr.forward_line() + end_itr.forward_line() + end_itr.backward_char() + + line_str = buffer.get_slice(start_itr, end_itr, True) + end_itr.forward_char() + buffer.insert(end_itr, f"{line_str}\n", -1) + + if not had_selection: + new_itr = buffer.get_iter_at_line_offset(start_line, start_char) + buffer.place_cursor(new_itr) + else: + new_itr = buffer.get_iter_at_line_offset(start_line, start_char) + new_end_itr = buffer.get_iter_at_line_offset((start_line + range_line_size), end_char) + buffer.select_range(new_itr, new_end_itr) diff --git a/src/core/widgets/code/commands/focus_left_sibling.py b/src/core/widgets/code/commands/focus_left_sibling.py new file mode 100644 index 0000000..42790c4 --- /dev/null +++ b/src/core/widgets/code/commands/focus_left_sibling.py @@ -0,0 +1,19 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Focus Left Sibling Command") + if not view.sibling_left: return + view.sibling_left.grab_focus() diff --git a/src/core/widgets/code/commands/focus_right_sibling.py b/src/core/widgets/code/commands/focus_right_sibling.py new file mode 100644 index 0000000..fbfbb48 --- /dev/null +++ b/src/core/widgets/code/commands/focus_right_sibling.py @@ -0,0 +1,19 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Focus Right Sibling Command") + if not view.sibling_right: return + view.sibling_right.grab_focus() diff --git a/src/core/widgets/code/commands/get_current_file.py b/src/core/widgets/code/commands/get_current_file.py new file mode 100644 index 0000000..6d28e2b --- /dev/null +++ b/src/core/widgets/code/commands/get_current_file.py @@ -0,0 +1,20 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Get Current File Command") + + buffer = view.get_buffer() + return view.files_manager.get_file(buffer) diff --git a/src/core/widgets/code/commands/get_filetype.py b/src/core/widgets/code/commands/get_filetype.py new file mode 100644 index 0000000..f19fed0 --- /dev/null +++ b/src/core/widgets/code/commands/get_filetype.py @@ -0,0 +1,21 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Get File Type Command") + + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + return file.ftype diff --git a/src/core/widgets/code/commands/get_text.py b/src/core/widgets/code/commands/get_text.py new file mode 100644 index 0000000..4a35bd8 --- /dev/null +++ b/src/core/widgets/code/commands/get_text.py @@ -0,0 +1,21 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Get Text Command") + + buffer = view.get_buffer() + start_itr, end_itr = buffer.get_bounds() + return buffer.get_text(start_itr, end_itr, True) diff --git a/src/core/widgets/code/commands/go_to.py b/src/core/widgets/code/commands/go_to.py new file mode 100644 index 0000000..81f9912 --- /dev/null +++ b/src/core/widgets/code/commands/go_to.py @@ -0,0 +1,31 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Go-To Command") + + file = view.command.exec("get_current_file") + gfile = file.get_location() + uri = gfile.get_uri() + + buffer = view.get_buffer() + iter = buffer.get_iter_at_mark( buffer.get_insert() ) + line = iter.get_line() + offset = iter.get_line_offset() + + event_system.emit( + "textDocument/definition", + (view, file.ftype, uri, line, offset,) + ) diff --git a/src/core/widgets/code/commands/has_focus.py b/src/core/widgets/code/commands/has_focus.py new file mode 100644 index 0000000..53fb64e --- /dev/null +++ b/src/core/widgets/code/commands/has_focus.py @@ -0,0 +1,19 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Has Focus Command") + ctx = view.get_parent().get_style_context() + return ctx.has_class("source-view-focused") diff --git a/src/core/widgets/code/commands/line_down.py b/src/core/widgets/code/commands/line_down.py new file mode 100644 index 0000000..01d5c37 --- /dev/null +++ b/src/core/widgets/code/commands/line_down.py @@ -0,0 +1,18 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Line Up Command") + view.emit("move-lines", True) diff --git a/src/core/widgets/code/commands/line_up.py b/src/core/widgets/code/commands/line_up.py new file mode 100644 index 0000000..0472f01 --- /dev/null +++ b/src/core/widgets/code/commands/line_up.py @@ -0,0 +1,18 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Line Up Command") + view.emit("move-lines", False) diff --git a/src/core/widgets/code/commands/load_file.py b/src/core/widgets/code/commands/load_file.py new file mode 100644 index 0000000..58677ea --- /dev/null +++ b/src/core/widgets/code/commands/load_file.py @@ -0,0 +1,32 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, + gfile: Gio.File, + file: SourceFile = None, +): + logger.debug("Load File Command") + if not file: + file = view.files_manager.new() + + file.load_path(gfile) + + language = view.language_manager \ + .guess_language(file.fname, None) + file.ftype = language + + file.buffer.set_language(language) + file.buffer.set_style_scheme(view.syntax_theme) diff --git a/src/core/widgets/code/commands/load_start_files.py b/src/core/widgets/code/commands/load_start_files.py new file mode 100644 index 0000000..6802699 --- /dev/null +++ b/src/core/widgets/code/commands/load_start_files.py @@ -0,0 +1,42 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, +): + logger.debug("Load Start File(s) Command") + + starting_files = settings_manager.get_starting_files() + + if len(starting_files) == 0: return + + file = starting_files.pop() + file = file.replace("FILE|", "") + gfile = Gio.File.new_for_path(file) + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + + view.command.exec_with_args( + "load_file", + (view, gfile, file) + ) + + if len(starting_files) == 0: return + + for file in starting_files: + file = file.replace("FILE|", "") + gfile = Gio.File.new_for_path(file) + + view.command.exec_with_args("load_file", (view, gfile)) diff --git a/src/core/widgets/code/commands/move_to_left_sibling.py b/src/core/widgets/code/commands/move_to_left_sibling.py new file mode 100644 index 0000000..5edf5bc --- /dev/null +++ b/src/core/widgets/code/commands/move_to_left_sibling.py @@ -0,0 +1,32 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Move To Left Sibling Command") + if not view.sibling_left: return + + buffer = view.get_buffer() + popped_file, next_file = view.files_manager.swap_file(buffer) + + popped_file.remove_observer(view) + popped_file.add_observer(view.sibling_left) + view.sibling_left.set_buffer(buffer) + view.sibling_left.grab_focus() + + if next_file: + next_file.add_observer(view) + view.set_buffer(next_file.buffer) + else: + view.command.exec("new_file") diff --git a/src/core/widgets/code/commands/move_to_right_sibling.py b/src/core/widgets/code/commands/move_to_right_sibling.py new file mode 100644 index 0000000..806f7c5 --- /dev/null +++ b/src/core/widgets/code/commands/move_to_right_sibling.py @@ -0,0 +1,32 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Move To Right Sibling Command") + if not view.sibling_right: return + + buffer = view.get_buffer() + popped_file, next_file = view.files_manager.swap_file(buffer) + + popped_file.remove_observer(view) + popped_file.add_observer(view.sibling_right) + view.sibling_right.set_buffer(buffer) + view.sibling_right.grab_focus() + + if next_file: + next_file.add_observer(view) + view.set_buffer(next_file.buffer) + else: + view.command.exec("new_file") diff --git a/src/core/widgets/code/commands/new_file.py b/src/core/widgets/code/commands/new_file.py new file mode 100644 index 0000000..85eb07a --- /dev/null +++ b/src/core/widgets/code/commands/new_file.py @@ -0,0 +1,33 @@ +# Python imports + + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("New File Command") + file = view.files_manager.new() + language = view.language_manager \ + .guess_language("file.txt", None) + + file.buffer.set_language(language) + file.buffer.set_style_scheme(view.syntax_theme) + + view.set_buffer(file.buffer) + file.add_observer(view) + + has_focus = view.command.exec("has_focus") + if not has_focus: return file + + view.command.exec("update_info_bar") + return file diff --git a/src/core/widgets/code/commands/open_files.py b/src/core/widgets/code/commands/open_files.py new file mode 100644 index 0000000..82dd055 --- /dev/null +++ b/src/core/widgets/code/commands/open_files.py @@ -0,0 +1,33 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Open File(s) Command") + gfiles = event_system.emit_and_await("open-files") + if not gfiles: return + + size = len(gfiles) + for i, gfile in enumerate(gfiles): + file = view.files_manager.new() + view.command.exec_with_args("load_file", (view, gfile, file)) + + if i == (size - 1): + buffer = view.get_buffer() + _file = view.files_manager.get_file(buffer) + _file.remove_observer(view) + + view.set_buffer(file.buffer) + file.add_observer(view) + view.command.exec("update_info_bar") diff --git a/src/core/widgets/code/commands/paste_temp_buffer.py b/src/core/widgets/code/commands/paste_temp_buffer.py new file mode 100644 index 0000000..30d28ed --- /dev/null +++ b/src/core/widgets/code/commands/paste_temp_buffer.py @@ -0,0 +1,28 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GLib +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Paste Temp Buffer Command") + + view.clear_temp_cut_buffer_delayed() + + buffer = view.get_buffer() + itr = buffer.get_iter_at_mark( buffer.get_insert() ) + insert_itr = itr.copy() + + buffer.insert(insert_itr, view._cut_buffer, -1) + + view.set_temp_cut_buffer_delayed() diff --git a/src/core/widgets/code/commands/save_file.py b/src/core/widgets/code/commands/save_file.py new file mode 100644 index 0000000..f63dd5a --- /dev/null +++ b/src/core/widgets/code/commands/save_file.py @@ -0,0 +1,30 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Save File Command") + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + + if file.ftype == "buffer": + file.save_as() + language = view.language_manager \ + .guess_language(file.fname, None) + file.ftype = language + file.buffer.set_language(language) + return + + file.save() + diff --git a/src/core/widgets/code/commands/save_file_as.py b/src/core/widgets/code/commands/save_file_as.py new file mode 100644 index 0000000..6e1568d --- /dev/null +++ b/src/core/widgets/code/commands/save_file_as.py @@ -0,0 +1,28 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.info("Save File As Command") + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + + file.save_as() + + language = view.language_manager \ + .guess_language(file.fname, None) + file.ftype = language + file.buffer.set_language(language) + file.add_observer(view) + view.exec_command("update_info_bar") diff --git a/src/core/widgets/code/commands/set_buffer.py b/src/core/widgets/code/commands/set_buffer.py new file mode 100644 index 0000000..a03e120 --- /dev/null +++ b/src/core/widgets/code/commands/set_buffer.py @@ -0,0 +1,36 @@ +# Python imports + + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, + file: SourceFile +): + logger.debug("Set Buffer Command") + + buffer = view.get_buffer() + _file = view.files_manager.get_file(buffer) + _file.remove_observer(view) + + if not file: + view.command.exec("new_file") + return + + view.set_buffer(file.buffer) + file.add_observer(view) + + has_focus = view.command.exec("has_focus") + if has_focus: + view.command.exec("update_info_bar") + diff --git a/src/core/widgets/code/commands/set_buffer_language.py b/src/core/widgets/code/commands/set_buffer_language.py new file mode 100644 index 0000000..299b23c --- /dev/null +++ b/src/core/widgets/code/commands/set_buffer_language.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View, + language: str +): + logger.debug("Set Buffer Language Command") + + buffer = editor.get_buffer() + buffer.set_language( + view.language_manager.get_language(language) + ) diff --git a/src/core/widgets/code/commands/set_buffer_style.py b/src/core/widgets/code/commands/set_buffer_style.py new file mode 100644 index 0000000..e12a030 --- /dev/null +++ b/src/core/widgets/code/commands/set_buffer_style.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View, + style: str +): + logger.debug("Set Buffer Style Command") + + buffer = editor.get_buffer() + buffer.set_style_scheme( + view.style_scheme_manager.get_scheme(style) + ) diff --git a/src/core/widgets/code/commands/set_focus_border.py b/src/core/widgets/code/commands/set_focus_border.py new file mode 100644 index 0000000..4f6bf39 --- /dev/null +++ b/src/core/widgets/code/commands/set_focus_border.py @@ -0,0 +1,26 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Set Focus Border Command") + ctx = view.get_parent().get_style_context() + ctx.add_class("source-view-focused") + + if view.sibling_right: + ctx = view.sibling_right.get_parent().get_style_context() + elif view.sibling_left: + ctx = view.sibling_left.get_parent().get_style_context() + + ctx.remove_class("source-view-focused") diff --git a/src/core/widgets/code/commands/set_miniview.py b/src/core/widgets/code/commands/set_miniview.py new file mode 100644 index 0000000..22b7161 --- /dev/null +++ b/src/core/widgets/code/commands/set_miniview.py @@ -0,0 +1,27 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from libs.dto.code_event import CodeEvent + +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, +): + logger.debug("Set MiniView Command") + event_system.emit("set-mini-view", (view,)) + + event = CodeEvent() + event.etype = "focused_view_change" + event.view = view + view.notify_observers(event) diff --git a/src/core/widgets/code/commands/show_completion.py b/src/core/widgets/code/commands/show_completion.py new file mode 100644 index 0000000..ba12082 --- /dev/null +++ b/src/core/widgets/code/commands/show_completion.py @@ -0,0 +1,18 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Show Completion Command") + view.completion.request_completion() diff --git a/src/core/widgets/code/commands/update_info_bar.py b/src/core/widgets/code/commands/update_info_bar.py new file mode 100644 index 0000000..73418a1 --- /dev/null +++ b/src/core/widgets/code/commands/update_info_bar.py @@ -0,0 +1,33 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, +): + logger.debug("Update Info Bar Command") + buffer = view.get_buffer() + file = view.files_manager.get_file(buffer) + + if not file: return + + iter = buffer.get_iter_at_mark( buffer.get_insert() ) + line = iter.get_line() + 1 + column = iter.get_line_offset() + ftype = file.ftype.get_id() if hasattr(file.ftype, "get_id") else file.ftype + + event_system.emit( + "set-info-labels", + (file.fpath, f"{line}:{column}", ftype, file.encoding) + ) diff --git a/src/core/widgets/code/commands/zoom_in.py b/src/core/widgets/code/commands/zoom_in.py new file mode 100644 index 0000000..2590bd5 --- /dev/null +++ b/src/core/widgets/code/commands/zoom_in.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Zoom In Command") + + ctx = view.get_style_context() + if view.zoom_level < 99: + ctx.remove_class(f"px{view.zoom_level}") + view.zoom_level += 1 + ctx.add_class(f"px{view.zoom_level}") \ No newline at end of file diff --git a/src/core/widgets/code/commands/zoom_out.py b/src/core/widgets/code/commands/zoom_out.py new file mode 100644 index 0000000..611905d --- /dev/null +++ b/src/core/widgets/code/commands/zoom_out.py @@ -0,0 +1,23 @@ +# Python imports + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports + + + +def execute( + view: GtkSource.View = None +): + logger.debug("Zoom Out Command") + + ctx = view.get_style_context() + if view.zoom_level > 1: + ctx.remove_class(f"px{view.zoom_level}") + view.zoom_level -= 1 + ctx.add_class(f"px{view.zoom_level}") \ No newline at end of file diff --git a/src/core/widgets/code/completion_manager.py b/src/core/widgets/code/completion_manager.py new file mode 100644 index 0000000..7600fb8 --- /dev/null +++ b/src/core/widgets/code/completion_manager.py @@ -0,0 +1,66 @@ +# Python imports + +# Lib imports +import gi +from gi.repository import GLib + +# Application imports +from .completion_providers.example_completion_provider import ExampleCompletionProvider +from .completion_providers.lsp_completion_provider import LSPCompletionProvider + + + +class CompletionManager(): + def __init__(self): + super(CompletionManager, self).__init__() + + self._lsp_provider = LSPCompletionProvider() + self._timeout_id = None + + + def set_completer(self, completer): + self._completor = completer + + def request_completion(self): + if self._timeout_id: + GLib.source_remove(self._timeout_id) + + self._timeout_id = GLib.timeout_add( + 800, + self._process_request_completion + ) + + def _process_request_completion(self): + self._start_completion() + + self._timeout_id = None + return False + + def _do_completion(self): + if self._completor.get_providers(): + self._mach_completion() + else: + self._start_completion() + + def _mach_completion(self): + """ + Note: Use IF providers were added to completion... + """ + self._completion.match( + self._completion.create_context() + ) + + def _start_completion(self): + """ + Note: Use IF NO providers have been added to completion... + print("here") + """ + self._completor.start( + [ + ExampleCompletionProvider(), + self._lsp_provider + ], + self._completor.create_context() + ) + + \ No newline at end of file diff --git a/src/core/widgets/code/completion_providers/__init__.py b/src/core/widgets/code/completion_providers/__init__.py new file mode 100644 index 0000000..fdff2e4 --- /dev/null +++ b/src/core/widgets/code/completion_providers/__init__.py @@ -0,0 +1,3 @@ +""" + Custom Completion Providers Module +""" diff --git a/src/core/widgets/code/completion_providers/example_completion_provider.py b/src/core/widgets/code/completion_providers/example_completion_provider.py new file mode 100644 index 0000000..10f29a0 --- /dev/null +++ b/src/core/widgets/code/completion_providers/example_completion_provider.py @@ -0,0 +1,84 @@ +# Python imports +import re + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('GtkSource', '4') + +from gi.repository import Gtk +from gi.repository import GtkSource +from gi.repository import GObject + +# Application imports + + + +class ExampleCompletionProvider(GObject.GObject, GtkSource.CompletionProvider): + """ + This is a custom Completion Example Provider. + # NOTE: used information from here --> https://warroom.rsmus.com/do-that-auto-complete/ + """ + __gtype_name__ = 'ExampleCompletionProvider' + + def __init__(self): + GObject.Object.__init__(self) + + def do_get_name(self): + """ Returns: a new string containing the name of the provider. """ + return 'Example Completion Provider' + + def do_match(self, context): + """ Get whether the provider match the context of completion detailed in context. """ + # NOTE: True for debugging but context needs to normally get checked for actual usage needs. + # TODO: Fix me + return True + + def do_get_priority(self): + """ Determin position in result list along other providor results. """ + return 1 + + # def do_get_activation(self): + # """ The context for when a provider will show results """ + # return GtkSource.CompletionActivation.NONE + # return GtkSource.CompletionActivation.USER_REQUESTED + # return GtkSource.CompletionActivation.INTERACTIVE + + def do_populate(self, context): + """ + In this instance, it will do 2 things: + 1) always provide Hello World! (Not ideal but an option so its in the example) + 2) Utilizes the Gtk.TextIter from the TextBuffer to determine if there is a jinja + example of '{{ custom.' if so it will provide you with the options of foo and bar. + If selected it will insert foo }} or bar }}, completing your syntax... + + PLEASE NOTE the GtkTextIter Logic and regex are really rough and should be adjusted and tuned + """ + + proposals = [ + GtkSource.CompletionItem(label='Hello World!', text = 'Hello World!', icon = None, info = None) # NOTE: Always proposed... + ] + + # Gtk Versions differ on get_iter responses... + end_iter = context.get_iter() + if not isinstance(end_iter, Gtk.TextIter): + _, end_iter = context.get_iter() + + if end_iter: + buf = end_iter.get_buffer() + mov_iter = end_iter.copy() + if mov_iter.backward_search('{{', Gtk.TextSearchFlags.VISIBLE_ONLY): + mov_iter, _ = mov_iter.backward_search('{{', Gtk.TextSearchFlags.VISIBLE_ONLY) + left_text = buf.get_text(mov_iter, end_iter, True) + else: + left_text = '' + + if re.match(r'.*\{\{\s*custom\.$', left_text): + proposals.append( + GtkSource.CompletionItem(label='foo', text='foo }}') # optionally proposed based on left search via regex + ) + proposals.append( + GtkSource.CompletionItem(label='bar', text='bar }}') # optionally proposed based on left search via regex + ) + + context.add_proposals(self, proposals, True) \ No newline at end of file diff --git a/src/core/widgets/code/completion_providers/lsp_completion_provider.py b/src/core/widgets/code/completion_providers/lsp_completion_provider.py new file mode 100644 index 0000000..45b76ba --- /dev/null +++ b/src/core/widgets/code/completion_providers/lsp_completion_provider.py @@ -0,0 +1,137 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('GtkSource', '4') + +from gi.repository import Gtk +from gi.repository import GtkSource +from gi.repository import GObject + +# Application imports + + + +class LSPCompletionProvider(GObject.Object, GtkSource.CompletionProvider): + """ + This code is an LSP code completion plugin for Newton. + # NOTE: Some code pulled/referenced from here --> https://github.com/isamert/gedi + """ + __gtype_name__ = 'LSPProvider' + + def __init__(self): + GObject.Object.__init__(self) + + self._icon_theme = Gtk.IconTheme.get_default() + + self.lsp_data = None + + + def pre_populate(self, context): + ... + + def do_get_name(self): + return "LSP Code Completion" + + def get_iter_correctly(self, context): + return context.get_iter()[1] if isinstance(context.get_iter(), tuple) else context.get_iter() + + def do_match(self, context): + iter = self.get_iter_correctly(context) + iter.backward_char() + + buffer = iter.get_buffer() + if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']: + return False + + ch = iter.get_char() + # NOTE: Look to re-add or apply supprting logic to use spaces + # As is it slows down the editor in certain contexts... + # if not (ch in ('_', '.', ' ') or ch.isalnum()): + if not (ch in ('_', '.') or ch.isalnum()): + return False + + return True + + def do_get_priority(self): + return 5 + + def do_populate(self, context, items = []): + # self.lsp_data + proposals = [] + + comp_item = GtkSource.CompletionItem.new() + comp_item.set_label("LSP Class") + comp_item.set_text("LSP Code") + # comp_item.set_icon(self.get_icon_for_type(completion.type)) + comp_item.set_info("A test LSP completion item...") + + context.add_proposals(self, [comp_item], True) + + + + + + + + + + + + + + + # def do_populate(self, context, items = []): + # if hasattr(self._source_view, "completion_items"): + # items = self._source_view.completion_items + + # proposals = [] + # for item in items: + # proposals.append( self.create_completion_item(item) ) + + # context.add_proposals(self, proposals, True) + + # def get_icon_for_type(self, _type): + # try: + # return self._theme.load_icon(icon_names[_type.lower()], 16, 0) + # except: + # ... + + # try: + # return self._theme.load_icon(Gtk.STOCK_ADD, 16, 0) + # except: + # ... + + # return None + + # def create_completion_item(self, item): + # comp_item = GtkSource.CompletionItem.new() + # keys = item.keys() + # comp_item.set_label(item["label"]) + + # if "insertText" in keys: + # comp_item.set_text(item["insertText"]) + + # if "additionalTextEdits" in keys: + # comp_item.additionalTextEdits = item["additionalTextEdits"] + + # return comp_item + + + # def create_completion_item(self, item): + # comp_item = GtkSource.CompletionItem.new() + # comp_item.set_label(item.label) + + # if item.textEdit: + # if isinstance(item.textEdit, dict): + # comp_item.set_text(item.textEdit["newText"]) + # else: + # comp_item.set_text(item.textEdit) + # else: + # comp_item.set_text(item.insertText) + + # comp_item.set_icon( self.get_icon_for_type(item.kind) ) + # comp_item.set_info(item.documentation) + + # return comp_item \ No newline at end of file diff --git a/src/core/widgets/code/completion_providers/python_completion_provider.py b/src/core/widgets/code/completion_providers/python_completion_provider.py new file mode 100644 index 0000000..319ce99 --- /dev/null +++ b/src/core/widgets/code/completion_providers/python_completion_provider.py @@ -0,0 +1,107 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('GtkSource', '4') + +from gi.repository import Gtk +from gi.repository import GtkSource +from gi.repository import GObject + +import jedi +from jedi.api import Script + +# Application imports + + + +# FIXME: Find real icon names... +icon_names = { + 'import': '', + 'module': '', + 'class': '', + 'function': '', + 'statement': '', + 'param': '' +} + + +class Jedi: + def get_script(file, doc_text): + return Script(code = doc_text, path = file) + + +class PythonCompletionProvider(GObject.Object, GtkSource.CompletionProvider): + """ + This code is A python code completion plugin for Newton. + # NOTE: Some code pulled/referenced from here --> https://github.com/isamert/gedi + """ + __gtype_name__ = 'PythonProvider' + + def __init__(self, file): + GObject.Object.__init__(self) + self._theme = Gtk.IconTheme.get_default() + self._file = file + + def do_get_name(self): + return "Python Code Completion" + + def get_iter_correctly(self, context): + return context.get_iter()[1] if isinstance(context.get_iter(), tuple) else context.get_iter() + + def do_match(self, context): + iter = self.get_iter_correctly(context) + iter.backward_char() + + buffer = iter.get_buffer() + if buffer.get_context_classes_at_iter(iter) != ['no-spell-check']: + return False + + ch = iter.get_char() + # NOTE: Look to re-add or apply supprting logic to use spaces + # As is it slows down the editor in certain contexts... + # if not (ch in ('_', '.', ' ') or ch.isalnum()): + if not (ch in ('_', '.') or ch.isalnum()): + return False + + return True + + def do_get_priority(self): + return 1 + + def do_get_activation(self): + return GtkSource.CompletionActivation.INTERACTIVE + + def do_populate(self, context): + # TODO: Maybe convert async? + it = self.get_iter_correctly(context) + buffer = it.get_buffer() + proposals = [] + + doc_text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), False) + iter_cursor = buffer.get_iter_at_mark(buffer.get_insert()) + linenum = iter_cursor.get_line() + 1 + charnum = iter_cursor.get_line_index() + + def create_generator(): + for completion in Jedi.get_script(self._file, doc_text).complete(line = linenum, column = None, fuzzy = False): + comp_item = GtkSource.CompletionItem.new() + comp_item.set_label(completion.name) + comp_item.set_text(completion.name) + comp_item.set_icon(self.get_icon_for_type(completion.type)) + comp_item.set_info(completion.docstring()) + yield comp_item + + for item in create_generator(): + proposals.append(item) + + context.add_proposals(self, proposals, True) + + def get_icon_for_type(self, _type): + try: + return self._theme.load_icon(icon_names[_type.lower()], 16, 0) + except (KeyError, AttributeError, GObject.GError) as e: + return self._theme.load_icon(Gtk.STOCK_ADD, 16, 0) + except (GObject.GError, AttributeError) as e: + return None \ No newline at end of file diff --git a/src/core/widgets/code/general_info_widget.py b/src/core/widgets/code/general_info_widget.py new file mode 100644 index 0000000..a9c47b6 --- /dev/null +++ b/src/core/widgets/code/general_info_widget.py @@ -0,0 +1,103 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Pango +from gi.repository import Gio + +# Application imports + + + +class GeneralInfoWidget(Gtk.Box): + """ docstring for StatusInfoWidget. """ + + def __init__(self): + super(GeneralInfoWidget, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_margin_start(25) + self.set_margin_end(25) + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe("set-info-labels", self._set_info_labels) + event_system.subscribe("set-path-label", self._set_path_label) + event_system.subscribe("set-encoding-label", self._set_encoding_label) + event_system.subscribe("set-line-char-label", self._set_line_char_label) + event_system.subscribe("set-file-type-label", self._set_file_type_label) + + + def _load_widgets(self): + self.path_label = Gtk.Label(label = "...") + self.line_char_label = Gtk.Label(label = "1:0") + self.encoding_label = Gtk.Label(label = "utf-8") + self.file_type_label = Gtk.Label(label = "buffer") + + self.add(self.path_label) + self.add(self.line_char_label) + self.add(self.encoding_label) + self.add(self.file_type_label) + + self.path_label.set_hexpand(True) + self.path_label.set_ellipsize(Pango.EllipsizeMode.START) + self.path_label.set_single_line_mode(True) + self.path_label.set_max_width_chars(48) + + self.line_char_label.set_hexpand(True) + self.encoding_label.set_hexpand(True) + self.file_type_label.set_hexpand(True) + + def _set_info_labels( + self, + path: Gio.File or str = None, + line_char: str = None, + file_type: str = None, + encoding_type: str = None + ): + self._set_path_label(path) + self._set_line_char_label(line_char) + self._set_file_type_label(file_type) + self._set_encoding_label(encoding_type) + + def _set_path_label(self, gfile: Gio.File or str = "..."): + gfile = "" if not gfile else gfile + + if isinstance(gfile, str): + # path = gfile + # path = "..." + path[-120: -1] if len(path) >= 123 else path + # self.path_label.set_text( path ) + self.path_label.set_text( gfile ) + self.path_label.set_tooltip_text( gfile ) + else: + self.path_label.set_text( gfile.get_path() ) + self.path_label.set_tooltip_text( gfile.get_path() ) + + def _set_line_char_label(self, line_char = "1:1"): + line_char = "1:1" if not line_char else line_char + + self.line_char_label.set_text(line_char) + + def _set_file_type_label(self, file_type = "buffer"): + file_type = "buffer" if not file_type else file_type + + self.file_type_label.set_text(file_type) + + def _set_encoding_label(self, encoding_type = "utf-8"): + encoding_type = "utf-8" if not encoding_type else encoding_type + + self.encoding_label.set_text(encoding_type) + + diff --git a/src/core/widgets/code/key_mapper.py b/src/core/widgets/code/key_mapper.py new file mode 100644 index 0000000..9ddfb96 --- /dev/null +++ b/src/core/widgets/code/key_mapper.py @@ -0,0 +1,127 @@ +# Python imports +import copy +import json + +# Lib imports +import gi +gi.require_version('Gdk', '3.0') +from gi.repository import Gdk + +# Application imports + + + +class NoKeyState: + held: dict = {} + released: dict = {} + +class CtrlKeyState: + held: dict = {} + released: dict = {} + +class ShiftKeyState: + held: dict = {} + released: dict = {} + +class AltKeyState: + held: dict = {} + released: dict = {} + +class CtrlShiftKeyState: + held: dict = {} + released: dict = {} + +class CtrlAltKeyState: + held: dict = {} + released: dict = {} + +class AltShiftKeyState: + held: dict = {} + released: dict = {} + +class CtrlShiftAltKeyState: + held: dict = {} + released: dict = {} + + + +class KeyMapper: + def __init__(self): + super(KeyMapper, self).__init__() + + self.state = NoKeyState + self._map = { + NoKeyState: NoKeyState(), + NoKeyState | CtrlKeyState : CtrlKeyState(), + NoKeyState | ShiftKeyState: ShiftKeyState(), + NoKeyState | AltKeyState : AltKeyState(), + NoKeyState | CtrlKeyState | ShiftKeyState : CtrlShiftKeyState(), + NoKeyState | CtrlKeyState | AltKeyState : CtrlAltKeyState(), + NoKeyState | AltKeyState | ShiftKeyState : AltShiftKeyState(), + NoKeyState | CtrlKeyState | ShiftKeyState | AltKeyState: CtrlShiftAltKeyState(), + } + + self.load_map() + + + def load_map(self): + self.states = copy.deepcopy(self._map) + bindings_file = f"{settings_manager.path_manager.get_home_config_path()}/code-key-bindings.json" + + with open(bindings_file, 'r') as f: + data = json.load(f)["keybindings"] + + for command in data: + press_state = "held" if "held" in data[command] else "released" + keyname = data[command][press_state] + + state = NoKeyState + if "" in keyname: + state = state | CtrlKeyState + if "" in keyname: + state = state | ShiftKeyState + if "" in keyname: + state = state | AltKeyState + + keyname = keyname.replace("", "") \ + .replace("", "") \ + .replace("", "") \ + .lower() + + getattr(self.states[state], press_state)[keyname] = command + + def re_map(self): + self.states = copy.deepcopy(self._map) + + def _key_press_event(self, eve): + keyname = Gdk.keyval_name(eve.keyval).lower() + + self._set_key_state(eve) + if keyname in self.states[self.state].held: + return self.states[self.state].held[keyname] + + def _key_release_event(self, eve): + keyname = Gdk.keyval_name(eve.keyval).lower() + + self._set_key_state(eve) + if keyname in self.states[self.state].released: + return self.states[self.state].released[keyname] + + def _set_key_state(self, eve): + modifiers = Gdk.ModifierType(eve.get_state() & ~Gdk.ModifierType.LOCK_MASK) + is_control = True if modifiers & Gdk.ModifierType.CONTROL_MASK else False + is_shift = True if modifiers & Gdk.ModifierType.SHIFT_MASK else False + + try: + is_alt = True if modifiers & Gdk.ModifierType.ALT_MASK else False + except Exception: + is_alt = True if modifiers & Gdk.ModifierType.MOD1_MASK else False + + self.state = NoKeyState + if is_control: + self.state = self.state | CtrlKeyState + if is_shift: + self.state = self.state | ShiftKeyState + if is_alt: + self.state = self.state | AltKeyState + diff --git a/src/core/widgets/code/miniview_widget.py b/src/core/widgets/code/miniview_widget.py new file mode 100644 index 0000000..ba5c758 --- /dev/null +++ b/src/core/widgets/code/miniview_widget.py @@ -0,0 +1,38 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('GtkSource', '4') +from gi.repository.GtkSource import Map + + +# Application imports + + + +class MiniViewWidget(Map): + def __init__(self): + super(MiniViewWidget, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.set_hexpand(False) + ctx = self.get_style_context() + ctx.add_class("mini-view") + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe(f"set-mini-view", self.set_smini_view) + + def _load_widgets(self): + ... + + def set_smini_view(self, source_view): + self.set_view(source_view) \ No newline at end of file diff --git a/src/core/widgets/code/mixins/__init__.py b/src/core/widgets/code/mixins/__init__.py new file mode 100644 index 0000000..96544fc --- /dev/null +++ b/src/core/widgets/code/mixins/__init__.py @@ -0,0 +1,3 @@ +""" + Code Mixins Package +""" \ No newline at end of file diff --git a/src/core/widgets/code/mixins/source_view_dnd_mixin.py b/src/core/widgets/code/mixins/source_view_dnd_mixin.py new file mode 100644 index 0000000..99b3fc2 --- /dev/null +++ b/src/core/widgets/code/mixins/source_view_dnd_mixin.py @@ -0,0 +1,40 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class SourceViewDnDMixin: + + def _set_up_dnd(self): + PLAIN_TEXT_TARGET_TYPE = 70 + URI_TARGET_TYPE = 80 + text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE) + uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) + targets = [ text_target, uri_target ] + + self.drag_dest_set_target_list(targets) + + def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time): + if info == 70: return + + if info == 80: + uris = data.get_uris() + + if len(uris) == 0: + uris = data.get_text().split("\n") + + self._on_uri_data_received(uris) + + def _on_uri_data_received(self, uris: []): + uri = uris.pop(0) + self.command.exec_with_args("dnd_load_file_to_buffer", (self, uri)) + + if len(uris) == 0: return + + self.command.exec_with_args("dnd_load_files", (self, uris)) diff --git a/src/core/widgets/code/mixins/source_view_events_mixin.py b/src/core/widgets/code/mixins/source_view_events_mixin.py new file mode 100644 index 0000000..5e070e0 --- /dev/null +++ b/src/core/widgets/code/mixins/source_view_events_mixin.py @@ -0,0 +1,63 @@ +# Python imports + +# Lib imports + +# Application imports +from libs.dto.code_event import CodeEvent + + + +class SourceViewEventsMixin: + def _focus_in_event(self, view, eve): + self.command.exec("set_miniview") + self.command.exec("set_focus_border") + self.command.exec("update_info_bar") + + def _move_cursor(self, view, step, count, extend_selection): + self.command.exec("update_info_bar") + + def _button_press_event(self, view, eve): + self.command.exec("update_info_bar") + + def _button_release_event(self, view, eve): + self.command.exec("update_info_bar") + + def _key_press_event(self, view, eve): + command = self.key_mapper._key_press_event(eve) + if not command: return False + + self.command.exec(command) + return True + + def _key_release_event(self, view, eve): + command = self.key_mapper._key_release_event(eve) + if not command: return False + + self.command.exec(command) + return True + + def notification(self, event: CodeEvent): + if not hasattr(self, "command"): return + + has_focus = self.command.exec("has_focus") + if not has_focus and not event.ignore_focus: return + + match event.etype: + case "removed_file": + logger.debug("SourceFileManager.remove_file") + if not event.file.buffer == self.get_buffer(): return + self.command.exec_with_args("set_buffer", (self, event.next_file)) + return + case "changed": + logger.debug("SourceFile._changed") + case "modified_changed": + logger.debug("SourceFile._modified_changed") + case "insert_text": + logger.debug("SourceFile._insert_text") + case "mark_set": + # logger.debug("SourceFile._mark_set") + ... + case _: + ... + + self.command.exec("update_info_bar") diff --git a/src/core/widgets/code/source_buffer.py b/src/core/widgets/code/source_buffer.py new file mode 100644 index 0000000..8c70296 --- /dev/null +++ b/src/core/widgets/code/source_buffer.py @@ -0,0 +1,40 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('GtkSource', '4') +from gi.repository import GtkSource + +# Application imports + + + +class SourceBuffer(GtkSource.Buffer): + def __init__(self): + super(SourceBuffer, self).__init__() + + self._handler_ids = [] + + + def set_signals( + self, + _changed, + _mark_set, + _insert_text, + _modified_changed, + ): + + self._handler_ids = [ + self.connect("changed", _changed), + self.connect("mark-set", _mark_set), + self.connect("insert-text", _insert_text), + self.connect("modified-changed", _modified_changed) + ] + + def clear_signals(self): + for handle_id in self._handler_ids: + self.disconnect(handle_id) + + def __del__(self): + for handle_id in self._handler_ids: + self.disconnect(handle_id) \ No newline at end of file diff --git a/src/core/widgets/code/source_file.py b/src/core/widgets/code/source_file.py new file mode 100644 index 0000000..2304202 --- /dev/null +++ b/src/core/widgets/code/source_file.py @@ -0,0 +1,137 @@ +# Python imports +import os + +# Lib imports +import gi + +gi.require_version('Gtk', '3.0') +gi.require_version('GtkSource', '4') + +from gi.repository import Gtk +from gi.repository import GtkSource +from gi.repository import Gio + +# Application imports +from libs.mixins.observable_mixin import ObservableMixin +from libs.dto.code_event import CodeEvent + +from .source_buffer import SourceBuffer + + + +class SourceFile(GtkSource.File, ObservableMixin): + def __init__(self): + super(SourceFile, self).__init__() + + self.observers = [] + + self.encoding: str = "UTF-8" + self.fname: str = "buffer" + self.fpath: str = "buffer" + self.ftype: str = "buffer" + + self.buffer: SourceBuffer = SourceBuffer() + + self._set_signals() + + + def _set_signals(self): + self.buffer.set_signals( + self._changed, + self._mark_set, + self._insert_text, + self._modified_changed + ) + + + def _insert_text(self, buffer: SourceBuffer, location: Gtk.TextIter, + text: str, length: int + ): + event = CodeEvent() + event.etype = "insert_text" + event.file = self + event.buffer = buffer + + self.notify_observers(event) + + def _changed(self, buffer: SourceBuffer): + event = CodeEvent() + event.etype = "changed" + event.file = self + event.buffer = buffer + + self.notify_observers(event) + + def _mark_set(self, buffer: SourceBuffer, location: Gtk.TextIter, + mark: Gtk.TextMark + ): + # event = CodeEvent() + # event.etype = "mark_set" + # event.file = self + # event.buffer = buffer + + # self.notify_observers(event) + ... + + def _modified_changed(self, buffer: SourceBuffer): + event = CodeEvent() + event.etype = "modified_changed" + event.file = self + event.buffer = buffer + + self.notify_observers(event) + + + def _write_file(self, gfile: Gio.File): + if not gfile: return + + with open(gfile.get_path(), 'w') as f: + start_itr, end_itr = self.buffer.get_bounds() + text = self.buffer.get_text(start_itr, end_itr, True) + + f.write(text) + + return gfile + + + def load_path(self, gfile: Gio.File): + if not gfile: return + + self.set_path(gfile) + data = gfile.load_bytes()[0].get_data().decode("UTF-8") + undo_manager = self.buffer.get_undo_manager() + + undo_manager.begin_not_undoable_action() + self.buffer.insert_at_cursor(data) + undo_manager.end_not_undoable_action() + + def set_path(self, gfile: Gio.File): + if not gfile: return + self.set_location(gfile) + + self.fpath = gfile.get_path() + self.fname = gfile.get_basename() + + event = CodeEvent() + event.etype = "set_path" + event.file = self + + self.notify_observers(event) + + def save(self): + self._write_file( self.get_location() ) + + def save_as(self): + file = event_system.emit_and_await("save-file-dialog") + if not file: return + + self._write_file(file) + self.set_path(file) + + return file + + def close(self): + self.observers.clear() + + del self.observers + del self.buffer \ No newline at end of file diff --git a/src/core/widgets/code/source_files_manager.py b/src/core/widgets/code/source_files_manager.py new file mode 100644 index 0000000..0e9c9f0 --- /dev/null +++ b/src/core/widgets/code/source_files_manager.py @@ -0,0 +1,106 @@ +# Python imports + +# Lib imports + +# Application imports +from libs.mixins.observable_mixin import ObservableMixin +from libs.singleton import Singleton +from libs.dto.code_event import CodeEvent + +from .source_file import SourceFile +from .source_buffer import SourceBuffer + + + +class SourceFilesManager(Singleton, list, ObservableMixin): + def __init__(self): + super(SourceFilesManager, self).__init__() + + self.observers = [] + + + def new(self): + file = SourceFile() + self.append(file) + return file + + def append(self, file: SourceFile): + if not file: return + super().append(file) + + event = CodeEvent() + event.etype = "appended_file" + event.file = file + + self.notify_observers(event) + + def get_file(self, buffer: SourceBuffer): + if not buffer: return + + for file in self: + if not buffer == file.buffer: continue + return file + + def pop_file(self, buffer: SourceBuffer): + if not buffer: return + + for i, file in enumerate(self): + if not buffer == file.buffer: continue + + j = self.next_index(i) + next_file = self[j] if not j == -1 else None + popped_file = self.pop(i) + event = CodeEvent() + event.etype = "popped_file" + event.file = popped_file + event.next_file = next_file + + self.notify_observers(event) + + return popped_file, next_file + + def swap_file(self, buffer: SourceBuffer): + if not buffer: return + + for i, file in enumerate(self): + if not buffer == file.buffer: continue + + j = self.next_index(i) + next_file = self[j] + swapped_file = self[j] if not j == -1 else None + + return swapped_file, next_file + + def remove_file(self, buffer: SourceBuffer): + if not buffer: return + + for i, file in enumerate(self): + if not buffer == file.buffer: continue + + j = self.next_index(i) + next_file = self[j] if not j == -1 else None + event = CodeEvent() + event.etype = "removed_file" + event.ignore_focus = True + event.file = file + event.next_file = next_file + self.notify_observers(event) + + self.remove(file) + file.close() + + return next_file + + def next_index(self, i): + size = len(self) + + if (i == 0) & (size >= 2): + j = i + 1 + elif (i == (size - 1)) & (size >= 2): + j = i - 1 + elif (size - 1) == 0: + j = -1 + else: + j = i + 1 + + return j \ No newline at end of file diff --git a/src/core/widgets/code/tab_widget.py b/src/core/widgets/code/tab_widget.py new file mode 100644 index 0000000..f1cc6c2 --- /dev/null +++ b/src/core/widgets/code/tab_widget.py @@ -0,0 +1,61 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class TabWidget(Gtk.Box): + def __init__(self): + super(TabWidget, self).__init__() + + self.file = None + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + ctx = self.get_style_context() + ctx.add_class("tab-widget") + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self._label_eve_box = Gtk.EventBox() + self.label = Gtk.Label(label = "") + self.close_btn = Gtk.Button(label = "X") + + ctx = self.label.get_style_context() + ctx.add_class("tab-label") + ctx = self.close_btn.get_style_context() + ctx.add_class("tab-close-bttn") + + self.label.set_hexpand(True) + + self._label_eve_box.add(self.label) + self.add(self._label_eve_box) + self.add(self.close_btn) + + def clear_signals_and_data(self): + del self.file + self._label_eve_box.disconnect(self._label_eve_box_id) + self.close_btn.disconnect(self.close_btn_id) + + def set_select_signal(self, callback): + self._label_eve_box_id = self._label_eve_box.connect('button-release-event', callback, self.file) + + def set_close_signal(self, callback): + self.close_btn_id = self.close_btn.connect('button-release-event', callback, self.file) diff --git a/src/core/widgets/code/tabs_widget.py b/src/core/widgets/code/tabs_widget.py new file mode 100644 index 0000000..208f44a --- /dev/null +++ b/src/core/widgets/code/tabs_widget.py @@ -0,0 +1,107 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports +from libs.dto.code_event import CodeEvent + +from .view import SourceView +from .source_files_manager import SourceFilesManager +from .source_file import SourceFile + +from .tab_widget import TabWidget + + + +class TabsWidget(Gtk.ScrolledWindow): + def __init__(self): + super(TabsWidget, self).__init__() + + self.active_view: SourceView = None + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.set_overlay_scrolling(False) + + def _setup_signals(self): + event_system.subscribe("register-view-to-tabs-widget", self._register_view_to_tabs_widget) + + def _subscribe_to_events(self): + self.files_manager: SourceFilesManager = SourceFilesManager() + self.files_manager.add_observer(self) + + def _load_widgets(self): + self.viewport = Gtk.Viewport() + self.tabs = Gtk.ButtonBox() + + self.tabs.set_layout(Gtk.ButtonBoxStyle.CENTER) + + self.viewport.add(self.tabs) + self.add(self.viewport) + + def _register_view_to_tabs_widget(self, view: SourceView): + view.add_observer(self) + view.set_files_manager(self.files_manager) + + def notification(self, event: CodeEvent): + match event.etype: + case "focused_view_change": + logger.debug("SourceView.focused_view_change") + self.active_view = event.view + case "appended_file": + logger.debug("SourceFilesManager.appended") + self.add_tab(event) + case "popped_file": + logger.debug("SourceFilesManager.pop_file") + case "removed_file": + logger.debug("SourceFilesManager.remove_file") + self.remove_tab(event) + case "set_path": + logger.debug("SourceFile.set_path") + self.update_tab_label(event) + case _: + ... + + def add_tab(self, event: CodeEvent): + tab = TabWidget() + tab.file = event.file + + tab.label.set_label(event.file.fname) + event.file.add_observer(self) + + def select_signal(widget, eve, file): + self.active_view.command.exec_with_args("set_buffer", (self.active_view, file)) + + def close_signal(widget, eve, file): + self.files_manager.remove_file(file.buffer) + + tab.set_select_signal(select_signal) + tab.set_close_signal(close_signal) + + self.tabs.add(tab) + + def remove_tab(self, event: CodeEvent): + for child in self.tabs.get_children(): + if not child.file == event.file: continue + + child.file.remove_observer(self) + self.tabs.remove(child) + child.clear_signals_and_data() + del child + + return + + def update_tab_label(self, event: CodeEvent): + for tab in self.tabs.get_children(): + if not tab.file == event.file: continue + tab.label.set_label(event.file.fname) + + return diff --git a/src/core/widgets/code/view.py b/src/core/widgets/code/view.py new file mode 100644 index 0000000..44be6f9 --- /dev/null +++ b/src/core/widgets/code/view.py @@ -0,0 +1,130 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('GtkSource', '4') + +from gi.repository import Gtk +from gi.repository import GLib +from gi.repository import GtkSource + +# Application imports +from libs.mixins.observable_mixin import ObservableMixin + +from .mixins.source_view_events_mixin import SourceViewEventsMixin +from .mixins.source_view_dnd_mixin import SourceViewDnDMixin + +from .source_files_manager import SourceFilesManager +from .completion_manager import CompletionManager +from .command_system import CommandSystem +from .key_mapper import KeyMapper + + + +class SourceView(GtkSource.View, ObservableMixin, SourceViewEventsMixin, SourceViewDnDMixin): + def __init__(self): + super(SourceView, self).__init__() + + self.observers = [] + self._cut_temp_timeout_id = None + self._cut_buffer = "" + + self.sibling_right = None + self.sibling_left = None + + self._setup_styles() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styles(self): + self.zoom_level = settings_manager.settings.theming.default_zoom + ctx = self.get_style_context() + + ctx.add_class("source-view") + ctx.add_class(f"px{self.zoom_level}") + + self.set_vexpand(True) + self.set_bottom_margin(800) + + self.set_show_line_marks(True) + self.set_show_line_numbers(True) + self.set_smart_backspace(True) + self.set_indent_on_tab(True) + self.set_insert_spaces_instead_of_tabs(True) + self.set_auto_indent(True) + self.set_monospace(True) + self.set_tab_width(4) + self.set_show_right_margin(True) + self.set_right_margin_position(80) + self.set_background_pattern(0) # 0 = None, 1 = Grid + self.set_highlight_current_line(True) + + def _setup_signals(self): + self.map_id = self.connect("map", self._init_map) + + self.connect("focus-in-event", self._focus_in_event) + self.connect("drag-data-received", self._on_drag_data_received) + self.connect("move-cursor", self._move_cursor) + self.connect("key-press-event", self._key_press_event) + self.connect("key-release-event", self._key_release_event) + self.connect("button-press-event", self._button_press_event) + self.connect("button-release-event", self._button_release_event) + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + self._set_up_dnd() + event_system.emit("register-view-to-tabs-widget", (self,)) + + def _init_map(self, view): + self.disconnect(self.map_id) + del self.map_id + + GLib.idle_add(self._init_show) + + def _init_show(self): + self.language_manager = GtkSource.LanguageManager() + self.style_scheme_manager = GtkSource.StyleSchemeManager() + + self.key_mapper = KeyMapper() + self.command = CommandSystem() + self.completion = CompletionManager() + + self.command.set_data(self) + self.completion.set_completer( self.get_completion() ) + + self.style_scheme_manager.append_search_path( + f"{settings_manager.path_manager.get_home_config_path()}/code_styles" + ) + self.syntax_theme = self.style_scheme_manager.get_scheme( + f"{settings_manager.settings.theming.syntax_theme}" + ) + + self.command.exec("new_file") + + if not self.sibling_right: return + + self.grab_focus() + self.command.exec("load_start_files") + + return False + + def set_files_manager(self, files_manager: SourceFilesManager): + self.files_manager = files_manager + self.files_manager.add_observer(self) + + def clear_temp_cut_buffer_delayed(self): + if self._cut_temp_timeout_id: + GLib.source_remove(self._cut_temp_timeout_id) + + def set_temp_cut_buffer_delayed(self): + def clear_temp_buffer(): + self._cut_buffer = "" + self._cut_temp_timeout_id = None + return False + + self._cut_temp_timeout_id = GLib.timeout_add(15000, clear_temp_buffer) diff --git a/src/core/widgets/controls/__init__.py b/src/core/widgets/controls/__init__.py new file mode 100644 index 0000000..a82161f --- /dev/null +++ b/src/core/widgets/controls/__init__.py @@ -0,0 +1,3 @@ +""" + Widgets.Controls Package +""" \ No newline at end of file diff --git a/src/core/widgets/controls/open_files_button.py b/src/core/widgets/controls/open_files_button.py new file mode 100644 index 0000000..df5e43c --- /dev/null +++ b/src/core/widgets/controls/open_files_button.py @@ -0,0 +1,83 @@ +# Python imports +from contextlib import suppress +import os + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gio + +# Application imports + + + +class OpenFilesButton(Gtk.Button): + """docstring for OpenFilesButton.""" + + def __init__(self): + super(OpenFilesButton, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.set_label("Open File(s)...") + self.set_image( Gtk.Image.new_from_icon_name("gtk-open", 4) ) + self.set_always_show_image(True) + self.set_image_position(1) # Left - 0, Right = 1 + self.set_hexpand(False) + + def _setup_signals(self): + self.connect("button-release-event", self._open_files) + + def _subscribe_to_events(self): + event_system.subscribe("open-files", self._open_files) + + def _load_widgets(self): + ... + + def _open_files(self, widget = None, eve = None, gfile = None): + start_dir = None + _gfiles = [] + + if gfile and gfile.query_exists(): + start_dir = gfile.get_parent() + + chooser = Gtk.FileChooserDialog("Open File(s)...", None, + Gtk.FileChooserAction.OPEN, + ( + Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, + Gtk.STOCK_OPEN, + Gtk.ResponseType.OK + ) + ) + + chooser.set_select_multiple(True) + + with suppress(Exception): + folder = widget.get_current_file().get_parent() if not start_dir else start_dir + chooser.set_current_folder( folder.get_path() ) + + response = chooser.run() + if not response == Gtk.ResponseType.OK: + chooser.destroy() + return _gfiles + + filenames = chooser.get_filenames() + if not filenames: + chooser.destroy() + return _gfiles + + for file in filenames: + path = file if os.path.isabs(file) else os.path.abspath(file) + _gfiles.append( Gio.File.new_for_path(path) ) + + chooser.destroy() + + logger.debug(_gfiles) + return _gfiles \ No newline at end of file diff --git a/src/core/widgets/controls/save_as_button.py b/src/core/widgets/controls/save_as_button.py new file mode 100644 index 0000000..aa81ae0 --- /dev/null +++ b/src/core/widgets/controls/save_as_button.py @@ -0,0 +1,72 @@ +# Python imports +import os + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gio + +# Application imports + + + +class SaveAsButton(Gtk.Button): + def __init__(self): + super(SaveAsButton, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + self.set_label("Save As") + self.set_image( Gtk.Image.new_from_icon_name("gtk-save-as", 4) ) + self.set_always_show_image(True) + self.set_image_position(1) # Left - 0, Right = 1 + self.set_hexpand(False) + + def _setup_signals(self): + self.connect("released", self._save_as) + + def _subscribe_to_events(self): + event_system.subscribe("save-as", self._save_as) + + def _load_widgets(self): + ... + + def _save_as(self, widget = None, eve = None, gfile = None): + start_dir = None + _gfile = None + + chooser = Gtk.FileChooserDialog("Save File As...", None, + Gtk.FileChooserAction.SAVE, + ( + Gtk.STOCK_CANCEL, + Gtk.ResponseType.CANCEL, + Gtk.STOCK_SAVE_AS, + Gtk.ResponseType.OK + ) + ) + + # chooser.set_select_multiple(False) + + response = chooser.run() + if not response == Gtk.ResponseType.OK: + chooser.destroy() + return _gfile + + file = chooser.get_filename() + if not file: + chooser.destroy() + return _gfile + + path = file if os.path.isabs(file) else os.path.abspath(file) + _gfile = Gio.File.new_for_path(path) + + chooser.destroy() + + logger.debug(f"File To Save As: {_gfile}") + return _gfile diff --git a/src/core/widgets/controls/transparency_scale.py b/src/core/widgets/controls/transparency_scale.py new file mode 100644 index 0000000..5332e38 --- /dev/null +++ b/src/core/widgets/controls/transparency_scale.py @@ -0,0 +1,48 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class TransparencyScale(Gtk.Scale): + def __init__(self): + super(TransparencyScale, self).__init__() + + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self.show_all() + + + def _setup_styling(self): + self.set_digits(0) + self.set_value_pos(Gtk.PositionType.RIGHT) + self.add_mark(50.0, Gtk.PositionType.TOP, "50%") + self.set_hexpand(True) + + def _setup_signals(self): + self.connect("value-changed", self._update_transparency) + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + adjust = self.get_adjustment() + adjust.set_lower(0) + adjust.set_upper(100) + adjust.set_value(settings_manager.settings.theming.transparency) + adjust.set_step_increment(1.0) + + def _update_transparency(self, range): + event_system.emit("remove-transparency") + tp = int(range.get_value()) + settings_manager.settings.theming.transparency = tp + event_system.emit("update-transparency") \ No newline at end of file diff --git a/src/core/widgets/save_file_dialog.py b/src/core/widgets/save_file_dialog.py new file mode 100644 index 0000000..1dc7eb7 --- /dev/null +++ b/src/core/widgets/save_file_dialog.py @@ -0,0 +1,66 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Gio + +# Application imports + + + +class SaveFileDialog: + """docstring for SaveFileDialog.""" + + def __init__(self): + super(SaveFileDialog, self).__init__() + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + ... + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + event_system.subscribe("save-file-dialog", self.save_file_dialog) + + def _load_widgets(self): + self._file_filter_text = Gtk.FileFilter() + self._file_filter_text.set_name("Code Files") + + for p in settings_manager.settings.filters.code: + self._file_filter_text.add_pattern(p) + + self._file_filter_all = Gtk.FileFilter() + self._file_filter_all.set_name("All Files") + self._file_filter_all.add_pattern("*.*") + + + def save_file_dialog(self, current_filename: str = "", current_file: Gio.File = None) -> str: + dlg = Gtk.FileChooserDialog(title = "Please choose a file...", parent = None, action = 1) + + dlg.add_buttons("Cancel", Gtk.ResponseType.CANCEL, "Save", Gtk.ResponseType.OK) + dlg.set_do_overwrite_confirmation(True) + dlg.add_filter(self._file_filter_text) + dlg.add_filter(self._file_filter_all) + + if current_filename == "": + import os + dlg.set_current_name("new.txt") + dlg.set_current_folder(os.path.expanduser('~')) + else: + dlg.set_current_folder(current_file.get_parent().get_uri()) + dlg.set_current_name(current_filename) + + response = dlg.run() + file = dlg.get_filename() if response == Gtk.ResponseType.OK else "" + dlg.destroy() + + return Gio.File.new_for_path(file) if not file == "" else None \ No newline at end of file diff --git a/src/core/widgets/separator_widget.py b/src/core/widgets/separator_widget.py new file mode 100644 index 0000000..7725b21 --- /dev/null +++ b/src/core/widgets/separator_widget.py @@ -0,0 +1,37 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk + +# Application imports + + + +class Separator(Gtk.Separator): + def __init__(self, id: str = None, ORIENTATION: int = 0): + super(Separator, self).__init__() + + builder = settings_manager.get_builder() + if id: + builder.expose_object(id, self) + + self.ORIENTATION = ORIENTATION + self._setup_styling() + self._setup_signals() + self._load_widgets() + + self.show() + + + def _setup_styling(self): + # HORIZONTAL = 0, VERTICAL = 1 + self.set_orientation(self.ORIENTATION) + + + def _setup_signals(self): + ... + + def _load_widgets(self): + ... diff --git a/src/core/widgets/vte_widget.py b/src/core/widgets/vte_widget.py new file mode 100644 index 0000000..d80bea2 --- /dev/null +++ b/src/core/widgets/vte_widget.py @@ -0,0 +1,128 @@ +# Python imports +import os + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +gi.require_version('Vte', '2.91') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib +from gi.repository import Vte + +# Application imports +from libs.dto.event import Event + + + +class VteWidgetException(Exception): + ... + + + +class VteWidget(Vte.Terminal): + """ + https://stackoverflow.com/questions/60454326/how-to-implement-a-linux-terminal-in-a-pygtk-app-like-vscode-and-pycharm-has + """ + + def __init__(self): + super(VteWidget, self).__init__() + + self.cd_cmd_prefix = ("cd".encode(), "cd ".encode()) + self.dont_process = False + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + self._do_session_spawn() + + self.show() + + + def _setup_styling(self): + ctx = self.get_style_context() + ctx.add_class("vte-widget") + + self.set_clear_background(False) + self.set_enable_sixel(True) + self.set_cursor_shape( Vte.CursorShape.IBEAM ) + + def _setup_signals(self): + self.connect("commit", self._commit) + + def _subscribe_to_events(self): + event_system.subscribe("update_term_path", self.update_term_path) + + def _load_widgets(self): + ... + + def _do_session_spawn(self): + self.spawn_sync( + Vte.PtyFlags.DEFAULT, + settings_manager.path_manager.get_home_path(), + ["/bin/bash"], + [], + GLib.SpawnFlags.DEFAULT, + None, None, + ) + + # Note: '-->:' is used as a delimiter to split on to get command actual. + # !!! DO NOT REMOVE UNLESS CODE UPDATED ACCORDINGLY !!! + startup_cmds = [ + "env -i /bin/bash --noprofile --norc\n", + "export TERM='xterm-256color'\n", + "export LC_ALL=C\n", + "export XDG_RUNTIME_DIR='/run/user/1000'\n", + "export DISPLAY=:0\n", + f"export XAUTHORITY='{settings_manager.path_manager.get_home_path()}/.Xauthority'\n", + f"\nexport HOME='{settings_manager.path_manager.get_home_path()}'\n", + "export PS1='\\h@\\u \\W -->: '\n", + "clear\n" + ] + + for i in startup_cmds: + self.run_command(i) + + def _commit(self, terminal, text, size): + if self.dont_process: + self.dont_process = False + return + + if not text.encode() == "\r".encode(): return + + text, attributes = self.get_text() + + if not text: return + + lines = text.strip().splitlines() + command_ran = None + + try: + command_ran = lines[-1].split("-->:")[1].strip() + except VteWidgetException as e: + logger.debug(e) + return + + if not command_ran[0:3].encode() in self.cd_cmd_prefix: + return + + target_path = command_ran.split( command_ran[0:3] )[1] + if target_path in (".", "./"): return + + if not target_path: + target_path = settings_manager.get_home_path() + + event = Event("pty_path_updated", "", target_path) + event_system.emit("handle_bridge_event", (event,)) + + def update_term_path(self, fpath: str): + self.dont_process = True + + cmds = [f"cd '{fpath}'\n", "clear\n"] + for cmd in cmds: + self.run_command(cmd) + + def run_command(self, cmd: str): + self.feed_child_binary(bytes(cmd, 'utf8')) \ No newline at end of file diff --git a/src/core/widgets/webkit/__init__.py b/src/core/widgets/webkit/__init__.py new file mode 100644 index 0000000..1b77b51 --- /dev/null +++ b/src/core/widgets/webkit/__init__.py @@ -0,0 +1,3 @@ +""" + WebKit2 UI Package +""" \ No newline at end of file diff --git a/src/core/widgets/webkit/webkit_ui.py b/src/core/widgets/webkit/webkit_ui.py new file mode 100644 index 0000000..263e491 --- /dev/null +++ b/src/core/widgets/webkit/webkit_ui.py @@ -0,0 +1,69 @@ +# Python imports +import json + +# Lib imports +import gi +gi.require_version('Gdk', '3.0') +gi.require_version('WebKit2', '4.0') +from gi.repository import Gdk +from gi.repository import WebKit2 + +# Application imports +from libs.settings.other.webkit_ui_settings import WebkitUISettings +from libs.dto.event import Event + + +class WebkitUI(WebKit2.WebView): + def __init__(self): + super(WebkitUI, self).__init__() + + self._setup_styling() + self._subscribe_to_events() + self._load_view() + self._setup_content_manager() + + self.show_all() + + + def _setup_styling(self): + self.set_vexpand(True) + self.set_hexpand(True) + self.set_background_color( Gdk.RGBA(0, 0, 0, 0.0) ) + + def _subscribe_to_events(self): + event_system.subscribe(f"ui-message", self.ui_message) + + def _load_settings(self): + self.set_settings( WebkitUISettings() ) + + def _load_view(self): + path = settings_manager.get_context_path() + data = None + + with open(f"{path}/index.html", "r") as f: + data = f.read() + + self.load_html(content = data, base_uri = f"file://{path}/") + + def _setup_content_manager(self): + content_manager = self.get_user_content_manager() + content_manager.connect("script-message-received", self._process_js_message) + content_manager.register_script_message_handler("backend") + + def _process_js_message(self, user_content_manager, js_result): + js_value = js_result.get_js_value() + message = js_value.to_string() + + try: + event = Event( **json.loads(message) ) + event_system.emit("handle-bridge-event", (event,)) + except Exception as e: + logger.info(e) + + def ui_message(self, message, mtype): + command = f"displayMessage('{message}', '{mtype}', '3')" + self.run_javascript(command, None, None) + + def run_javascript(self, script, cancellable, callback): + logger.debug(script) + super().run_javascript(script, cancellable, callback) diff --git a/src/core/window.py b/src/core/window.py new file mode 100644 index 0000000..3a9f914 --- /dev/null +++ b/src/core/window.py @@ -0,0 +1,200 @@ +# Python imports +import signal + +# Lib imports +import gi +import cairo +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GLib + +try: + from gi.repository import GdkX11 +except ImportError: + logger.debug("Could not import X11 gir module...") + +# Application imports +from libs.status_icon import StatusIcon +from core.controllers.base_controller import BaseController + + + +class ControllerStartExceptiom(Exception): + ... + + + +class Window(Gtk.ApplicationWindow): + """ docstring for Window. """ + + def __init__(self): + super(Window, self).__init__() + settings_manager.set_main_window(self) + + self._status_icon = None + self._controller = None + + self.guake_key = settings_manager.get_guake_key() + self.hidefunc = None + + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + self._set_window_data() + self._set_size_constraints() + self._setup_window_toggle_event() + + self.show() + + + def _setup_styling(self): + self.set_title(f"{APP_NAME}") + self.set_icon_from_file( settings_manager.path_manager.get_window_icon() ) + self.set_decorated(True) + self.set_skip_pager_hint(False) + self.set_skip_taskbar_hint(False) + self.set_gravity(5) # 5 = CENTER + self.set_position(1) # 1 = CENTER, 4 = CENTER_ALWAYS + + ctx = self.get_style_context() + ctx.add_class("main-window") + ctx.add_class(f"mw_transparency_{settings_manager.settings.theming.transparency}") + + def _setup_signals(self): + self.connect("focus-in-event", self._on_focus_in_event) + self.connect("focus-out-event", self._on_focus_out_event) + + self.connect("delete-event", self.stop) + GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT, self.stop) + + def _subscribe_to_events(self): + event_system.subscribe("tear-down", self.stop) + event_system.subscribe("load-interactive-debug", self._load_interactive_debug) + + def _load_widgets(self): + if settings_manager.is_debug(): + self.set_interactive_debugging(True) + + self._controller = BaseController() + self._status_icon = StatusIcon() + if not self._controller: + raise ControllerStartException("BaseController exited and doesn't exist...") + + self.add( self._controller.get_base_container() ) + + def _display_manager(self): + """ Try to detect which display manager we are running under... """ + + import os + if os.environ.get('WAYLAND_DISPLAY'): + return 'WAYLAND' + + return 'X11' + + def _set_size_constraints(self): + _window_x = settings_manager.settings.config.main_window_x + _window_y = settings_manager.settings.config.main_window_y + _min_width = settings_manager.settings.config.main_window_min_width + _min_height = settings_manager.settings.config.main_window_min_height + _width = settings_manager.settings.config.main_window_width + _height = settings_manager.settings.config.main_window_height + + self.move(_window_x, _window_y - 28) + self.set_size_request(_min_width, _min_height) + self.set_default_size(_width, _height) + + def _set_window_data(self) -> None: + screen = self.get_screen() + visual = screen.get_rgba_visual() + + if visual and screen.is_composited() and settings_manager.settings.config.make_transparent == 0: + self.set_visual(visual) + self.set_app_paintable(True) + # self.connect("draw", self._area_draw) + + # bind css file + cssProvider = Gtk.CssProvider() + styleContext = Gtk.StyleContext() + cssProvider.load_from_path( settings_manager.path_manager.get_css_file() ) + styleContext.add_provider_for_screen(screen, cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_USER) + + def _area_draw(self, widget: Gtk.ApplicationWindow, cr: cairo.Context) -> None: + cr.set_source_rgba( *settings_manager.get_paint_bg_color() ) + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.paint() + cr.set_operator(cairo.OPERATOR_OVER) + + + def _on_focus_in_event(self, widget, event): + event_system.emit("pause-dnd-signals") + + def _on_focus_out_event(self, widget, event): + event_system.emit("listen-dnd-signals") + + def _load_interactive_debug(self): + self.set_interactive_debugging(True) + + def _setup_window_toggle_event(self) -> None: + hidebound = None + if not self.guake_key or not self._display_manager() == 'X11': + return + + try: + import gi + gi.require_version('Keybinder', '3.0') + from gi.repository import Keybinder + + Keybinder.init() + Keybinder.set_use_cooked_accelerators(False) + except (ImportError, ValueError) as e: + logger.warning(e) + logger.warning('Unable to load Keybinder module. This means the hide_window shortcut will be unavailable') + + return + + # Attempt to grab a global hotkey for hiding the window. + # If we fail, we'll never hide the window, iconifying instead. + try: + hidebound = Keybinder.bind(self.guake_key, self._on_toggle_window, self) + except (KeyError, NameError) as e: + logger.warning(e) + + if not hidebound: + logger.debug('Unable to bind hide_window key, another instance/window has it.') + self.hidefunc = self.iconify + else: + self.hidefunc = self.hide + + def _on_toggle_window(self, data, window): + """Handle a request to hide/show the window""" + if not window.get_property('visible'): + window.show() + # Note: Needed to properly grab widget focus when set_skip_taskbar_hint set to True + window.present() + # NOTE: Need here to enforce sticky after hide and reshow. + window.stick() + else: + self.hidefunc() + + + def start(self): + Gtk.main() + + def stop(self, widget = None, eve = None): + event_system.emit("shutting-down") + + size = self.get_size() + pos = self.get_position() + + settings_manager.set_main_window_width(size.width) + settings_manager.set_main_window_height(size.height) + settings_manager.set_main_window_x(pos.root_x) + settings_manager.set_main_window_y(pos.root_y) + settings_manager.save_settings() + + settings_manager.clear_pid() + Gtk.main_quit() diff --git a/src/libs/__init__.py b/src/libs/__init__.py new file mode 100644 index 0000000..620f163 --- /dev/null +++ b/src/libs/__init__.py @@ -0,0 +1,3 @@ +""" + Libs Package +""" \ No newline at end of file diff --git a/src/libs/db/__init__.py b/src/libs/db/__init__.py new file mode 100644 index 0000000..d20f589 --- /dev/null +++ b/src/libs/db/__init__.py @@ -0,0 +1,6 @@ +""" + DB Package +""" + +from .models import User +from .db import DB \ No newline at end of file diff --git a/src/libs/db/db.py b/src/libs/db/db.py new file mode 100644 index 0000000..b2b22ce --- /dev/null +++ b/src/libs/db/db.py @@ -0,0 +1,42 @@ +# Python imports +from typing import Optional +from os import path + +# Lib imports +from sqlmodel import Session, create_engine + +# Application imports +from .models import SQLModel, User + + + +class DB: + def __init__(self): + super(DB, self).__init__() + + self.engine = None + + self.create_engine() + + + def create_engine(self): + db_path = f"sqlite:///{settings_manager.get_home_config_path()}/database.db" + self.engine = create_engine(db_path) + + SQLModel.metadata.create_all(self.engine) + + def _add_entry(self, entry): + with Session(self.engine) as session: + session.add(entry) + session.commit() + + + def add_user_entry(self, name = None, password = None, email = None): + if not name or not password or not email: return + + user = User() + user.name = name + user.password = password + user.email = email + + self._add_entry(user) diff --git a/src/libs/db/models.py b/src/libs/db/models.py new file mode 100644 index 0000000..4ce4007 --- /dev/null +++ b/src/libs/db/models.py @@ -0,0 +1,15 @@ +# Python imports +from typing import Optional + +# Lib imports +from sqlmodel import SQLModel, Field + +# Application imports + + + +class User(SQLModel, table = True): + id: Optional[int] = Field(default = None, primary_key = True) + name: str + password: str + email: Optional[str] = None diff --git a/src/libs/debugging.py b/src/libs/debugging.py new file mode 100644 index 0000000..5eaa286 --- /dev/null +++ b/src/libs/debugging.py @@ -0,0 +1,60 @@ +# Python imports + +# Lib imports + +# Application imports + + + +# Break into a Python console upon SIGUSR1 (Linux) or SIGBREAK (Windows: +# CTRL+Pause/Break). To be included in all production code, just in case. +def debug_signal_handler(signal, frame): + del signal + del frame + + try: + import rpdb2 + logger.debug("\n\nStarting embedded RPDB2 debugger. Password is 'foobar'\n\n") + rpdb2.start_embedded_debugger("foobar", True, True) + rpdb2.setbreak(depth=1) + return + except Exception: + ... + + try: + from rfoo.utils import rconsole + logger.debug("\n\nStarting embedded rconsole debugger...\n\n") + rconsole.spawn_server() + return + except Exception as ex: + ... + + try: + from pudb import set_trace + logger.debug("\n\nStarting PuDB debugger...\n\n") + set_trace(paused = True) + return + except Exception as ex: + ... + + try: + import ipdb + logger.debug("\n\nStarting IPDB debugger...\n\n") + ipdb.set_trace() + return + except Exception as ex: + ... + + try: + import pdb + logger.debug("\n\nStarting embedded PDB debugger...\n\n") + pdb.Pdb(skip=['gi.*']).set_trace() + return + except Exception as ex: + ... + + try: + import code + code.interact() + except Exception as ex: + logger.debug(f"{ex}, returning to normal program flow...") \ No newline at end of file diff --git a/src/libs/dto/__init__.py b/src/libs/dto/__init__.py new file mode 100644 index 0000000..8c55071 --- /dev/null +++ b/src/libs/dto/__init__.py @@ -0,0 +1,5 @@ +""" + Dasta Class Package +""" + +from .event import Event \ No newline at end of file diff --git a/src/libs/dto/code_event.py b/src/libs/dto/code_event.py new file mode 100644 index 0000000..0e87976 --- /dev/null +++ b/src/libs/dto/code_event.py @@ -0,0 +1,18 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports +from .observable_event import ObservableEvent + + + +@dataclass +class CodeEvent(ObservableEvent): + etype: str = "" + ignore_focus: bool = False + view: any = None + file: any = None + next_file: any = None + buffer: any = None \ No newline at end of file diff --git a/src/libs/dto/event.py b/src/libs/dto/event.py new file mode 100644 index 0000000..847beb5 --- /dev/null +++ b/src/libs/dto/event.py @@ -0,0 +1,14 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports + + + +@dataclass +class Event: + topic: str + content: str + raw_content: str \ No newline at end of file diff --git a/src/libs/dto/observable_event.py b/src/libs/dto/observable_event.py new file mode 100644 index 0000000..1a51caa --- /dev/null +++ b/src/libs/dto/observable_event.py @@ -0,0 +1,10 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class ObservableEvent: + ... \ No newline at end of file diff --git a/src/libs/endpoint_registry.py b/src/libs/endpoint_registry.py new file mode 100644 index 0000000..86e4295 --- /dev/null +++ b/src/libs/endpoint_registry.py @@ -0,0 +1,22 @@ +# Python imports + +# Lib imports + +# Application imports +from .singleton import Singleton + + + +class EndpointRegistry(Singleton): + def __init__(self): + self._endpoints = {} + + def register(self, rule, **options): + def decorator(f): + self._endpoints[rule] = f + return f + + return decorator + + def get_endpoints(self): + return self._endpoints diff --git a/src/libs/event_system.py b/src/libs/event_system.py new file mode 100644 index 0000000..cd6975f --- /dev/null +++ b/src/libs/event_system.py @@ -0,0 +1,73 @@ +# Python imports +from collections import defaultdict + +# Lib imports + +# Application imports +from .singleton import Singleton + + + +class EventSystem(Singleton): + """ Create event system. """ + + def __init__(self): + self.subscribers = defaultdict(list) + self._is_paused = False + + self._subscribe_to_events() + + + def _subscribe_to_events(self): + self.subscribe("pause_event_processing", self._pause_processing_events) + self.subscribe("resume_event_processing", self._resume_processing_events) + + def _pause_processing_events(self): + self._is_paused = True + + def _resume_processing_events(self): + self._is_paused = False + + def subscribe(self, event_type, fn): + self.subscribers[event_type].append(fn) + + def unsubscribe(self, event_type, fn): + self.subscribers[event_type].remove(fn) + + def unsubscribe_all(self, event_type): + self.subscribers.pop(event_type, None) + + def emit(self, event_type, data = None): + if self._is_paused and event_type != "resume_event_processing": + return + + if event_type in self.subscribers: + for fn in self.subscribers[event_type]: + if data: + if hasattr(data, '__iter__') and not type(data) is str: + fn(*data) + else: + fn(data) + else: + fn() + + def emit_and_await(self, event_type, data = None): + if self._is_paused and event_type != "resume_event_processing": + return + + """ NOTE: Should be used when signal has only one listener and vis-a-vis """ + if event_type in self.subscribers: + response = None + for fn in self.subscribers[event_type]: + if data: + if hasattr(data, '__iter__') and not type(data) is str: + response = fn(*data) + else: + response = fn(data) + else: + response = fn() + + if not response in (None, ''): + break + + return response diff --git a/src/libs/ipc_server.py b/src/libs/ipc_server.py new file mode 100644 index 0000000..0ee8e8f --- /dev/null +++ b/src/libs/ipc_server.py @@ -0,0 +1,148 @@ +# Python imports +import os +import threading +import time +from contextlib import suppress +from multiprocessing.connection import Client +from multiprocessing.connection import Listener + +# Lib imports + +# Application imports +from .singleton import Singleton + + + +class IPCServer(Singleton): + """ Create a listener so that other {APP_NAME} instances send requests back to existing instance. """ + def __init__(self, ipc_address: str = '127.0.0.1', conn_type: str = "socket"): + self.is_ipc_alive = False + self._ipc_port = 0 # Use 0 to let Listener chose port + self._ipc_address = ipc_address + self._conn_type = conn_type + self._ipc_authkey = b'' + bytes(f'{APP_NAME}-ipc', 'utf-8') + self._ipc_timeout = 15.0 + + if conn_type == "socket": + self._ipc_address = f'/tmp/{APP_NAME}-ipc.sock' + elif conn_type == "full_network": + self._ipc_address = '0.0.0.0' + elif conn_type == "full_network_unsecured": + self._ipc_authkey = None + self._ipc_address = '0.0.0.0' + elif conn_type == "local_network_unsecured": + self._ipc_authkey = None + + self._subscribe_to_events() + + def _subscribe_to_events(self): + event_system.subscribe("post-file-to-ipc", self.send_ipc_message) + + + def create_ipc_listener(self) -> None: + if self._conn_type == "socket": + if settings_manager.is_dirty_start(): + with suppress(FileNotFoundError, PermissionError): + os.unlink(self._ipc_address) + + listener = Listener(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + listener = Listener((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + listener = Listener((self._ipc_address, self._ipc_port)) + + + self.is_ipc_alive = True + self._run_ipc_loop(listener) + + @daemon_threaded + def _run_ipc_loop(self, listener) -> None: + # NOTE: Not thread safe if using with Gtk. Need to import GLib and use idle_add + while self.is_ipc_alive: + try: + conn = listener.accept() + start_time = time.perf_counter() + self._handle_ipc_message(conn, start_time) + except EOFError as e: + logger.debug( repr(e) ) + except (OSError, ConnectionError, BrokenPipeError) as e: + logger.debug( f"IPC connection error: {e}" ) + except Exception as e: + logger.debug( f"Unexpected IPC error: {e}" ) + finally: + conn.close() + + listener.close() + + def _handle_ipc_message(self, conn, start_time) -> None: + while self.is_ipc_alive: + msg = conn.recv() + logger.debug(msg) + + if "FILE|" in msg: + file = msg.split("FILE|")[1].strip() + if file: + event_system.emit("handle-file-from-ipc", file) + + conn.close() + break + + if "DIR|" in msg: + file = msg.split("DIR|")[1].strip() + if file: + event_system.emit("handle-dir-from-ipc", file) + + conn.close() + break + + + if msg in ['close connection', 'close server', 'Empty Data...']: + conn.close() + break + + # NOTE: Not perfect but insures we don't lock up the connection for too long. + end_time = time.perf_counter() + if (end_time - start_time) > self._ipc_timeout: + conn.close() + break + + + def send_ipc_message(self, message: str = "Empty Data...") -> None: + try: + if self._conn_type == "socket": + conn = Client(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + conn = Client((self._ipc_address, self._ipc_port)) + + conn.send(message) + conn.close() + except ConnectionRefusedError as e: + logger.error("Connection refused...") + except (OSError, ConnectionError, BrokenPipeError) as e: + logger.error( f"IPC connection error: {e}" ) + except Exception as e: + logger.error( f"Unexpected IPC error: {e}" ) + + + def send_test_ipc_message(self, message: str = "Empty Data...") -> None: + try: + if self._conn_type == "socket": + conn = Client(address=self._ipc_address, family="AF_UNIX", authkey=self._ipc_authkey) + elif "unsecured" not in self._conn_type: + conn = Client((self._ipc_address, self._ipc_port), authkey=self._ipc_authkey) + else: + conn = Client((self._ipc_address, self._ipc_port)) + + conn.send(message) + conn.close() + except ConnectionRefusedError as e: + if self._conn_type == "socket": + logger.error("IPC Socket no longer valid.... Removing.") + with suppress(FileNotFoundError, PermissionError): + os.unlink(self._ipc_address) + except (OSError, ConnectionError, BrokenPipeError) as e: + logger.error( f"IPC connection error: {e}" ) + except Exception as e: + logger.error( f"Unexpected IPC error: {e}" ) \ No newline at end of file diff --git a/src/libs/keybindings.py b/src/libs/keybindings.py new file mode 100644 index 0000000..0437b72 --- /dev/null +++ b/src/libs/keybindings.py @@ -0,0 +1,138 @@ +# Python imports +import re + +# Lib imports +import gi +gi.require_version('Gdk', '3.0') +from gi.repository import Gdk + +# Application imports +from .singleton import Singleton + + + +def logger(log = ""): + print(log) + + +class KeymapError(Exception): + """ Custom exception for errors in keybinding configurations """ + +MODIFIER = re.compile('<([^<]+)>') +class Keybindings(Singleton): + """ Class to handle loading and lookup of Terminator keybindings """ + + modifiers = { + 'ctrl': Gdk.ModifierType.CONTROL_MASK, + 'control': Gdk.ModifierType.CONTROL_MASK, + 'primary': Gdk.ModifierType.CONTROL_MASK, + 'shift': Gdk.ModifierType.SHIFT_MASK, + 'alt': Gdk.ModifierType.MOD1_MASK, + 'super': Gdk.ModifierType.SUPER_MASK, + 'hyper': Gdk.ModifierType.HYPER_MASK, + 'mod2': Gdk.ModifierType.MOD2_MASK + } + + empty = {} + keys = None + _masks = None + _lookup = None + + def __init__(self): + self.keymap = Gdk.Keymap.get_default() + self.configure({}) + + def print_keys(self): + print(self.keys) + + def append_bindings(self, combos): + """ Accept new binding(s) and reload """ + for item in combos: + method, keys = item.split(":") + self.keys[method] = keys + + self.reload() + + def configure(self, bindings): + """ Accept new bindings and reconfigure with them """ + self.keys = bindings + self.reload() + + def reload(self): + """ Parse bindings and mangle into an appropriate form """ + self._lookup = {} + self._masks = 0 + + for action, bindings in list(self.keys.items()): + if isinstance(bindings, list): + bindings = (*bindings,) + elif not isinstance(bindings, tuple): + bindings = (bindings,) + + + for binding in bindings: + if not binding or binding == "None": + continue + + try: + keyval, mask = self._parsebinding(binding) + # Does much the same, but with worse error handling. + # keyval, mask = Gtk.accelerator_parse(binding) + except KeymapError as e: + logger(f"Keybinding reload failed to parse binding '{binding}': {e}") + else: + if mask & Gdk.ModifierType.SHIFT_MASK: + if keyval == Gdk.KEY_Tab: + keyval = Gdk.KEY_ISO_Left_Tab + mask &= ~Gdk.ModifierType.SHIFT_MASK + else: + keyvals = Gdk.keyval_convert_case(keyval) + if keyvals[0] != keyvals[1]: + keyval = keyvals[1] + mask &= ~Gdk.ModifierType.SHIFT_MASK + else: + keyval = Gdk.keyval_to_lower(keyval) + + self._lookup.setdefault(mask, {}) + self._lookup[mask][keyval] = action + self._masks |= mask + + def _parsebinding(self, binding): + """ Parse an individual binding using Gtk's binding function """ + mask = 0 + modifiers = re.findall(MODIFIER, binding) + + if modifiers: + for modifier in modifiers: + mask |= self._lookup_modifier(modifier) + + key = re.sub(MODIFIER, '', binding) + if key == '': + raise KeymapError('No key found!') + + keyval = Gdk.keyval_from_name(key) + + if keyval == 0: + raise KeymapError(f"Key '{key}' is unrecognised...") + return (keyval, mask) + + def _lookup_modifier(self, modifier): + """ Map modifier names to gtk values """ + try: + return self.modifiers[modifier.lower()] + except KeyError: + raise KeymapError(f"Unhandled modifier '<{modifier}>'") + + def lookup(self, event): + """ Translate a keyboard event into a mapped key """ + try: + _found, keyval, _egp, _lvl, consumed = self.keymap.translate_keyboard_state( + event.hardware_keycode, + Gdk.ModifierType(event.get_state() & ~Gdk.ModifierType.LOCK_MASK), + event.group) + except TypeError: + logger(f"Keybinding lookup failed to translate keyboard event: {dir(event)}") + return None + + mask = (event.get_state() & ~consumed) & self._masks + return self._lookup.get(mask, self.empty).get(keyval, None) diff --git a/src/libs/logger.py b/src/libs/logger.py new file mode 100644 index 0000000..10e93c4 --- /dev/null +++ b/src/libs/logger.py @@ -0,0 +1,61 @@ +# Python imports +import os +import logging + +# Lib imports + +# Application imports +from .singleton import Singleton + + + +class Logger(Singleton): + """ + Create a new logging object and return it. + :note: + NOSET # Don't know the actual log level of this... (defaulting or literally none?) + Log Levels (From least to most) + Type Value + CRITICAL 50 + ERROR 40 + WARNING 30 + INFO 20 + DEBUG 10 + :param loggerName: Sets the name of the logger object. (Used in log lines) + :param createFile: Whether we create a log file or just pump to terminal + + :return: the logging object we created + """ + + def __init__(self, config_path: str, _ch_log_lvl = logging.CRITICAL, _fh_log_lvl = logging.INFO): + self._CONFIG_PATH = config_path + self.global_lvl = logging.DEBUG # Keep this at highest so that handlers can filter to their desired levels + self.ch_log_lvl = _ch_log_lvl # Prety much the only one we ever change + self.fh_log_lvl = _fh_log_lvl + + def get_logger(self, loggerName: str = "NO_LOGGER_NAME_PASSED", createFile: bool = True) -> logging.Logger: + log = logging.getLogger(loggerName) + log.setLevel(self.global_lvl) + + # Set our log output styles + fFormatter = logging.Formatter('[%(asctime)s] %(pathname)s:%(lineno)d %(levelname)s - %(message)s', '%m-%d %H:%M:%S') + cFormatter = logging.Formatter('%(pathname)s:%(lineno)d] %(levelname)s - %(message)s') + + ch = logging.StreamHandler() + ch.setLevel(level=self.ch_log_lvl) + ch.setFormatter(cFormatter) + log.addHandler(ch) + + if createFile: + folder = self._CONFIG_PATH + file = f"{folder}/application.log" + + if not os.path.exists(folder): + os.mkdir(folder) + + fh = logging.FileHandler(file) + fh.setLevel(level=self.fh_log_lvl) + fh.setFormatter(fFormatter) + log.addHandler(fh) + + return log diff --git a/src/libs/mixins/__init__.py b/src/libs/mixins/__init__.py new file mode 100644 index 0000000..e852849 --- /dev/null +++ b/src/libs/mixins/__init__.py @@ -0,0 +1,3 @@ +""" + Libs.Mixins Package +""" \ No newline at end of file diff --git a/src/libs/mixins/dnd_mixin.py b/src/libs/mixins/dnd_mixin.py new file mode 100644 index 0000000..4e231d3 --- /dev/null +++ b/src/libs/mixins/dnd_mixin.py @@ -0,0 +1,70 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import Gio + +# Application imports + + + +class DnDMixin: + + def _setup_dnd(self): + flags = Gtk.DestDefaults.ALL + + PLAIN_TEXT_TARGET_TYPE = 70 + URI_TARGET_TYPE = 80 + + text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE) + uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE) + + # targets = [ text_target, uri_target ] + targets = [ uri_target ] + + action = Gdk.DragAction.COPY + + # self.drag_dest_set_target_list(targets) + self.drag_dest_set(flags, targets, action) + + self._setup_dnd_signals() + + def _setup_dnd_signals(self): + # self.connect("drag-motion", self._on_drag_motion) + # self.connect('drag-drop', self._on_drag_set) + self.connect("drag-data-received", self._on_drag_data_received) + + def _on_drag_motion(self, widget, drag_context, x, y, time): + Gdk.drag_status(drag_context, drag_context.get_actions(), time) + + return False + + def _on_drag_set(self, widget, drag_context, data, info, time): + self.drag_get_data(drag_context, drag_context.list_targets()[-1], time) + + return False + + def _on_drag_data_received(self, widget, drag_context, x, y, data, info, time): + if info == 70: return + + if info == 80: + uris = data.get_uris() + files = [] + + if len(uris) == 0: + uris = data.get_text().split("\n") + + for uri in uris: + gfile = None + try: + gfile = Gio.File.new_for_uri(uri) + except Exception as e: + gfile = Gio.File.new_for_path(uri) + + files.append(gfile) + + event_system.emit('set-pre-drop-dnd', (files,)) \ No newline at end of file diff --git a/src/libs/mixins/ipc_signals_mixin.py b/src/libs/mixins/ipc_signals_mixin.py new file mode 100644 index 0000000..880266d --- /dev/null +++ b/src/libs/mixins/ipc_signals_mixin.py @@ -0,0 +1,31 @@ +# Python imports + +# Lib imports +import gi +from gi.repository import GLib + +# Application imports + + + + +class IPCSignalsMixin: + """ IPCSignalsMixin handle messages from another starting {APP_NAME} process. """ + + def print_to_console(self, message = None): + logger.debug(message) + + def handle_file_from_ipc(self, fpath: str) -> None: + logger.debug(f"File From IPC: {fpath}") + GLib.idle_add( + self.broadcast_message, "handle-file", (fpath,) + ) + + def handle_dir_from_ipc(self, fpath: str) -> None: + logger.debug(f"Dir From IPC: {fpath}") + GLib.idle_add( + self.broadcast_message, "handle-folder", (fpath,) + ) + + def broadcast_message(self, message_type: str = "none", data: () = ()) -> None: + event_system.emit(message_type, data) \ No newline at end of file diff --git a/src/libs/mixins/keyboard_signals_mixin.py b/src/libs/mixins/keyboard_signals_mixin.py new file mode 100644 index 0000000..03446d0 --- /dev/null +++ b/src/libs/mixins/keyboard_signals_mixin.py @@ -0,0 +1,96 @@ +# Python imports +import re + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') +from gi.repository import Gtk +from gi.repository import Gdk + +# Application imports + + + +valid_keyvalue_pat = re.compile(r"[a-z0-9A-Z-_\[\]\(\)\| ]") + + + +class KeyboardSignalsMixin: + """ KeyboardSignalsMixin keyboard hooks controller. """ + + # TODO: Need to set methods that use this to somehow check the keybindings state instead. + def unset_keys_and_data(self, widget = None, eve = None): + self.ctrl_down = False + self.shift_down = False + self.alt_down = False + + def unmap_special_keys(self, keyname): + if "control" in keyname: + self.ctrl_down = False + if "shift" in keyname: + self.shift_down = False + if "alt" in keyname: + self.alt_down = False + + def on_global_key_press_controller(self, eve, user_data): + keyname = Gdk.keyval_name(user_data.keyval).lower() + modifiers = Gdk.ModifierType(user_data.get_state() & ~Gdk.ModifierType.LOCK_MASK) + + self.was_midified_key = True if modifiers != 0 else False + + if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]: + if "control" in keyname: + self.ctrl_down = True + if "shift" in keyname: + self.shift_down = True + if "alt" in keyname: + self.alt_down = True + + def on_global_key_release_controller(self, widget, event): + """ Handler for keyboard events """ + keyname = Gdk.keyval_name(event.keyval).lower() + modifiers = Gdk.ModifierType(event.get_state() & ~Gdk.ModifierType.LOCK_MASK) + + if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]: + should_return = self.was_midified_key and (self.ctrl_down or self.shift_down or self.alt_down) + self.unmap_special_keys(keyname) + + if should_return: + self.was_midified_key = False + return + + mapping = keybindings.lookup(event) + logger.debug(f"on_global_key_release_controller > key > {keyname}") + logger.debug(f"on_global_key_release_controller > keyval > {event.keyval}") + logger.debug(f"on_global_key_release_controller > mapping > {mapping}") + + if mapping: + self.handle_mapped_key_event(mapping) + else: + self.handle_as_key_event_scope(keyname) + + def handle_mapped_key_event(self, mapping): + try: + self.handle_as_controller_scope(mapping) + except Exception: + self.handle_as_plugin_scope(mapping) + + def handle_as_controller_scope(self, mapping): + getattr(self, mapping)() + + def handle_as_plugin_scope(self, mapping): + if "||" in mapping: + sender, eve_type = mapping.split("||") + else: + sender = "" + eve_type = mapping + + self.handle_key_event_system(sender, eve_type) + + def handle_as_key_event_scope(self, keyname): + if self.ctrl_down and not keyname in ["1", "kp_1", "2", "kp_2", "3", "kp_3", "4", "kp_4"]: + self.handle_key_event_system(None, keyname) + + def handle_key_event_system(self, sender, eve_type): + event_system.emit(eve_type) \ No newline at end of file diff --git a/src/libs/mixins/observable_mixin.py b/src/libs/mixins/observable_mixin.py new file mode 100644 index 0000000..64207e5 --- /dev/null +++ b/src/libs/mixins/observable_mixin.py @@ -0,0 +1,26 @@ +# Python imports + +# Lib imports + +# Application imports +from ..dto.observable_event import ObservableEvent + + + +class ObservableMixin: + observers = [] + + def add_observer(self, observer: any): + if not hasattr(observer, 'notification') or not callable(getattr(observer, 'notification')): + raise ValueError(f"Observer '{observer}' must implement a `notification` method.") + + self.observers.append(observer) + + def remove_observer(self, observer: any): + if not observer in self.observers: return + + self.observers.remove(observer) + + def notify_observers(self, event: ObservableEvent): + for observer in self.observers: + observer.notification(event) \ No newline at end of file diff --git a/src/libs/settings/__init__.py b/src/libs/settings/__init__.py new file mode 100644 index 0000000..228a75d --- /dev/null +++ b/src/libs/settings/__init__.py @@ -0,0 +1,4 @@ +""" + Settings Package +""" +from .manager import SettingsManager \ No newline at end of file diff --git a/src/libs/settings/manager.py b/src/libs/settings/manager.py new file mode 100644 index 0000000..191f194 --- /dev/null +++ b/src/libs/settings/manager.py @@ -0,0 +1,126 @@ +# Python imports +import inspect +import time + +# Lib imports + +# Application imports +from ..singleton import Singleton +from .start_check_mixin import StartCheckMixin + +from .path_manager import PathManager +from .options.settings import Settings + + + +class SettingsManager(StartCheckMixin, Singleton): + def __init__(self): + self.path_manager: PathManager = PathManager() + self.settings: Settings = None + + self._main_window = None + self._builder = None + + self._trace_debug: bool = False + self._debug: bool = False + self._dirty_start: bool = False + self._passed_in_file: bool = False + self._starting_files: list = [] + + self.PAINT_BG_COLOR: tuple = (0, 0, 0, 0.0) + + self.load_keybindings() + self.load_context_menu_data() + + + def get_monitor_data(self) -> list: + screen = self._main_window.get_screen() + monitors = [] + for m in range(screen.get_n_monitors()): + monitors.append(screen.get_monitor_geometry(m)) + print("{}x{}+{}+{}".format(monitor.width, monitor.height, monitor.x, monitor.y)) + + return monitors + + def get_main_window(self) -> any: return self._main_window + def get_builder(self) -> any: return self._builder + def get_paint_bg_color(self) -> any: return self.PAINT_BG_COLOR + def get_context_menu_data(self) -> str: return self._context_menu_data + + def get_icon_theme(self) -> str: return self._ICON_THEME + def get_starting_files(self) -> list: return self._starting_files + def get_guake_key(self) -> tuple: return self._guake_key + + def get_starting_args(self): + return self.args, self.unknownargs + + def set_main_window(self, window): self._main_window = window + def set_builder(self, builder) -> any: self._builder = builder + + def set_main_window_x(self, x: int = 0): self.settings.config.main_window_x = x + def set_main_window_y(self, y: int = 0): self.settings.config.main_window_y = y + def set_main_window_width(self, width: int = 800): self.settings.config.main_window_width = width + def set_main_window_height(self, height: int = 600): self.settings.config.main_window_height = height + def set_main_window_min_width(self, width: int = 720): self.settings.config.main_window_min_width = width + def set_main_window_min_height(self, height: int = 480): self.settings.config.main_window_min_height = height + def set_starting_files(self, files: list): self._starting_files = files + def set_start_load_time(self): self._start_load_time = time.perf_counter() + def set_end_load_time(self): self._end_load_time = time.perf_counter() + + def set_starting_args(self, args, unknownargs): + self.args = args + self.unknownargs = unknownargs + + def set_trace_debug(self, trace_debug: bool): + self._trace_debug = trace_debug + + def set_debug(self, debug: bool): + self._debug = debug + + def set_is_starting_with_file(self, is_passed_in_file: bool = False): + self._passed_in_file = is_passed_in_file + + def is_trace_debug(self) -> str: return self._trace_debug + def is_debug(self) -> str: return self._debug + def is_starting_with_file(self) -> bool: return self._passed_in_file + + def log_load_time(self): logger.info( f"Load Time: {self._end_load_time - self._start_load_time}" ) + + + def register_signals_to_builder(self, classes = None): + handlers = {} + + for c in classes: + methods = None + try: + methods = inspect.getmembers(c, predicate = inspect.ismethod) + handlers.update(methods) + except Exception as e: + ... + + self._builder.connect_signals(handlers) + + def call_method(self, target_class: any = None, _method_name: str = "", data: any = None): + method_name = str(_method_name) + method = getattr(target_class, method_name, lambda data: f"No valid key passed...\nkey={method_name}\nargs={data}") + return method(data) if data else method() + + def load_keybindings(self): + bindings = self.path_manager.load_keybindings() + self._guake_key = bindings["guake_key"] + + keybindings.configure(bindings) + + def load_context_menu_data(self): + self._context_menu_data = self.path_manager.load_context_menu_data() + + def load_settings(self): + data = self.path_manager.load_settings() + if not data: + self.settings = Settings() + return + + self.settings = Settings(**data) + + def save_settings(self): + self.path_manager.save_settings(self.settings) diff --git a/src/libs/settings/options/__init__.py b/src/libs/settings/options/__init__.py new file mode 100644 index 0000000..e06487a --- /dev/null +++ b/src/libs/settings/options/__init__.py @@ -0,0 +1,8 @@ +""" + Settings.Options Package +""" +from .settings import Settings +from .config import Config +from .filters import Filters +from .theming import Theming +from .debugging import Debugging \ No newline at end of file diff --git a/src/libs/settings/options/config.py b/src/libs/settings/options/config.py new file mode 100644 index 0000000..4b4ee23 --- /dev/null +++ b/src/libs/settings/options/config.py @@ -0,0 +1,39 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports + + +@dataclass +class Config: + base_of_home: str = "" + hide_hidden_files: str = "true" + thumbnailer_path: str = "ffmpegthumbnailer" + blender_thumbnailer_path: str = "" + go_past_home: str = "true" + lock_folder: str = "false" + locked_folders: list = field(default_factory=lambda: [ "venv", "flasks" ]) + mplayer_options: str = "-quiet -really-quiet -xy 1600 -geometry 50%:50%", + music_app: str = "/opt/deadbeef/bin/deadbeef" + media_app: str = "mpv" + image_app: str = "mirage" + office_app: str = "libreoffice" + pdf_app: str = "evince" + code_app: str = "atom" + text_app: str = "leafpad" + file_manager_app: str = "solarfm" + terminal_app: str = "terminator" + remux_folder_max_disk_usage: str = "8589934592" + make_transparent: int = 0 + main_window_x: int = 721 + main_window_y: int = 465 + main_window_min_width: int = 720 + main_window_min_height: int = 480 + main_window_width: int = 800 + main_window_height: int = 600 + application_dirs: list = field(default_factory=lambda: [ + "/usr/share/applications", + f"{settings_manager.get_home_path()}/.local/share/applications" + ]) diff --git a/src/libs/settings/options/debugging.py b/src/libs/settings/options/debugging.py new file mode 100644 index 0000000..3fc605d --- /dev/null +++ b/src/libs/settings/options/debugging.py @@ -0,0 +1,12 @@ +# Python imports +from dataclasses import dataclass + +# Lib imports + +# Application imports + + +@dataclass +class Debugging: + ch_log_lvl: int = 10 + fh_log_lvl: int = 20 diff --git a/src/libs/settings/options/filters.py b/src/libs/settings/options/filters.py new file mode 100644 index 0000000..e5293bf --- /dev/null +++ b/src/libs/settings/options/filters.py @@ -0,0 +1,90 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports + + +@dataclass +class Filters: + meshs: list = field(default_factory=lambda: [ + ".blend", + ".dae", + ".fbx", + ".gltf", + ".obj", + ".stl" + ]) + code: list = field(default_factory=lambda: [ + ".cpp", + ".css", + ".c", + ".go", + ".html", + ".htm", + ".java", + ".js", + ".json", + ".lua", + ".md", + ".py", + ".rs", + ".toml", + ".xml", + ".pom" + ]) + videos: list = field(default_factory=lambda:[ + ".mkv", + ".mp4", + ".webm", + ".avi", + ".mov", + ".m4v", + ".mpg", + ".mpeg", + ".wmv", + ".flv" + ]) + office: list = field(default_factory=lambda: [ + ".doc", + ".docx", + ".xls", + ".xlsx", + ".xlt", + ".xltx", + ".xlm", + ".ppt", + ".pptx", + ".pps", + ".ppsx", + ".odt", + ".rtf" + ]) + images: list = field(default_factory=lambda: [ + ".png", + ".jpg", + ".jpeg", + ".gif", + ".ico", + ".tga", + ".webp" + ]) + text: list = field(default_factory=lambda: [ + ".txt", + ".text", + ".sh", + ".cfg", + ".conf", + ".log" + ]) + music: list = field(default_factory=lambda: [ + ".psf", + ".mp3", + ".ogg", + ".flac", + ".m4a" + ]) + pdf: list = field(default_factory=lambda: [ + ".pdf" + ]) diff --git a/src/libs/settings/options/settings.py b/src/libs/settings/options/settings.py new file mode 100644 index 0000000..0e3597b --- /dev/null +++ b/src/libs/settings/options/settings.py @@ -0,0 +1,31 @@ +# Python imports +from dataclasses import dataclass, field +from dataclasses import asdict + +# Gtk imports + +# Application imports +from .config import Config +from .filters import Filters +from .theming import Theming +from .debugging import Debugging + + +@dataclass +class Settings: + load_defaults: bool = True + config: Config = field(default_factory=lambda: Config()) + filters: Filters = field(default_factory=lambda: Filters()) + theming: Theming = field(default_factory=lambda: Theming()) + debugging: Debugging = field(default_factory=lambda: Debugging()) + + def __post_init__(self): + if not self.load_defaults: + self.load_defaults = False + self.config = Config(**self.config) + self.filters = Filters(**self.filters) + self.theming = Theming(**self.theming) + self.debugging = Debugging(**self.debugging) + + def as_dict(self): + return asdict(self) diff --git a/src/libs/settings/options/theming.py b/src/libs/settings/options/theming.py new file mode 100644 index 0000000..c52f50e --- /dev/null +++ b/src/libs/settings/options/theming.py @@ -0,0 +1,16 @@ +# Python imports +from dataclasses import dataclass + +# Lib imports + +# Application imports + + +@dataclass +class Theming: + transparency: int = 64 + default_zoom: int = 12 + syntax_theme: str = "penguins-in-space" + success_color: str = "#88cc27" + warning_color: str = "#ffa800" + error_color: str = "#ff0000" diff --git a/src/libs/settings/other/__init__.py b/src/libs/settings/other/__init__.py new file mode 100644 index 0000000..c38a726 --- /dev/null +++ b/src/libs/settings/other/__init__.py @@ -0,0 +1,3 @@ +""" + Settings.Other Package +""" \ No newline at end of file diff --git a/src/libs/settings/other/webkit_ui_settings.py b/src/libs/settings/other/webkit_ui_settings.py new file mode 100644 index 0000000..981ea49 --- /dev/null +++ b/src/libs/settings/other/webkit_ui_settings.py @@ -0,0 +1,42 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('WebKit2', '4.0') +from gi.repository import WebKit2 + +# Application imports + + + +class WebkitUISettings(WebKit2.Settings): + def __init__(self): + super(WebkitUISettings, self).__init__() + + self._set_default_settings() + + + # Note: Highly insecure setup but most "app" like setup I could think of. + # Audit heavily any scripts/links ran/clicked under this setup! + def _set_default_settings(self): + self.set_enable_xss_auditor(True) + self.set_enable_hyperlink_auditing(True) + # self.set_enable_xss_auditor(False) + # self.set_enable_hyperlink_auditing(False) + self.set_allow_file_access_from_file_urls(True) + self.set_allow_universal_access_from_file_urls(True) + + self.set_enable_page_cache(False) + self.set_enable_offline_web_application_cache(False) + self.set_enable_html5_local_storage(False) + self.set_enable_html5_database(False) + + self.set_enable_fullscreen(False) + self.set_print_backgrounds(False) + self.set_enable_tabs_to_links(False) + self.set_enable_developer_extras(True) + self.set_enable_webrtc(True) + self.set_enable_webaudio(True) + self.set_enable_accelerated_2d_canvas(True) + + self.set_user_agent(f"{APP_NAME}") \ No newline at end of file diff --git a/src/libs/settings/path_manager.py b/src/libs/settings/path_manager.py new file mode 100644 index 0000000..40a07c5 --- /dev/null +++ b/src/libs/settings/path_manager.py @@ -0,0 +1,123 @@ +# Python imports +import json +import zipfile + +from os import path +from os import mkdir + +# Lib imports + +# Application imports + + + +class MissingConfigError(Exception): + pass + + + +class PathManager: + def __init__(self): + self._SCRIPT_PTH: str = path.dirname(path.realpath(__file__)) + self._USER_HOME: str = path.expanduser('~') + self._HOME_CONFIG_PATH: str = f"{self._USER_HOME}/.config/{APP_NAME.lower()}" + self._USR_PATH: str = f"/usr/share/{APP_NAME.lower()}" + self._USR_CONFIG_FILE: str = f"{self._USR_PATH}/settings.json" + + self._CONTEXT_PATH: str = f"{self._HOME_CONFIG_PATH}/context_path" + self._PLUGINS_PATH: str = f"{self._HOME_CONFIG_PATH}/plugins" + self._DEFAULT_ICONS: str = f"{self._HOME_CONFIG_PATH}/icons" + self._CONFIG_FILE: str = f"{self._HOME_CONFIG_PATH}/settings.json" + self._GLADE_FILE: str = f"{self._HOME_CONFIG_PATH}/Main_Window.glade" + self._CSS_FILE: str = f"{self._HOME_CONFIG_PATH}/stylesheet.css" + self._KEY_BINDINGS_FILE: str = f"{self._HOME_CONFIG_PATH}/key-bindings.json" + self._PID_FILE: str = f"{self._HOME_CONFIG_PATH}/{APP_NAME.lower()}.pid" + self._UI_WIDEGTS_PATH: str = f"{self._HOME_CONFIG_PATH}/ui_widgets" + self._CONTEXT_MENU: str = f"{self._HOME_CONFIG_PATH}/contexct_menu.json" + self._WINDOW_ICON: str = f"{self._DEFAULT_ICONS}/{APP_NAME.lower()}.png" + + # self._USR_CONFIG_FILE: str = f"{self._USR_PATH}/settings.json" + # self._PLUGINS_PATH: str = f"plugins" + # self._CONFIG_FILE: str = f"settings.json" + # self._GLADE_FILE: str = f"Main_Window.glade" + # self._CSS_FILE: str = f"stylesheet.css" + # self._KEY_BINDINGS_FILE: str = f"key-bindings.json" + # self._PID_FILE: str = f"{APP_NAME.lower()}.pid" + # self._WINDOW_ICON: str = f"{APP_NAME.lower()}.png" + # self._UI_WIDEGTS_PATH: str = f"ui_widgets" + # self._CONTEXT_MENU: str = f"contexct_menu.json" + # self._DEFAULT_ICONS: str = f"icons" + + + # with zipfile.ZipFile("files.zip", mode="r", allowZip64=True) as zf: + # with io.TextIOWrapper(zf.open("text1.txt"), encoding="utf-8") as f: + + + if not path.exists(self._HOME_CONFIG_PATH): + mkdir(self._HOME_CONFIG_PATH) + if not path.exists(self._PLUGINS_PATH): + mkdir(self._PLUGINS_PATH) + + if not path.exists(self._DEFAULT_ICONS): + self._DEFAULT_ICONS = f"{self._USR_PATH}/icons" + if not path.exists(self._DEFAULT_ICONS): + raise MissingConfigError("Unable to find the application icons directory.") + if not path.exists(self._GLADE_FILE): + self._GLADE_FILE = f"{self._USR_PATH}/Main_Window.glade" + if not path.exists(self._GLADE_FILE): + raise MissingConfigError("Unable to find the application Glade file.") + if not path.exists(self._KEY_BINDINGS_FILE): + self._KEY_BINDINGS_FILE = f"{self._USR_PATH}/key-bindings.json" + if not path.exists(self._KEY_BINDINGS_FILE): + raise MissingConfigError("Unable to find the application Keybindings file.") + if not path.exists(self._CSS_FILE): + self._CSS_FILE = f"{self._USR_PATH}/stylesheet.css" + if not path.exists(self._CSS_FILE): + raise MissingConfigError("Unable to find the application Stylesheet file.") + if not path.exists(self._WINDOW_ICON): + self._WINDOW_ICON = f"{self._USR_PATH}/icons/{APP_NAME.lower()}.png" + if not path.exists(self._WINDOW_ICON): + raise MissingConfigError("Unable to find the application icon.") + if not path.exists(self._UI_WIDEGTS_PATH): + self._UI_WIDEGTS_PATH = f"{self._USR_PATH}/ui_widgets" + if not path.exists(self._CONTEXT_MENU): + self._CONTEXT_MENU = f"{self._USR_PATH}/contexct_menu.json" + + + def get_glade_file(self) -> str: return self._GLADE_FILE + def get_ui_widgets_path(self) -> str: return self._UI_WIDEGTS_PATH + def get_context_path(self) -> str: return self._CONTEXT_PATH + def get_plugins_path(self) -> str: return self._PLUGINS_PATH + def get_css_file(self) -> str: return self._CSS_FILE + def get_home_config_path(self) -> str: return self._HOME_CONFIG_PATH + def get_window_icon(self) -> str: return self._WINDOW_ICON + def get_home_path(self) -> str: return self._USER_HOME + + def load_keybindings(self): + try: + with open(self._KEY_BINDINGS_FILE) as file: + return json.load(file)["keybindings"] + except Exception as e: + print( f"Settings Path Manager: {self._KEY_BINDINGS_FILE}\n\t\t{repr(e)}" ) + return {} + + def load_context_menu_data(self): + try: + with open(self._CONTEXT_MENU) as file: + return json.load(file) + except Exception as e: + print( f"Settings Path Manager: {self._CONTEXT_MENU}\n\t\t{repr(e)}" ) + return {} + + def load_settings(self): + if not path.exists(self._CONFIG_FILE): + return None + + with open(self._CONFIG_FILE) as file: + data = json.load(file) + data["load_defaults"] = False + return data + + def save_settings(self, settings: any): + with open(self._CONFIG_FILE, 'w') as outfile: + json.dump(settings.as_dict(), outfile, separators=(',', ':'), indent=4) \ No newline at end of file diff --git a/src/libs/settings/start_check_mixin.py b/src/libs/settings/start_check_mixin.py new file mode 100644 index 0000000..a15d2b7 --- /dev/null +++ b/src/libs/settings/start_check_mixin.py @@ -0,0 +1,65 @@ +# Python imports +import os +import json +import inspect +from contextlib import suppress + +# Lib imports + +# Application imports + + + + +class StartCheckMixin: + def is_dirty_start(self) -> bool: + return self._dirty_start + + def clear_pid(self): + if not self.is_trace_debug(): + self._clean_pid() + + def do_dirty_start_check(self): + if self.is_trace_debug(): + pid = os.getpid() + self._print_pid(pid) + return + + if os.path.exists(self.path_manager._PID_FILE): + with open(self.path_manager._PID_FILE, "r") as f: + pid = f.readline().strip() + if pid not in ("", None): + if self.is_pid_alive( int(pid) ): + print("PID file exists and PID is alive... Letting downstream errors (sans debug args) handle app closure propigation.") + return + + self._write_new_pid() + + """ Check For the existence of a unix pid. """ + def is_pid_alive(self, pid): + print(f"PID Found: {pid}") + + try: + os.kill(pid, 0) + except OSError: + print(f"{APP_NAME} PID file exists but PID is irrelevant; starting dirty...") + self._dirty_start = True + return False + + return True + + def _write_new_pid(self): + pid = os.getpid() + self._write_pid(pid) + self._print_pid(pid) + + def _print_pid(self, pid): + print(f"{APP_NAME} PID: {pid}") + + def _clean_pid(self): + with suppress(FileNotFoundError, PermissionError): + os.unlink(self.path_manager._PID_FILE) + + def _write_pid(self, pid): + with open(self.path_manager._PID_FILE, "w") as _pid: + _pid.write(f"{pid}") \ No newline at end of file diff --git a/src/libs/singleton.py b/src/libs/singleton.py new file mode 100644 index 0000000..5f791c0 --- /dev/null +++ b/src/libs/singleton.py @@ -0,0 +1,29 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class SingletonError(Exception): + pass + + + +class Singleton: + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is not None: + logger.debug(f"'{cls.__name__}' is a Singleton. Returning instance...") + return cls._instance + + cls._instance = super(Singleton, cls).__new__(cls) + return cls._instance + + def __init__(self): + if self._instance is not None: + return + + super(Singleton, self).__init__() diff --git a/src/libs/singleton_raised.py b/src/libs/singleton_raised.py new file mode 100644 index 0000000..e720553 --- /dev/null +++ b/src/libs/singleton_raised.py @@ -0,0 +1,26 @@ +# Python imports + +# Lib imports + +# Application imports + + + +class SingletonError(Exception): + pass + + + +class SingletonRaised: + _instance = None + + def __new__(cls, *args, **kwargs): + if cls._instance is not None: + raise SingletonError(f"'{cls.__name__}' is a Singleton. Cannot create a new instance...") + + cls._instance = super(Singleton, cls).__new__(cls) + return cls._instance + + def __init__(self): + if cls._instance is not None: + return diff --git a/src/libs/status_icon.py b/src/libs/status_icon.py new file mode 100644 index 0000000..2769a05 --- /dev/null +++ b/src/libs/status_icon.py @@ -0,0 +1,67 @@ +# Python imports + +# Lib imports +import gi +gi.require_version('Gtk', '3.0') +gi.require_version('AppIndicator3', '0.1') +from gi.repository import Gtk +from gi.repository import GLib +from gi.repository import AppIndicator3 + +# Application imports + + + +class StatusIcon(): + """ StatusIcon for Application to go to Status Tray. """ + + def __init__(self): + self._setup_styling() + self._setup_signals() + self._subscribe_to_events() + self._load_widgets() + + + def _setup_styling(self): + ... + + def _setup_signals(self): + ... + + def _subscribe_to_events(self): + ... + + def _load_widgets(self): + status_menu = Gtk.Menu() + icon_theme = Gtk.IconTheme.get_default() + check_menu_item = Gtk.CheckMenuItem.new_with_label("Update icon") + quit_menu_item = Gtk.MenuItem.new_with_label("Quit") + + # Create StatusNotifierItem + self.indicator = AppIndicator3.Indicator.new( + f"{APP_NAME}-statusicon", + "gtk-info", + AppIndicator3.IndicatorCategory.APPLICATION_STATUS) + self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) + + check_menu_item.connect("activate", self.check_menu_item_cb) + quit_menu_item.connect("activate", self.quit_menu_item_cb) + icon_theme.connect('changed', self.icon_theme_changed_cb) + + self.indicator.set_menu(status_menu) + status_menu.append(check_menu_item) + status_menu.append(quit_menu_item) + status_menu.show_all() + + def update_icon(self, icon_name): + self.indicator.set_icon(icon_name) + + def check_menu_item_cb(self, widget, data = None): + icon_name = "parole" if widget.get_active() else "gtk-info" + self.update_icon(icon_name) + + def icon_theme_changed_cb(self, theme): + self.update_icon("gtk-info") + + def quit_menu_item_cb(self, widget, data = None): + event_system.emit("tear-down") diff --git a/src/plugins/__init__.py b/src/plugins/__init__.py new file mode 100644 index 0000000..5624b32 --- /dev/null +++ b/src/plugins/__init__.py @@ -0,0 +1,3 @@ +""" + Gtk Bound Plugins Module +""" diff --git a/src/plugins/dto/__init__.py b/src/plugins/dto/__init__.py new file mode 100644 index 0000000..2e533d6 --- /dev/null +++ b/src/plugins/dto/__init__.py @@ -0,0 +1,3 @@ +""" + Gtk Plugins DTO Module +""" diff --git a/src/plugins/dto/manifest.py b/src/plugins/dto/manifest.py new file mode 100644 index 0000000..54c7f26 --- /dev/null +++ b/src/plugins/dto/manifest.py @@ -0,0 +1,27 @@ +# Python imports +from dataclasses import dataclass, field +from dataclasses import asdict + +# Gtk imports + +# Application imports +from .requests import Requests + + + +@dataclass +class Manifest: + name: str = "" + author: str = "" + credit: str = "" + version: str = "0.0.1" + support: str = "support@mail.com" + pre_launch: bool = False + requests: Requests = field(default_factory = lambda: Requests()) + + def __post_init__(self): + if isinstance(self.requests, dict): + self.requests = Requests(**self.requests) + + def as_dict(self): + return asdict(self) diff --git a/src/plugins/dto/manifest_meta.py b/src/plugins/dto/manifest_meta.py new file mode 100644 index 0000000..8e1056b --- /dev/null +++ b/src/plugins/dto/manifest_meta.py @@ -0,0 +1,19 @@ +# Python imports +from dataclasses import dataclass, field +from dataclasses import asdict + +# Gtk imports + +# Application imports +from .manifest import Manifest + + + +@dataclass +class ManifestMeta: + folder: str = "" + path: str = "" + manifest: Manifest = field(default_factory = lambda: Manifest()) + + def as_dict(self): + return asdict(self) diff --git a/src/plugins/dto/requests.py b/src/plugins/dto/requests.py new file mode 100644 index 0000000..8321e34 --- /dev/null +++ b/src/plugins/dto/requests.py @@ -0,0 +1,15 @@ +# Python imports +from dataclasses import dataclass, field + +# Lib imports + +# Application imports + + +@dataclass +class Requests: + ui_target: str = "" + ui_target_id: str = "" + pass_events: bool = False + pass_ui_objects: list = field(default_factory = lambda: []) + bind_keys: list = field(default_factory = lambda: []) diff --git a/src/plugins/manifest_manager.py b/src/plugins/manifest_manager.py new file mode 100644 index 0000000..518c198 --- /dev/null +++ b/src/plugins/manifest_manager.py @@ -0,0 +1,68 @@ +# Python imports +import os +import json +from os.path import join + +# Lib imports + +# Application imports +from .dto.manifest_meta import ManifestMeta +from .dto.manifest import Manifest + + + +class ManifestMapperException(Exception): + ... + + + +class ManifestManager: + def __init__(self): + + self._plugins_path = settings_manager.path_manager.get_plugins_path() + + self.pre_launch_manifests = [] + self.post_launch_manifests = [] + + self.load_manifests() + + + def load_manifests(self): + logger.info(f"Loading manifests...") + + for path, folder in [ + [join(self._plugins_path, item), item] + if + os.path.isdir( join(self._plugins_path, item) ) + else + None + for item in os.listdir(self._plugins_path) + ]: + self.load(folder, path) + + def load(self, folder, path): + manifest_pth = join(path, "manifest.json") + + if not os.path.exists(manifest_pth): + raise ManifestMapperException("Invalid Plugin Structure: Plugin doesn't have 'manifest.json'. Aboarting load...") + + with open(manifest_pth) as f: + data = json.load(f) + manifest = Manifest(**data) + manifest_meta = ManifestMeta() + + manifest_meta.folder = folder + manifest_meta.path = path + manifest_meta.manifest = manifest + + if manifest.pre_launch: + self.pre_launch_manifests.append(manifest_meta) + else: + self.post_launch_manifests.append(manifest_meta) + + def get_pre_launch_manifests(self) -> dict: + return self.pre_launch_manifests + + def get_post_launch_plugins(self) -> None: + return self.post_launch_manifests + diff --git a/src/plugins/plugin_base.py b/src/plugins/plugin_base.py new file mode 100644 index 0000000..7a63917 --- /dev/null +++ b/src/plugins/plugin_base.py @@ -0,0 +1,92 @@ +# Python imports +import os +import time +import inspect + +# Lib imports + +# Application imports + + +class PluginBaseException(Exception): + ... + + +class PluginBase: + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.name = "Example Plugin" # NOTE: Need to remove after establishing private bidirectional 1-1 message bus + # where self.name should not be needed for message comms + + self._builder = None + self._ui_objects = None + self._event_system = None + + + def run(self): + """ + Must define regardless if needed and can 'pass' if plugin doesn't need it. + Is intended to be used to setup internal signals or custom Gtk Builders/UI logic. + """ + raise PluginBaseException("Method hasn't been overriden...") + + def generate_reference_ui_element(self): + """ + Requests Key: 'ui_target': "plugin_control_list", + Must define regardless if needed and can 'pass' if plugin doesn't use it. + Must return a widget if "ui_target" is set. + """ + raise PluginBaseException("Method hasn't been overriden...") + + def set_ui_object_collection(self, ui_objects): + """ + Requests Key: "pass_ui_objects": [""] + Request reference to a UI component. Will be passed back as array to plugin. + Must define in plugin if set and an array of valid glade UI IDs is given. + """ + self._ui_objects = ui_objects + + def set_event_system(self, event_system): + """ + Requests Key: 'pass_events': true + Must define in plugin if "pass_events" is set to true. + """ + self._event_system = event_system + + def subscribe_to_events(self): + ... + + def _connect_builder_signals(self, caller_class, builder): + classes = [caller_class] + handlers = {} + for c in classes: + methods = None + try: + methods = inspect.getmembers(c, predicate=inspect.ismethod) + handlers.update(methods) + except Exception as e: + logger.debug(repr(e)) + + builder.connect_signals(handlers) + + def reload_package(self, plugin_path, module_dict_main=locals()): + import importlib + from pathlib import Path + + def reload_package_recursive(current_dir, module_dict): + for path in current_dir.iterdir(): + if "__init__" in str(path) or path.stem not in module_dict: + continue + + if path.is_file() and path.suffix == ".py": + importlib.reload(module_dict[path.stem]) + elif path.is_dir(): + reload_package_recursive(path, module_dict[path.stem].__dict__) + + reload_package_recursive(Path(plugin_path).parent, module_dict_main["module_dict_main"]) + + + def clear_children(self, widget: type) -> None: + """ Clear children of a gtk widget. """ + for child in widget.get_children(): + widget.remove(child) diff --git a/src/plugins/plugin_reload_mixin.py b/src/plugins/plugin_reload_mixin.py new file mode 100644 index 0000000..2b256ff --- /dev/null +++ b/src/plugins/plugin_reload_mixin.py @@ -0,0 +1,36 @@ +# Python imports + +# Lib imports +import gi +from gi.repository import Gio + +# Application imports + + + +class PluginReloadMixin: + _plugins_dir_watcher = None + + def _set_plugins_watcher(self) -> None: + self._plugins_dir_watcher = Gio.File.new_for_path( + self._plugins_path + ).monitor_directory( + Gio.FileMonitorFlags.WATCH_MOVES, + Gio.Cancellable() + ) + + self._plugins_dir_watcher.connect("changed", self._on_plugins_changed, ()) + + def _on_plugins_changed(self, + file_monitor, file, + other_file = None, + eve_type = None, + data = None + ): + if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED, + Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN, + Gio.FileMonitorEvent.MOVED_OUT]: + self.reload_plugins(file) + + def reload_plugins(self, file: str = None) -> None: + logger.info(f"Reloading plugins... stub.") diff --git a/src/plugins/plugins_controller.py b/src/plugins/plugins_controller.py new file mode 100644 index 0000000..831a38e --- /dev/null +++ b/src/plugins/plugins_controller.py @@ -0,0 +1,134 @@ +# Python imports +import os +import sys +import importlib +import traceback +from os.path import join +from os.path import isdir + +# Lib imports +import gi +from gi.repository import GLib + +# Application imports +from .dto.manifest_meta import ManifestMeta +from .plugin_reload_mixin import PluginReloadMixin +from .manifest_manager import ManifestManager + + + +class InvalidPluginException(Exception): + ... + + + +class PluginsController(PluginReloadMixin): + """PluginsController controller""" + + def __init__(self): + # path = os.path.dirname(os.path.realpath(__file__)) + # sys.path.insert(0, path) # NOTE: I think I'm not using this correctly... + + self._plugin_collection = [] + + self._plugins_path = settings_manager.path_manager.get_plugins_path() + self._manifest_manager = ManifestManager() + + self._set_plugins_watcher() + + + def pre_launch_plugins(self) -> None: + logger.info(f"Loading pre-launch plugins...") + manifest_metas: [] = self._manifest_manager.get_pre_launch_manifests() + self._load_plugins(manifest_metas, is_pre_launch = True) + + def post_launch_plugins(self) -> None: + logger.info(f"Loading post-launch plugins...") + manifest_metas: [] = self._manifest_manager.get_post_launch_plugins() + self._load_plugins(manifest_metas) + + def _load_plugins( + self, + manifest_metas: [] = [], + is_pre_launch: bool = False + ) -> None: + parent_path = os.getcwd() + + for manifest_meta in manifest_metas: + path, folder, manifest = manifest_meta.path, manifest_meta.folder, manifest_meta.manifest + + try: + target = join(path, "plugin.py") + if not os.path.exists(target): + raise InvalidPluginException("Invalid Plugin Structure: Plugin doesn't have 'plugin.py'. Aboarting load...") + + module = self.load_plugin_module(path, folder, target) + + if is_pre_launch: + self.execute_plugin(module, manifest_meta) + else: + GLib.idle_add(self.execute_plugin, module, manifest_meta) + except Exception as e: + logger.info(f"Malformed Plugin: Not loading -->: '{folder}' !") + logger.debug("Trace: ", traceback.print_exc()) + + os.chdir(parent_path) + + def load_plugin_module(self, path, folder, target): + os.chdir(path) + + locations = [] + self.collect_search_locations(path, locations) + + spec = importlib.util.spec_from_file_location(folder, target, submodule_search_locations = locations) + module = importlib.util.module_from_spec(spec) + sys.modules[folder] = module + spec.loader.exec_module(module) + + return module + + def collect_search_locations(self, path: str, locations: list): + locations.append(path) + for file in os.listdir(path): + _path = os.path.join(path, file) + if os.path.isdir(_path): + self.collect_search_locations(_path, locations) + + def execute_plugin(self, module: type, manifest_meta: ManifestMeta): + manifest = manifest_meta.manifest + manifest_meta.instance = module.Plugin() + + if manifest.requests.ui_target: + builder = settings_manager.get_builder() + ui_target = manifest.requests.ui_target + ui_target_id = manifest.requests.ui_target_id + + if not ui_target == "other": + ui_target = builder.get_object(ui_target) + else: + if not ui_target_id: + raise InvalidPluginException('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') + + ui_target = builder.get_object(ui_target_id) + + if not ui_target: + raise InvalidPluginException('Unknown "ui_target" given in requests.') + + ui_element = manifest_meta.instance.generate_reference_ui_element() + + ui_target.add(ui_element) + + if manifest.requests.pass_ui_objects: + manifest_meta.instance.set_ui_object_collection( + [ builder.get_object(obj) for obj in manifest.requests.pass_ui_objects ] + ) + + if manifest.requests.pass_events: + manifest_meta.instance.set_event_system(event_system) + manifest_meta.instance.subscribe_to_events() + + if manifest.requests.bind_keys: + keybindings.append_bindings( manifest.requests.bind_keys ) + + manifest_meta.instance.run() + self._plugin_collection.append(manifest_meta) diff --git a/user_config/bin/ b/user_config/bin/ new file mode 100755 index 0000000..c36f8a4 --- /dev/null +++ b/user_config/bin/ @@ -0,0 +1,39 @@ +#!/bin/bash + +# . CONFIG.sh + +# set -o xtrace ## To debug scripts +# set -o errexit ## To exit on error +# set -o errunset ## To exit if a variable is referenced but not set + + +function main() { + call_path=`pwd` + path="" + + # NOTE: Remove if you want to pass file(s) besides directories... + if [[ ! "${1::1}" == /* ]]; then + path="${call_path}/${1}" + else + path="${1}" + fi + + if [ ! -d "${path}" ]; then + echo ": Path given not a directory..." + exit 1 + fi + # End NOTE: Remove if you want to pass file(s) besides directories... + + # Collect abs paths and stuff in 'files' array + files=() + for f in "$@"; do + target=$(readlink -f "${f}") + i="${#files[@]}" + size=$(($i + 1)) + files[$size]="${target}" + done + + cd "/opt/" + python /opt/.zip "$@" +} +main "$@"; \ No newline at end of file diff --git a/user_config/usr/applications/newton.desktop b/user_config/usr/applications/newton.desktop new file mode 100644 index 0000000..00f8ede --- /dev/null +++ b/user_config/usr/applications/newton.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Name=Newton +GenericName=Text editor and mini IDE +Comment=General purpose text editor and IDE +Exec=/bin/newton %F +Icon=/usr/share/newton/icons/newton.png +Type=Application +StartupNotify=true +Categories=GNOME;GTK;Utility;TextEditor;Development; +MimeType=text/plain;text/py;text/js;text/java;text/cpp;text/sh;text/html;text/json; +Terminal=false diff --git a/user_config/usr/share/newton/Main_Window.glade b/user_config/usr/share/newton/Main_Window.glade new file mode 100644 index 0000000..c1a1964 --- /dev/null +++ b/user_config/usr/share/newton/Main_Window.glade @@ -0,0 +1,28 @@ + + + + + + True + False + vertical + + + True + False + Loaded Me From Glade! + + + False + True + 0 + + + + + + + + + + diff --git a/user_config/usr/share/newton/code-key-bindings.json b/user_config/usr/share/newton/code-key-bindings.json new file mode 100644 index 0000000..e35ca74 --- /dev/null +++ b/user_config/usr/share/newton/code-key-bindings.json @@ -0,0 +1,64 @@ +{ + "keybindings": { + "show_completion": { + "released": "space" + }, + "line_up": { + "held": "Up" + }, + "line_down": { + "held": "Down" + }, + "zoom_in": { + "held": "equal" + }, + "zoom_out": { + "held": "minus" + }, + "cut_to_temp_buffer": { + "held": "k" + }, + "duplicate_line": { + "held": "d" + }, + "go_to": { + "released": "g" + }, + "paste_temp_buffer": { + "held": "u" + }, + "new_file": { + "released": "t" + }, + "buffer_undo": { + "held": "z" + }, + "buffer_redo": { + "held": "y" + }, + "open_files": { + "released": "o" + }, + "close_file": { + "released": "w" + }, + "save_file": { + "released": "s" + }, + "save_file_as": { + "released": "s" + }, + "focus_left_sibling": { + "released": "Page_Up" + }, + "focus_right_sibling": { + "released": "Page_Down" + }, + "move_to_left_sibling": { + "released": "Up" + }, + "move_to_right_sibling": { + "released": "Down" + } + } +} \ No newline at end of file diff --git a/user_config/usr/share/newton/code_styles/catppuccin-frappe.xml b/user_config/usr/share/newton/code_styles/catppuccin-frappe.xml new file mode 100644 index 0000000..76b043e --- /dev/null +++ b/user_config/usr/share/newton/code_styles/catppuccin-frappe.xml @@ -0,0 +1,100 @@ + + + + + + sacerdos + <_description>Soothing pastel theme for Gedit + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

bootstrap-icons

+ +
+
+ +
123
+
+
+ +
activity
+
+
+ +
alarm-fill
+
+
+ +
alarm
+
+
+ +
align-bottom
+
+
+ +
align-center
+
+
+ +
align-end
+
+
+ +
align-middle
+
+
+ +
align-start
+
+
+ +
align-top
+
+
+ +
alt
+
+
+ +
app-indicator
+
+
+ +
app
+
+
+ +
apple
+
+
+ +
archive-fill
+
+
+ +
archive
+
+
+ +
arrow-90deg-down
+
+
+ +
arrow-90deg-left
+
+
+ +
arrow-90deg-right
+
+
+ +
arrow-90deg-up
+
+
+ +
arrow-bar-down
+
+
+ +
arrow-bar-left
+
+
+ +
arrow-bar-right
+
+
+ +
arrow-bar-up
+
+
+ +
arrow-clockwise
+
+
+ +
arrow-counterclockwise
+
+
+ +
arrow-down-circle-fill
+
+
+ +
arrow-down-circle
+
+
+ +
arrow-down-left-circle-fill
+
+
+ +
arrow-down-left-circle
+
+
+ +
arrow-down-left-square-fill
+
+
+ +
arrow-down-left-square
+
+
+ +
arrow-down-left
+
+
+ +
arrow-down-right-circle-fill
+
+
+ +
arrow-down-right-circle
+
+
+ +
arrow-down-right-square-fill
+
+
+ +
arrow-down-right-square
+
+
+ +
arrow-down-right
+
+
+ +
arrow-down-short
+
+
+ +
arrow-down-square-fill
+
+
+ +
arrow-down-square
+
+
+ +
arrow-down-up
+
+
+ +
arrow-down
+
+
+ +
arrow-left-circle-fill
+
+
+ +
arrow-left-circle
+
+
+ +
arrow-left-right
+
+
+ +
arrow-left-short
+
+
+ +
arrow-left-square-fill
+
+
+ +
arrow-left-square
+
+
+ +
arrow-left
+
+
+ +
arrow-repeat
+
+
+ +
arrow-return-left
+
+
+ +
arrow-return-right
+
+
+ +
arrow-right-circle-fill
+
+
+ +
arrow-right-circle
+
+
+ +
arrow-right-short
+
+
+ +
arrow-right-square-fill
+
+
+ +
arrow-right-square
+
+
+ +
arrow-right
+
+
+ +
arrow-through-heart-fill
+
+
+ +
arrow-through-heart
+
+
+ +
arrow-up-circle-fill
+
+
+ +
arrow-up-circle
+
+
+ +
arrow-up-left-circle-fill
+
+
+ +
arrow-up-left-circle
+
+
+ +
arrow-up-left-square-fill
+
+
+ +
arrow-up-left-square
+
+
+ +
arrow-up-left
+
+
+ +
arrow-up-right-circle-fill
+
+
+ +
arrow-up-right-circle
+
+
+ +
arrow-up-right-square-fill
+
+
+ +
arrow-up-right-square
+
+
+ +
arrow-up-right
+
+
+ +
arrow-up-short
+
+
+ +
arrow-up-square-fill
+
+
+ +
arrow-up-square
+
+
+ +
arrow-up
+
+
+ +
arrows-angle-contract
+
+
+ +
arrows-angle-expand
+
+
+ +
arrows-collapse
+
+
+ +
arrows-expand
+
+
+ +
arrows-fullscreen
+
+
+ +
arrows-move
+
+
+ +
aspect-ratio-fill
+
+
+ +
aspect-ratio
+
+
+ +
asterisk
+
+
+ +
at
+
+
+ +
award-fill
+
+
+ +
award
+
+
+ +
back
+
+
+ +
backspace-fill
+
+
+ +
backspace-reverse-fill
+
+
+ +
backspace-reverse
+
+
+ +
backspace
+
+
+ +
badge-3d-fill
+
+
+ +
badge-3d
+
+
+ +
badge-4k-fill
+
+
+ +
badge-4k
+
+
+ +
badge-8k-fill
+
+
+ +
badge-8k
+
+
+ +
badge-ad-fill
+
+
+ +
badge-ad
+
+
+ +
badge-ar-fill
+
+
+ +
badge-ar
+
+
+ +
badge-cc-fill
+
+
+ +
badge-cc
+
+
+ +
badge-hd-fill
+
+
+ +
badge-hd
+
+
+ +
badge-sd-fill
+
+
+ +
badge-sd
+
+
+ +
badge-tm-fill
+
+
+ +
badge-tm
+
+
+ +
badge-vo-fill
+
+
+ +
badge-vo
+
+
+ +
badge-vr-fill
+
+
+ +
badge-vr
+
+
+ +
badge-wc-fill
+
+
+ +
badge-wc
+
+
+ +
bag-check-fill
+
+
+ +
bag-check
+
+
+ +
bag-dash-fill
+
+
+ +
bag-dash
+
+
+ +
bag-fill
+
+
+ +
bag-heart-fill
+
+
+ +
bag-heart
+
+
+ +
bag-plus-fill
+
+
+ +
bag-plus
+
+
+ +
bag-x-fill
+
+
+ +
bag-x
+
+
+ +
bag
+
+
+ +
balloon-fill
+
+
+ +
balloon-heart-fill
+
+
+ +
balloon-heart
+
+
+ +
balloon
+
+
+ +
bandaid-fill
+
+
+ +
bandaid
+
+
+ +
bank
+
+
+ +
bank2
+
+
+ +
bar-chart-fill
+
+
+ +
bar-chart-line-fill
+
+
+ +
bar-chart-line
+
+
+ +
bar-chart-steps
+
+
+ +
bar-chart
+
+
+ +
basket-fill
+
+
+ +
basket
+
+
+ +
basket2-fill
+
+
+ +
basket2
+
+
+ +
basket3-fill
+
+
+ +
basket3
+
+
+ +
battery-charging
+
+
+ +
battery-full
+
+
+ +
battery-half
+
+
+ +
battery
+
+
+ +
behance
+
+
+ +
bell-fill
+
+
+ +
bell-slash-fill
+
+
+ +
bell-slash
+
+
+ +
bell
+
+
+ +
bezier
+
+
+ +
bezier2
+
+
+ +
bicycle
+
+
+ +
binoculars-fill
+
+
+ +
binoculars
+
+
+ +
blockquote-left
+
+
+ +
blockquote-right
+
+
+ +
bluetooth
+
+
+ +
body-text
+
+
+ +
book-fill
+
+
+ +
book-half
+
+
+ +
book
+
+
+ +
bookmark-check-fill
+
+
+ +
bookmark-check
+
+
+ +
bookmark-dash-fill
+
+
+ +
bookmark-dash
+
+
+ +
bookmark-fill
+
+
+ +
bookmark-heart-fill
+
+
+ +
bookmark-heart
+
+
+ +
bookmark-plus-fill
+
+
+ +
bookmark-plus
+
+
+ +
bookmark-star-fill
+
+
+ +
bookmark-star
+
+
+ +
bookmark-x-fill
+
+
+ +
bookmark-x
+
+
+ +
bookmark
+
+
+ +
bookmarks-fill
+
+
+ +
bookmarks
+
+
+ +
bookshelf
+
+
+ +
boombox-fill
+
+
+ +
boombox
+
+
+ +
bootstrap-fill
+
+
+ +
bootstrap-reboot
+
+
+ +
bootstrap
+
+
+ +
border-all
+
+
+ +
border-bottom
+
+
+ +
border-center
+
+
+ +
border-inner
+
+
+ +
border-left
+
+
+ +
border-middle
+
+
+ +
border-outer
+
+
+ +
border-right
+
+
+ +
border-style
+
+
+ +
border-top
+
+
+ +
border-width
+
+
+ +
border
+
+
+ +
bounding-box-circles
+
+
+ +
bounding-box
+
+
+ +
box-arrow-down-left
+
+
+ +
box-arrow-down-right
+
+
+ +
box-arrow-down
+
+
+ +
box-arrow-in-down-left
+
+
+ +
box-arrow-in-down-right
+
+
+ +
box-arrow-in-down
+
+
+ +
box-arrow-in-left
+
+
+ +
box-arrow-in-right
+
+
+ +
box-arrow-in-up-left
+
+
+ +
box-arrow-in-up-right
+
+
+ +
box-arrow-in-up
+
+
+ +
box-arrow-left
+
+
+ +
box-arrow-right
+
+
+ +
box-arrow-up-left
+
+
+ +
box-arrow-up-right
+
+
+ +
box-arrow-up
+
+
+ +
box-seam
+
+
+ +
box
+
+
+ +
box2-fill
+
+
+ +
box2-heart-fill
+
+
+ +
box2-heart
+
+
+ +
box2
+
+
+ +
boxes
+
+
+ +
braces-asterisk
+
+
+ +
braces
+
+
+ +
bricks
+
+
+ +
briefcase-fill
+
+
+ +
briefcase
+
+
+ +
brightness-alt-high-fill
+
+
+ +
brightness-alt-high
+
+
+ +
brightness-alt-low-fill
+
+
+ +
brightness-alt-low
+
+
+ +
brightness-high-fill
+
+
+ +
brightness-high
+
+
+ +
brightness-low-fill
+
+
+ +
brightness-low
+
+
+ +
broadcast-pin
+
+
+ +
broadcast
+
+
+ +
brush-fill
+
+
+ +
brush
+
+
+ +
bucket-fill
+
+
+ +
bucket
+
+
+ +
bug-fill
+
+
+ +
bug
+
+
+ +
building
+
+
+ +
bullseye
+
+
+ +
calculator-fill
+
+
+ +
calculator
+
+
+ +
calendar-check-fill
+
+
+ +
calendar-check
+
+
+ +
calendar-date-fill
+
+
+ +
calendar-date
+
+
+ +
calendar-day-fill
+
+
+ +
calendar-day
+
+
+ +
calendar-event-fill
+
+
+ +
calendar-event
+
+
+ +
calendar-fill
+
+
+ +
calendar-heart-fill
+
+
+ +
calendar-heart
+
+
+ +
calendar-minus-fill
+
+
+ +
calendar-minus
+
+
+ +
calendar-month-fill
+
+
+ +
calendar-month
+
+
+ +
calendar-plus-fill
+
+
+ +
calendar-plus
+
+
+ +
calendar-range-fill
+
+
+ +
calendar-range
+
+
+ +
calendar-week-fill
+
+
+ +
calendar-week
+
+
+ +
calendar-x-fill
+
+
+ +
calendar-x
+
+
+ +
calendar
+
+
+ +
calendar2-check-fill
+
+
+ +
calendar2-check
+
+
+ +
calendar2-date-fill
+
+
+ +
calendar2-date
+
+
+ +
calendar2-day-fill
+
+
+ +
calendar2-day
+
+
+ +
calendar2-event-fill
+
+
+ +
calendar2-event
+
+
+ +
calendar2-fill
+
+
+ +
calendar2-heart-fill
+
+
+ +
calendar2-heart
+
+
+ +
calendar2-minus-fill
+
+
+ +
calendar2-minus
+
+
+ +
calendar2-month-fill
+
+
+ +
calendar2-month
+
+
+ +
calendar2-plus-fill
+
+
+ +
calendar2-plus
+
+
+ +
calendar2-range-fill
+
+
+ +
calendar2-range
+
+
+ +
calendar2-week-fill
+
+
+ +
calendar2-week
+
+
+ +
calendar2-x-fill
+
+
+ +
calendar2-x
+
+
+ +
calendar2
+
+
+ +
calendar3-event-fill
+
+
+ +
calendar3-event
+
+
+ +
calendar3-fill
+
+
+ +
calendar3-range-fill
+
+
+ +
calendar3-range
+
+
+ +
calendar3-week-fill
+
+
+ +
calendar3-week
+
+
+ +
calendar3
+
+
+ +
calendar4-event
+
+
+ +
calendar4-range
+
+
+ +
calendar4-week
+
+
+ +
calendar4
+
+
+ +
camera-fill
+
+
+ +
camera-reels-fill
+
+
+ +
camera-reels
+
+
+ +
camera-video-fill
+
+
+ +
camera-video-off-fill
+
+
+ +
camera-video-off
+
+
+ +
camera-video
+
+
+ +
camera
+
+
+ +
camera2
+
+
+ +
capslock-fill
+
+
+ +
capslock
+
+
+ +
card-checklist
+
+
+ +
card-heading
+
+
+ +
card-image
+
+
+ +
card-list
+
+
+ +
card-text
+
+
+ +
caret-down-fill
+
+
+ +
caret-down-square-fill
+
+
+ +
caret-down-square
+
+
+ +
caret-down
+
+
+ +
caret-left-fill
+
+
+ +
caret-left-square-fill
+
+
+ +
caret-left-square
+
+
+ +
caret-left
+
+
+ +
caret-right-fill
+
+
+ +
caret-right-square-fill
+
+
+ +
caret-right-square
+
+
+ +
caret-right
+
+
+ +
caret-up-fill
+
+
+ +
caret-up-square-fill
+
+
+ +
caret-up-square
+
+
+ +
caret-up
+
+
+ +
cart-check-fill
+
+
+ +
cart-check
+
+
+ +
cart-dash-fill
+
+
+ +
cart-dash
+
+
+ +
cart-fill
+
+
+ +
cart-plus-fill
+
+
+ +
cart-plus
+
+
+ +
cart-x-fill
+
+
+ +
cart-x
+
+
+ +
cart
+
+
+ +
cart2
+
+
+ +
cart3
+
+
+ +
cart4
+
+
+ +
cash-coin
+
+
+ +
cash-stack
+
+
+ +
cash
+
+
+ +
cast
+
+
+ +
chat-dots-fill
+
+
+ +
chat-dots
+
+
+ +
chat-fill
+
+
+ +
chat-heart-fill
+
+
+ +
chat-heart
+
+
+ +
chat-left-dots-fill
+
+
+ +
chat-left-dots
+
+
+ +
chat-left-fill
+
+
+ +
chat-left-heart-fill
+
+
+ +
chat-left-heart
+
+
+ +
chat-left-quote-fill
+
+
+ +
chat-left-quote
+
+
+ +
chat-left-text-fill
+
+
+ +
chat-left-text
+
+
+ +
chat-left
+
+
+ +
chat-quote-fill
+
+
+ +
chat-quote
+
+
+ +
chat-right-dots-fill
+
+
+ +
chat-right-dots
+
+
+ +
chat-right-fill
+
+
+ +
chat-right-heart-fill
+
+
+ +
chat-right-heart
+
+
+ +
chat-right-quote-fill
+
+
+ +
chat-right-quote
+
+
+ +
chat-right-text-fill
+
+
+ +
chat-right-text
+
+
+ +
chat-right
+
+
+ +
chat-square-dots-fill
+
+
+ +
chat-square-dots
+
+
+ +
chat-square-fill
+
+
+ +
chat-square-heart-fill
+
+
+ +
chat-square-heart
+
+
+ +
chat-square-quote-fill
+
+
+ +
chat-square-quote
+
+
+ +
chat-square-text-fill
+
+
+ +
chat-square-text
+
+
+ +
chat-square
+
+
+ +
chat-text-fill
+
+
+ +
chat-text
+
+
+ +
chat
+
+
+ +
check-all
+
+
+ +
check-circle-fill
+
+
+ +
check-circle
+
+
+ +
check-lg
+
+
+ +
check-square-fill
+
+
+ +
check-square
+
+
+ +
check
+
+
+ +
check2-all
+
+
+ +
check2-circle
+
+
+ +
check2-square
+
+
+ +
check2
+
+
+ +
chevron-bar-contract
+
+
+ +
chevron-bar-down
+
+
+ +
chevron-bar-expand
+
+
+ +
chevron-bar-left
+
+
+ +
chevron-bar-right
+
+
+ +
chevron-bar-up
+
+
+ +
chevron-compact-down
+
+
+ +
chevron-compact-left
+
+
+ +
chevron-compact-right
+
+
+ +
chevron-compact-up
+
+
+ +
chevron-contract
+
+
+ +
chevron-double-down
+
+
+ +
chevron-double-left
+
+
+ +
chevron-double-right
+
+
+ +
chevron-double-up
+
+
+ +
chevron-down
+
+
+ +
chevron-expand
+
+
+ +
chevron-left
+
+
+ +
chevron-right
+
+
+ +
chevron-up
+
+
+ +
circle-fill
+
+
+ +
circle-half
+
+
+ +
circle-square
+
+
+ +
circle
+
+
+ +
clipboard-check-fill
+
+
+ +
clipboard-check
+
+
+ +
clipboard-data-fill
+
+
+ +
clipboard-data
+
+
+ +
clipboard-fill
+
+
+ +
clipboard-heart-fill
+
+
+ +
clipboard-heart
+
+
+ +
clipboard-minus-fill
+
+
+ +
clipboard-minus
+
+
+ +
clipboard-plus-fill
+
+
+ +
clipboard-plus
+
+
+ +
clipboard-pulse
+
+
+ +
clipboard-x-fill
+
+
+ +
clipboard-x
+
+
+ +
clipboard
+
+
+ +
clipboard2-check-fill
+
+
+ +
clipboard2-check
+
+
+ +
clipboard2-data-fill
+
+
+ +
clipboard2-data
+
+
+ +
clipboard2-fill
+
+
+ +
clipboard2-heart-fill
+
+
+ +
clipboard2-heart
+
+
+ +
clipboard2-minus-fill
+
+
+ +
clipboard2-minus
+
+
+ +
clipboard2-plus-fill
+
+
+ +
clipboard2-plus
+
+
+ +
clipboard2-pulse-fill
+
+
+ +
clipboard2-pulse
+
+
+ +
clipboard2-x-fill
+
+
+ +
clipboard2-x
+
+
+ +
clipboard2
+
+
+ +
clock-fill
+
+
+ +
clock-history
+
+
+ +
clock
+
+
+ +
cloud-arrow-down-fill
+
+
+ +
cloud-arrow-down
+
+
+ +
cloud-arrow-up-fill
+
+
+ +
cloud-arrow-up
+
+
+ +
cloud-check-fill
+
+
+ +
cloud-check
+
+
+ +
cloud-download-fill
+
+
+ +
cloud-download
+
+
+ +
cloud-drizzle-fill
+
+
+ +
cloud-drizzle
+
+
+ +
cloud-fill
+
+
+ +
cloud-fog-fill
+
+
+ +
cloud-fog
+
+
+ +
cloud-fog2-fill
+
+
+ +
cloud-fog2
+
+
+ +
cloud-hail-fill
+
+
+ +
cloud-hail
+
+
+ +
cloud-haze-fill
+
+
+ +
cloud-haze
+
+
+ +
cloud-haze2-fill
+
+
+ +
cloud-haze2
+
+
+ +
cloud-lightning-fill
+
+
+ +
cloud-lightning-rain-fill
+
+
+ +
cloud-lightning-rain
+
+
+ +
cloud-lightning
+
+
+ +
cloud-minus-fill
+
+
+ +
cloud-minus
+
+
+ +
cloud-moon-fill
+
+
+ +
cloud-moon
+
+
+ +
cloud-plus-fill
+
+
+ +
cloud-plus
+
+
+ +
cloud-rain-fill
+
+
+ +
cloud-rain-heavy-fill
+
+
+ +
cloud-rain-heavy
+
+
+ +
cloud-rain
+
+
+ +
cloud-slash-fill
+
+
+ +
cloud-slash
+
+
+ +
cloud-sleet-fill
+
+
+ +
cloud-sleet
+
+
+ +
cloud-snow-fill
+
+
+ +
cloud-snow
+
+
+ +
cloud-sun-fill
+
+
+ +
cloud-sun
+
+
+ +
cloud-upload-fill
+
+
+ +
cloud-upload
+
+
+ +
cloud
+
+
+ +
clouds-fill
+
+
+ +
clouds
+
+
+ +
cloudy-fill
+
+
+ +
cloudy
+
+
+ +
code-slash
+
+
+ +
code-square
+
+
+ +
code
+
+
+ +
coin
+
+
+ +
collection-fill
+
+
+ +
collection-play-fill
+
+
+ +
collection-play
+
+
+ +
collection
+
+
+ +
columns-gap
+
+
+ +
columns
+
+
+ +
command
+
+
+ +
compass-fill
+
+
+ +
compass
+
+
+ +
cone-striped
+
+
+ +
cone
+
+
+ +
controller
+
+
+ +
cpu-fill
+
+
+ +
cpu
+
+
+ +
credit-card-2-back-fill
+
+
+ +
credit-card-2-back
+
+
+ +
credit-card-2-front-fill
+
+
+ +
credit-card-2-front
+
+
+ +
credit-card-fill
+
+
+ +
credit-card
+
+
+ +
crop
+
+
+ +
cup-fill
+
+
+ +
cup-straw
+
+
+ +
cup
+
+
+ +
currency-bitcoin
+
+
+ +
currency-dollar
+
+
+ +
currency-euro
+
+
+ +
currency-exchange
+
+
+ +
currency-pound
+
+
+ +
currency-yen
+
+
+ +
cursor-fill
+
+
+ +
cursor-text
+
+
+ +
cursor
+
+
+ +
dash-circle-dotted
+
+
+ +
dash-circle-fill
+
+
+ +
dash-circle
+
+
+ +
dash-lg
+
+
+ +
dash-square-dotted
+
+
+ +
dash-square-fill
+
+
+ +
dash-square
+
+
+ +
dash
+
+
+ +
device-hdd-fill
+
+
+ +
device-hdd
+
+
+ +
device-ssd-fill
+
+
+ +
device-ssd
+
+
+ +
diagram-2-fill
+
+
+ +
diagram-2
+
+
+ +
diagram-3-fill
+
+
+ +
diagram-3
+
+
+ +
diamond-fill
+
+
+ +
diamond-half
+
+
+ +
diamond
+
+
+ +
dice-1-fill
+
+
+ +
dice-1
+
+
+ +
dice-2-fill
+
+
+ +
dice-2
+
+
+ +
dice-3-fill
+
+
+ +
dice-3
+
+
+ +
dice-4-fill
+
+
+ +
dice-4
+
+
+ +
dice-5-fill
+
+
+ +
dice-5
+
+
+ +
dice-6-fill
+
+
+ +
dice-6
+
+
+ +
disc-fill
+
+
+ +
disc
+
+
+ +
discord
+
+
+ +
display-fill
+
+
+ +
display
+
+
+ +
displayport-fill
+
+
+ +
displayport
+
+
+ +
distribute-horizontal
+
+
+ +
distribute-vertical
+
+
+ +
door-closed-fill
+
+
+ +
door-closed
+
+
+ +
door-open-fill
+
+
+ +
door-open
+
+
+ +
dot
+
+
+ +
download
+
+
+ +
dpad-fill
+
+
+ +
dpad
+
+
+ +
dribbble
+
+
+ +
droplet-fill
+
+
+ +
droplet-half
+
+
+ +
droplet
+
+
+ +
ear-fill
+
+
+ +
ear
+
+
+ +
earbuds
+
+
+ +
easel-fill
+
+
+ +
easel
+
+
+ +
easel2-fill
+
+
+ +
easel2
+
+
+ +
easel3-fill
+
+
+ +
easel3
+
+
+ +
egg-fill
+
+
+ +
egg-fried
+
+
+ +
egg
+
+
+ +
eject-fill
+
+
+ +
eject
+
+
+ +
emoji-angry-fill
+
+
+ +
emoji-angry
+
+
+ +
emoji-dizzy-fill
+
+
+ +
emoji-dizzy
+
+
+ +
emoji-expressionless-fill
+
+
+ +
emoji-expressionless
+
+
+ +
emoji-frown-fill
+
+
+ +
emoji-frown
+
+
+ +
emoji-heart-eyes-fill
+
+
+ +
emoji-heart-eyes
+
+
+ +
emoji-kiss-fill
+
+
+ +
emoji-kiss
+
+
+ +
emoji-laughing-fill
+
+
+ +
emoji-laughing
+
+
+ +
emoji-neutral-fill
+
+
+ +
emoji-neutral
+
+
+ +
emoji-smile-fill
+
+
+ +
emoji-smile-upside-down-fill
+
+
+ +
emoji-smile-upside-down
+
+
+ +
emoji-smile
+
+
+ +
emoji-sunglasses-fill
+
+
+ +
emoji-sunglasses
+
+
+ +
emoji-wink-fill
+
+
+ +
emoji-wink
+
+
+ +
envelope-check-fill
+
+
+ +
envelope-check
+
+
+ +
envelope-dash-fill
+
+
+ +
envelope-dash
+
+
+ +
envelope-exclamation-fill
+
+
+ +
envelope-exclamation
+
+
+ +
envelope-fill
+
+
+ +
envelope-heart-fill
+
+
+ +
envelope-heart
+
+
+ +
envelope-open-fill
+
+
+ +
envelope-open-heart-fill
+
+
+ +
envelope-open-heart
+
+
+ +
envelope-open
+
+
+ +
envelope-paper-fill
+
+
+ +
envelope-paper-heart-fill
+
+
+ +
envelope-paper-heart
+
+
+ +
envelope-paper
+
+
+ +
envelope-plus-fill
+
+
+ +
envelope-plus
+
+
+ +
envelope-slash-fill
+
+
+ +
envelope-slash
+
+
+ +
envelope-x-fill
+
+
+ +
envelope-x
+
+
+ +
envelope
+
+
+ +
eraser-fill
+
+
+ +
eraser
+
+
+ +
ethernet
+
+
+ +
exclamation-circle-fill
+
+
+ +
exclamation-circle
+
+
+ +
exclamation-diamond-fill
+
+
+ +
exclamation-diamond
+
+
+ +
exclamation-lg
+
+
+ +
exclamation-octagon-fill
+
+
+ +
exclamation-octagon
+
+
+ +
exclamation-square-fill
+
+
+ +
exclamation-square
+
+
+ +
exclamation-triangle-fill
+
+
+ +
exclamation-triangle
+
+
+ +
exclamation
+
+
+ +
exclude
+
+
+ +
explicit-fill
+
+
+ +
explicit
+
+
+ +
eye-fill
+
+
+ +
eye-slash-fill
+
+
+ +
eye-slash
+
+
+ +
eye
+
+
+ +
eyedropper
+
+
+ +
eyeglasses
+
+
+ +
facebook
+
+
+ +
fan
+
+
+ +
file-arrow-down-fill
+
+
+ +
file-arrow-down
+
+
+ +
file-arrow-up-fill
+
+
+ +
file-arrow-up
+
+
+ +
file-bar-graph-fill
+
+
+ +
file-bar-graph
+
+
+ +
file-binary-fill
+
+
+ +
file-binary
+
+
+ +
file-break-fill
+
+
+ +
file-break
+
+
+ +
file-check-fill
+
+
+ +
file-check
+
+
+ +
file-code-fill
+
+
+ +
file-code
+
+
+ +
file-diff-fill
+
+
+ +
file-diff
+
+
+ +
file-earmark-arrow-down-fill
+
+
+ +
file-earmark-arrow-down
+
+
+ +
file-earmark-arrow-up-fill
+
+
+ +
file-earmark-arrow-up
+
+
+ +
file-earmark-bar-graph-fill
+
+
+ +
file-earmark-bar-graph
+
+
+ +
file-earmark-binary-fill
+
+
+ +
file-earmark-binary
+
+
+ +
file-earmark-break-fill
+
+
+ +
file-earmark-break
+
+
+ +
file-earmark-check-fill
+
+
+ +
file-earmark-check
+
+
+ +
file-earmark-code-fill
+
+
+ +
file-earmark-code
+
+
+ +
file-earmark-diff-fill
+
+
+ +
file-earmark-diff
+
+
+ +
file-earmark-easel-fill
+
+
+ +
file-earmark-easel
+
+
+ +
file-earmark-excel-fill
+
+
+ +
file-earmark-excel
+
+
+ +
file-earmark-fill
+
+
+ +
file-earmark-font-fill
+
+
+ +
file-earmark-font
+
+
+ +
file-earmark-image-fill
+
+
+ +
file-earmark-image
+
+
+ +
file-earmark-lock-fill
+
+
+ +
file-earmark-lock
+
+
+ +
file-earmark-lock2-fill
+
+
+ +
file-earmark-lock2
+
+
+ +
file-earmark-medical-fill
+
+
+ +
file-earmark-medical
+
+
+ +
file-earmark-minus-fill
+
+
+ +
file-earmark-minus
+
+
+ +
file-earmark-music-fill
+
+
+ +
file-earmark-music
+
+
+ +
file-earmark-pdf-fill
+
+
+ +
file-earmark-pdf
+
+
+ +
file-earmark-person-fill
+
+
+ +
file-earmark-person
+
+
+ +
file-earmark-play-fill
+
+
+ +
file-earmark-play
+
+
+ +
file-earmark-plus-fill
+
+
+ +
file-earmark-plus
+
+
+ +
file-earmark-post-fill
+
+
+ +
file-earmark-post
+
+
+ +
file-earmark-ppt-fill
+
+
+ +
file-earmark-ppt
+
+
+ +
file-earmark-richtext-fill
+
+
+ +
file-earmark-richtext
+
+
+ +
file-earmark-ruled-fill
+
+
+ +
file-earmark-ruled
+
+
+ +
file-earmark-slides-fill
+
+
+ +
file-earmark-slides
+
+
+ +
file-earmark-spreadsheet-fill
+
+
+ +
file-earmark-spreadsheet
+
+
+ +
file-earmark-text-fill
+
+
+ +
file-earmark-text
+
+
+ +
file-earmark-word-fill
+
+
+ +
file-earmark-word
+
+
+ +
file-earmark-x-fill
+
+
+ +
file-earmark-x
+
+
+ +
file-earmark-zip-fill
+
+
+ +
file-earmark-zip
+
+
+ +
file-earmark
+
+
+ +
file-easel-fill
+
+
+ +
file-easel
+
+
+ +
file-excel-fill
+
+
+ +
file-excel
+
+
+ +
file-fill
+
+
+ +
file-font-fill
+
+
+ +
file-font
+
+
+ +
file-image-fill
+
+
+ +
file-image
+
+
+ +
file-lock-fill
+
+
+ +
file-lock
+
+
+ +
file-lock2-fill
+
+
+ +
file-lock2
+
+
+ +
file-medical-fill
+
+
+ +
file-medical
+
+
+ +
file-minus-fill
+
+
+ +
file-minus
+
+
+ +
file-music-fill
+
+
+ +
file-music
+
+
+ +
file-pdf-fill
+
+
+ +
file-pdf
+
+
+ +
file-person-fill
+
+
+ +
file-person
+
+
+ +
file-play-fill
+
+
+ +
file-play
+
+
+ +
file-plus-fill
+
+
+ +
file-plus
+
+
+ +
file-post-fill
+
+
+ +
file-post
+
+
+ +
file-ppt-fill
+
+
+ +
file-ppt
+
+
+ +
file-richtext-fill
+
+
+ +
file-richtext
+
+
+ +
file-ruled-fill
+
+
+ +
file-ruled
+
+
+ +
file-slides-fill
+
+
+ +
file-slides
+
+
+ +
file-spreadsheet-fill
+
+
+ +
file-spreadsheet
+
+
+ +
file-text-fill
+
+
+ +
file-text
+
+
+ +
file-word-fill
+
+
+ +
file-word
+
+
+ +
file-x-fill
+
+
+ +
file-x
+
+
+ +
file-zip-fill
+
+
+ +
file-zip
+
+
+ +
file
+
+
+ +
files-alt
+
+
+ +
files
+
+
+ +
filetype-aac
+
+
+ +
filetype-ai
+
+
+ +
filetype-bmp
+
+
+ +
filetype-cs
+
+
+ +
filetype-css
+
+
+ +
filetype-csv
+
+
+ +
filetype-doc
+
+
+ +
filetype-docx
+
+
+ +
filetype-exe
+
+
+ +
filetype-gif
+
+
+ +
filetype-heic
+
+
+ +
filetype-html
+
+
+ +
filetype-java
+
+
+ +
filetype-jpg
+
+
+ +
filetype-js
+
+
+ +
filetype-json
+
+
+ +
filetype-jsx
+
+
+ +
filetype-key
+
+
+ +
filetype-m4p
+
+
+ +
filetype-md
+
+
+ +
filetype-mdx
+
+
+ +
filetype-mov
+
+
+ +
filetype-mp3
+
+
+ +
filetype-mp4
+
+
+ +
filetype-otf
+
+
+ +
filetype-pdf
+
+
+ +
filetype-php
+
+
+ +
filetype-png
+
+
+ +
filetype-ppt
+
+
+ +
filetype-pptx
+
+
+ +
filetype-psd
+
+
+ +
filetype-py
+
+
+ +
filetype-raw
+
+
+ +
filetype-rb
+
+
+ +
filetype-sass
+
+
+ +
filetype-scss
+
+
+ +
filetype-sh
+
+
+ +
filetype-svg
+
+
+ +
filetype-tiff
+
+
+ +
filetype-tsx
+
+
+ +
filetype-ttf
+
+
+ +
filetype-txt
+
+
+ +
filetype-wav
+
+
+ +
filetype-woff
+
+
+ +
filetype-xls
+
+
+ +
filetype-xlsx
+
+
+ +
filetype-xml
+
+
+ +
filetype-yml
+
+
+ +
film
+
+
+ +
filter-circle-fill
+
+
+ +
filter-circle
+
+
+ +
filter-left
+
+
+ +
filter-right
+
+
+ +
filter-square-fill
+
+
+ +
filter-square
+
+
+ +
filter
+
+
+ +
fingerprint
+
+
+ +
flag-fill
+
+
+ +
flag
+
+
+ +
flower1
+
+
+ +
flower2
+
+
+ +
flower3
+
+
+ +
folder-check
+
+
+ +
folder-fill
+
+
+ +
folder-minus
+
+
+ +
folder-plus
+
+
+ +
folder-symlink-fill
+
+
+ +
folder-symlink
+
+
+ +
folder-x
+
+
+ +
folder
+
+
+ +
folder2-open
+
+
+ +
folder2
+
+
+ +
fonts
+
+
+ +
forward-fill
+
+
+ +
forward
+
+
+ +
front
+
+
+ +
fullscreen-exit
+
+
+ +
fullscreen
+
+
+ +
funnel-fill
+
+
+ +
funnel
+
+
+ +
gear-fill
+
+
+ +
gear-wide-connected
+
+
+ +
gear-wide
+
+
+ +
gear
+
+
+ +
gem
+
+
+ +
gender-ambiguous
+
+
+ +
gender-female
+
+
+ +
gender-male
+
+
+ +
gender-trans
+
+
+ +
geo-alt-fill
+
+
+ +
geo-alt
+
+
+ +
geo-fill
+
+
+ +
geo
+
+
+ +
gift-fill
+
+
+ +
gift
+
+
+ +
git
+
+
+ +
github
+
+
+ +
globe
+
+
+ +
globe2
+
+
+ +
google
+
+
+ +
gpu-card
+
+
+ +
graph-down-arrow
+
+
+ +
graph-down
+
+
+ +
graph-up-arrow
+
+
+ +
graph-up
+
+
+ +
grid-1x2-fill
+
+
+ +
grid-1x2
+
+
+ +
grid-3x2-gap-fill
+
+
+ +
grid-3x2-gap
+
+
+ +
grid-3x2
+
+
+ +
grid-3x3-gap-fill
+
+
+ +
grid-3x3-gap
+
+
+ +
grid-3x3
+
+
+ +
grid-fill
+
+
+ +
grid
+
+
+ +
grip-horizontal
+
+
+ +
grip-vertical
+
+
+ +
hammer
+
+
+ +
hand-index-fill
+
+
+ +
hand-index-thumb-fill
+
+
+ +
hand-index-thumb
+
+
+ +
hand-index
+
+
+ +
hand-thumbs-down-fill
+
+
+ +
hand-thumbs-down
+
+
+ +
hand-thumbs-up-fill
+
+
+ +
hand-thumbs-up
+
+
+ +
handbag-fill
+
+
+ +
handbag
+
+
+ +
hash
+
+
+ +
hdd-fill
+
+
+ +
hdd-network-fill
+
+
+ +
hdd-network
+
+
+ +
hdd-rack-fill
+
+
+ +
hdd-rack
+
+
+ +
hdd-stack-fill
+
+
+ +
hdd-stack
+
+
+ +
hdd
+
+
+ +
hdmi-fill
+
+
+ +
hdmi
+
+
+ +
headphones
+
+
+ +
headset-vr
+
+
+ +
headset
+
+
+ +
heart-arrow
+
+
+ +
heart-fill
+
+
+ +
heart-half
+
+
+ +
heart-pulse-fill
+
+
+ +
heart-pulse
+
+
+ +
heart
+
+
+ +
heartbreak-fill
+
+
+ +
heartbreak
+
+
+ +
hearts
+
+
+ +
heptagon-fill
+
+
+ +
heptagon-half
+
+
+ +
heptagon
+
+
+ +
hexagon-fill
+
+
+ +
hexagon-half
+
+
+ +
hexagon
+
+
+ +
hospital-fill
+
+
+ +
hospital
+
+
+ +
hourglass-bottom
+
+
+ +
hourglass-split
+
+
+ +
hourglass-top
+
+
+ +
hourglass
+
+
+ +
house-door-fill
+
+
+ +
house-door
+
+
+ +
house-fill
+
+
+ +
house-heart-fill
+
+
+ +
house-heart
+
+
+ +
house
+
+
+ +
hr
+
+
+ +
hurricane
+
+
+ +
hypnotize
+
+
+ +
image-alt
+
+
+ +
image-fill
+
+
+ +
image
+
+
+ +
images
+
+
+ +
inbox-fill
+
+
+ +
inbox
+
+
+ +
inboxes-fill
+
+
+ +
inboxes
+
+
+ +
incognito
+
+
+ +
infinity
+
+
+ +
info-circle-fill
+
+
+ +
info-circle
+
+
+ +
info-lg
+
+
+ +
info-square-fill
+
+
+ +
info-square
+
+
+ +
info
+
+
+ +
input-cursor-text
+
+
+ +
input-cursor
+
+
+ +
instagram
+
+
+ +
intersect
+
+
+ +
journal-album
+
+
+ +
journal-arrow-down
+
+
+ +
journal-arrow-up
+
+
+ +
journal-bookmark-fill
+
+
+ +
journal-bookmark
+
+
+ +
journal-check
+
+
+ +
journal-code
+
+
+ +
journal-medical
+
+
+ +
journal-minus
+
+
+ +
journal-plus
+
+
+ +
journal-richtext
+
+
+ +
journal-text
+
+
+ +
journal-x
+
+
+ +
journal
+
+
+ +
journals
+
+
+ +
joystick
+
+
+ +
justify-left
+
+
+ +
justify-right
+
+
+ +
justify
+
+
+ +
kanban-fill
+
+
+ +
kanban
+
+
+ +
key-fill
+
+
+ +
key
+
+
+ +
keyboard-fill
+
+
+ +
keyboard
+
+
+ +
ladder
+
+
+ +
lamp-fill
+
+
+ +
lamp
+
+
+ +
laptop-fill
+
+
+ +
laptop
+
+
+ +
layer-backward
+
+
+ +
layer-forward
+
+
+ +
layers-fill
+
+
+ +
layers-half
+
+
+ +
layers
+
+
+ +
layout-sidebar-inset-reverse
+
+
+ +
layout-sidebar-inset
+
+
+ +
layout-sidebar-reverse
+
+
+ +
layout-sidebar
+
+
+ +
layout-split
+
+
+ +
layout-text-sidebar-reverse
+
+
+ +
layout-text-sidebar
+
+
+ +
layout-text-window-reverse
+
+
+ +
layout-text-window
+
+
+ +
layout-three-columns
+
+
+ +
layout-wtf
+
+
+ +
life-preserver
+
+
+ +
lightbulb-fill
+
+
+ +
lightbulb-off-fill
+
+
+ +
lightbulb-off
+
+
+ +
lightbulb
+
+
+ +
lightning-charge-fill
+
+
+ +
lightning-charge
+
+
+ +
lightning-fill
+
+
+ +
lightning
+
+
+ +
line
+
+
+ +
link-45deg
+
+
+ +
link
+
+
+ +
linkedin
+
+
+ +
list-check
+
+
+ +
list-columns-reverse
+
+
+ +
list-columns
+
+
+ +
list-nested
+
+
+ +
list-ol
+
+
+ +
list-stars
+
+
+ +
list-task
+
+
+ +
list-ul
+
+
+ +
list
+
+
+ +
lock-fill
+
+
+ +
lock
+
+
+ +
magic
+
+
+ +
magnet-fill
+
+
+ +
magnet
+
+
+ +
mailbox
+
+
+ +
mailbox2
+
+
+ +
map-fill
+
+
+ +
map
+
+
+ +
markdown-fill
+
+
+ +
markdown
+
+
+ +
mask
+
+
+ +
mastodon
+
+
+ +
medium
+
+
+ +
megaphone-fill
+
+
+ +
megaphone
+
+
+ +
memory
+
+
+ +
menu-app-fill
+
+
+ +
menu-app
+
+
+ +
menu-button-fill
+
+
+ +
menu-button-wide-fill
+
+
+ +
menu-button-wide
+
+
+ +
menu-button
+
+
+ +
menu-down
+
+
+ +
menu-up
+
+
+ +
messenger
+
+
+ +
meta
+
+
+ +
mic-fill
+
+
+ +
mic-mute-fill
+
+
+ +
mic-mute
+
+
+ +
mic
+
+
+ +
microsoft
+
+
+ +
minecart-loaded
+
+
+ +
minecart
+
+
+ +
modem-fill
+
+
+ +
modem
+
+
+ +
moisture
+
+
+ +
moon-fill
+
+
+ +
moon-stars-fill
+
+
+ +
moon-stars
+
+
+ +
moon
+
+
+ +
mortarboard-fill
+
+
+ +
mortarboard
+
+
+ +
motherboard-fill
+
+
+ +
motherboard
+
+
+ +
mouse-fill
+
+
+ +
mouse
+
+
+ +
mouse2-fill
+
+
+ +
mouse2
+
+
+ +
mouse3-fill
+
+
+ +
mouse3
+
+
+ +
music-note-beamed
+
+
+ +
music-note-list
+
+
+ +
music-note
+
+
+ +
music-player-fill
+
+
+ +
music-player
+
+
+ +
newspaper
+
+
+ +
nintendo-switch
+
+
+ +
node-minus-fill
+
+
+ +
node-minus
+
+
+ +
node-plus-fill
+
+
+ +
node-plus
+
+
+ +
nut-fill
+
+
+ +
nut
+
+
+ +
octagon-fill
+
+
+ +
octagon-half
+
+
+ +
octagon
+
+
+ +
optical-audio-fill
+
+
+ +
optical-audio
+
+
+ +
option
+
+
+ +
outlet
+
+
+ +
paint-bucket
+
+
+ +
palette-fill
+
+
+ +
palette
+
+
+ +
palette2
+
+
+ +
paperclip
+
+
+ +
paragraph
+
+
+ +
patch-check-fill
+
+
+ +
patch-check
+
+
+ +
patch-exclamation-fill
+
+
+ +
patch-exclamation
+
+
+ +
patch-minus-fill
+
+
+ +
patch-minus
+
+
+ +
patch-plus-fill
+
+
+ +
patch-plus
+
+
+ +
patch-question-fill
+
+
+ +
patch-question
+
+
+ +
pause-btn-fill
+
+
+ +
pause-btn
+
+
+ +
pause-circle-fill
+
+
+ +
pause-circle
+
+
+ +
pause-fill
+
+
+ +
pause
+
+
+ +
paypal
+
+
+ +
pc-display-horizontal
+
+
+ +
pc-display
+
+
+ +
pc-horizontal
+
+
+ +
pc
+
+
+ +
pci-card
+
+
+ +
peace-fill
+
+
+ +
peace
+
+
+ +
pen-fill
+
+
+ +
pen
+
+
+ +
pencil-fill
+
+
+ +
pencil-square
+
+
+ +
pencil
+
+
+ +
pentagon-fill
+
+
+ +
pentagon-half
+
+
+ +
pentagon
+
+
+ +
people-fill
+
+
+ +
people
+
+
+ +
percent
+
+
+ +
person-badge-fill
+
+
+ +
person-badge
+
+
+ +
person-bounding-box
+
+
+ +
person-check-fill
+
+
+ +
person-check
+
+
+ +
person-circle
+
+
+ +
person-dash-fill
+
+
+ +
person-dash
+
+
+ +
person-fill
+
+
+ +
person-heart
+
+
+ +
person-hearts
+
+
+ +
person-lines-fill
+
+
+ +
person-plus-fill
+
+
+ +
person-plus
+
+
+ +
person-rolodex
+
+
+ +
person-square
+
+
+ +
person-video
+
+
+ +
person-video2
+
+
+ +
person-video3
+
+
+ +
person-workspace
+
+
+ +
person-x-fill
+
+
+ +
person-x
+
+
+ +
person
+
+
+ +
phone-fill
+
+
+ +
phone-flip
+
+
+ +
phone-landscape-fill
+
+
+ +
phone-landscape
+
+
+ +
phone-vibrate-fill
+
+
+ +
phone-vibrate
+
+
+ +
phone
+
+
+ +
pie-chart-fill
+
+
+ +
pie-chart
+
+
+ +
piggy-bank-fill
+
+
+ +
piggy-bank
+
+
+ +
pin-angle-fill
+
+
+ +
pin-angle
+
+
+ +
pin-fill
+
+
+ +
pin-map-fill
+
+
+ +
pin-map
+
+
+ +
pin
+
+
+ +
pinterest
+
+
+ +
pip-fill
+
+
+ +
pip
+
+
+ +
play-btn-fill
+
+
+ +
play-btn
+
+
+ +
play-circle-fill
+
+
+ +
play-circle
+
+
+ +
play-fill
+
+
+ +
play
+
+
+ +
playstation
+
+
+ +
plug-fill
+
+
+ +
plug
+
+
+ +
plugin
+
+
+ +
plus-circle-dotted
+
+
+ +
plus-circle-fill
+
+
+ +
plus-circle
+
+
+ +
plus-lg
+
+
+ +
plus-slash-minus
+
+
+ +
plus-square-dotted
+
+
+ +
plus-square-fill
+
+
+ +
plus-square
+
+
+ +
plus
+
+
+ +
postage-fill
+
+
+ +
postage-heart-fill
+
+
+ +
postage-heart
+
+
+ +
postage
+
+
+ +
postcard-fill
+
+
+ +
postcard-heart-fill
+
+
+ +
postcard-heart
+
+
+ +
postcard
+
+
+ +
power
+
+
+ +
printer-fill
+
+
+ +
printer
+
+
+ +
projector-fill
+
+
+ +
projector
+
+
+ +
puzzle-fill
+
+
+ +
puzzle
+
+
+ +
qr-code-scan
+
+
+ +
qr-code
+
+
+ +
question-circle-fill
+
+
+ +
question-circle
+
+
+ +
question-diamond-fill
+
+
+ +
question-diamond
+
+
+ +
question-lg
+
+
+ +
question-octagon-fill
+
+
+ +
question-octagon
+
+
+ +
question-square-fill
+
+
+ +
question-square
+
+
+ +
question
+
+
+ +
quora
+
+
+ +
quote
+
+
+ +
radioactive
+
+
+ +
rainbow
+
+
+ +
receipt-cutoff
+
+
+ +
receipt
+
+
+ +
reception-0
+
+
+ +
reception-1
+
+
+ +
reception-2
+
+
+ +
reception-3
+
+
+ +
reception-4
+
+
+ +
record-btn-fill
+
+
+ +
record-btn
+
+
+ +
record-circle-fill
+
+
+ +
record-circle
+
+
+ +
record-fill
+
+
+ +
record
+
+
+ +
record2-fill
+
+
+ +
record2
+
+
+ +
recycle
+
+
+ +
reddit
+
+
+ +
reply-all-fill
+
+
+ +
reply-all
+
+
+ +
reply-fill
+
+
+ +
reply
+
+
+ +
robot
+
+
+ +
router-fill
+
+
+ +
router
+
+
+ +
rss-fill
+
+
+ +
rss
+
+
+ +
rulers
+
+
+ +
safe-fill
+
+
+ +
safe
+
+
+ +
safe2-fill
+
+
+ +
safe2
+
+
+ +
save-fill
+
+
+ +
save
+
+
+ +
save2-fill
+
+
+ +
save2
+
+
+ +
scissors
+
+
+ +
screwdriver
+
+
+ +
sd-card-fill
+
+
+ +
sd-card
+
+
+ +
search-heart-fill
+
+
+ +
search-heart
+
+
+ +
search
+
+
+ +
segmented-nav
+
+
+ +
send-check-fill
+
+
+ +
send-check
+
+
+ +
send-dash-fill
+
+
+ +
send-dash
+
+
+ +
send-exclamation-fill
+
+
+ +
send-exclamation
+
+
+ +
send-fill
+
+
+ +
send-plus-fill
+
+
+ +
send-plus
+
+
+ +
send-slash-fill
+
+
+ +
send-slash
+
+
+ +
send-x-fill
+
+
+ +
send-x
+
+
+ +
send
+
+
+ +
server
+
+
+ +
share-fill
+
+
+ +
share
+
+
+ +
shield-check
+
+
+ +
shield-exclamation
+
+
+ +
shield-fill-check
+
+
+ +
shield-fill-exclamation
+
+
+ +
shield-fill-minus
+
+
+ +
shield-fill-plus
+
+
+ +
shield-fill-x
+
+
+ +
shield-fill
+
+
+ +
shield-lock-fill
+
+
+ +
shield-lock
+
+
+ +
shield-minus
+
+
+ +
shield-plus
+
+
+ +
shield-shaded
+
+
+ +
shield-slash-fill
+
+
+ +
shield-slash
+
+
+ +
shield-x
+
+
+ +
shield
+
+
+ +
shift-fill
+
+
+ +
shift
+
+
+ +
shop-window
+
+
+ +
shop
+
+
+ +
shuffle
+
+
+ +
signal
+
+
+ +
signpost-2-fill
+
+
+ +
signpost-2
+
+
+ +
signpost-fill
+
+
+ +
signpost-split-fill
+
+
+ +
signpost-split
+
+
+ +
signpost
+
+
+ +
sim-fill
+
+
+ +
sim
+
+
+ +
skip-backward-btn-fill
+
+
+ +
skip-backward-btn
+
+
+ +
skip-backward-circle-fill
+
+
+ +
skip-backward-circle
+
+
+ +
skip-backward-fill
+
+
+ +
skip-backward
+
+
+ +
skip-end-btn-fill
+
+
+ +
skip-end-btn
+
+
+ +
skip-end-circle-fill
+
+
+ +
skip-end-circle
+
+
+ +
skip-end-fill
+
+
+ +
skip-end
+
+
+ +
skip-forward-btn-fill
+
+
+ +
skip-forward-btn
+
+
+ +
skip-forward-circle-fill
+
+
+ +
skip-forward-circle
+
+
+ +
skip-forward-fill
+
+
+ +
skip-forward
+
+
+ +
skip-start-btn-fill
+
+
+ +
skip-start-btn
+
+
+ +
skip-start-circle-fill
+
+
+ +
skip-start-circle
+
+
+ +
skip-start-fill
+
+
+ +
skip-start
+
+
+ +
skype
+
+
+ +
slack
+
+
+ +
slash-circle-fill
+
+
+ +
slash-circle
+
+
+ +
slash-lg
+
+
+ +
slash-square-fill
+
+
+ +
slash-square
+
+
+ +
slash
+
+
+ +
sliders
+
+
+ +
sliders2-vertical
+
+
+ +
sliders2
+
+
+ +
smartwatch
+
+
+ +
snapchat
+
+
+ +
snow
+
+
+ +
snow2
+
+
+ +
snow3
+
+
+ +
sort-alpha-down-alt
+
+
+ +
sort-alpha-down
+
+
+ +
sort-alpha-up-alt
+
+
+ +
sort-alpha-up
+
+
+ +
sort-down-alt
+
+
+ +
sort-down
+
+
+ +
sort-numeric-down-alt
+
+
+ +
sort-numeric-down
+
+
+ +
sort-numeric-up-alt
+
+
+ +
sort-numeric-up
+
+
+ +
sort-up-alt
+
+
+ +
sort-up
+
+
+ +
soundwave
+
+
+ +
speaker-fill
+
+
+ +
speaker
+
+
+ +
speedometer
+
+
+ +
speedometer2
+
+
+ +
spellcheck
+
+
+ +
spotify
+
+
+ +
square-fill
+
+
+ +
square-half
+
+
+ +
square
+
+
+ +
stack-overflow
+
+
+ +
stack
+
+
+ +
star-fill
+
+
+ +
star-half
+
+
+ +
star
+
+
+ +
stars
+
+
+ +
steam
+
+
+ +
stickies-fill
+
+
+ +
stickies
+
+
+ +
sticky-fill
+
+
+ +
sticky
+
+
+ +
stop-btn-fill
+
+
+ +
stop-btn
+
+
+ +
stop-circle-fill
+
+
+ +
stop-circle
+
+
+ +
stop-fill
+
+
+ +
stop
+
+
+ +
stoplights-fill
+
+
+ +
stoplights
+
+
+ +
stopwatch-fill
+
+
+ +
stopwatch
+
+
+ +
strava
+
+
+ +
subtract
+
+
+ +
suit-club-fill
+
+
+ +
suit-club
+
+
+ +
suit-diamond-fill
+
+
+ +
suit-diamond
+
+
+ +
suit-heart-fill
+
+
+ +
suit-heart
+
+
+ +
suit-spade-fill
+
+
+ +
suit-spade
+
+
+ +
sun-fill
+
+
+ +
sun
+
+
+ +
sunglasses
+
+
+ +
sunrise-fill
+
+
+ +
sunrise
+
+
+ +
sunset-fill
+
+
+ +
sunset
+
+
+ +
symmetry-horizontal
+
+
+ +
symmetry-vertical
+
+
+ +
table
+
+
+ +
tablet-fill
+
+
+ +
tablet-landscape-fill
+
+
+ +
tablet-landscape
+
+
+ +
tablet
+
+
+ +
tag-fill
+
+
+ +
tag
+
+
+ +
tags-fill
+
+
+ +
tags
+
+
+ +
telegram
+
+
+ +
telephone-fill
+
+
+ +
telephone-forward-fill
+
+
+ +
telephone-forward
+
+
+ +
telephone-inbound-fill
+
+
+ +
telephone-inbound
+
+
+ +
telephone-minus-fill
+
+
+ +
telephone-minus
+
+
+ +
telephone-outbound-fill
+
+
+ +
telephone-outbound
+
+
+ +
telephone-plus-fill
+
+
+ +
telephone-plus
+
+
+ +
telephone-x-fill
+
+
+ +
telephone-x
+
+
+ +
telephone
+
+
+ +
terminal-dash
+
+
+ +
terminal-fill
+
+
+ +
terminal-plus
+
+
+ +
terminal-split
+
+
+ +
terminal-x
+
+
+ +
terminal
+
+
+ +
text-center
+
+
+ +
text-indent-left
+
+
+ +
text-indent-right
+
+
+ +
text-left
+
+
+ +
text-paragraph
+
+
+ +
text-right
+
+
+ +
textarea-resize
+
+
+ +
textarea-t
+
+
+ +
textarea
+
+
+ +
thermometer-half
+
+
+ +
thermometer-high
+
+
+ +
thermometer-low
+
+
+ +
thermometer-snow
+
+
+ +
thermometer-sun
+
+
+ +
thermometer
+
+
+ +
three-dots-vertical
+
+
+ +
three-dots
+
+
+ +
thunderbolt-fill
+
+
+ +
thunderbolt
+
+
+ +
ticket-detailed-fill
+
+
+ +
ticket-detailed
+
+
+ +
ticket-fill
+
+
+ +
ticket-perforated-fill
+
+
+ +
ticket-perforated
+
+
+ +
ticket
+
+
+ +
tiktok
+
+
+ +
toggle-off
+
+
+ +
toggle-on
+
+
+ +
toggle2-off
+
+
+ +
toggle2-on
+
+
+ +
toggles
+
+
+ +
toggles2
+
+
+ +
tools
+
+
+ +
tornado
+
+
+ +
translate
+
+
+ +
trash-fill
+
+
+ +
trash
+
+
+ +
trash2-fill
+
+
+ +
trash2
+
+
+ +
trash3-fill
+
+
+ +
trash3
+
+
+ +
tree-fill
+
+
+ +
tree
+
+
+ +
triangle-fill
+
+
+ +
triangle-half
+
+
+ +
triangle
+
+
+ +
trophy-fill
+
+
+ +
trophy
+
+
+ +
tropical-storm
+
+
+ +
truck-flatbed
+
+
+ +
truck
+
+
+ +
tsunami
+
+
+ +
tv-fill
+
+
+ +
tv
+
+
+ +
twitch
+
+
+ +
twitter
+
+
+ +
type-bold
+
+
+ +
type-h1
+
+
+ +
type-h2
+
+
+ +
type-h3
+
+
+ +
type-italic
+
+
+ +
type-strikethrough
+
+
+ +
type-underline
+
+
+ +
type
+
+
+ +
ui-checks-grid
+
+
+ +
ui-checks
+
+
+ +
ui-radios-grid
+
+
+ +
ui-radios
+
+
+ +
umbrella-fill
+
+
+ +
umbrella
+
+
+ +
union
+
+
+ +
unlock-fill
+
+
+ +
unlock
+
+
+ +
upc-scan
+
+
+ +
upc
+
+
+ +
upload
+
+
+ +
usb-c-fill
+
+
+ +
usb-c
+
+
+ +
usb-drive-fill
+
+
+ +
usb-drive
+
+
+ +
usb-fill
+
+
+ +
usb-micro-fill
+
+
+ +
usb-micro
+
+
+ +
usb-mini-fill
+
+
+ +
usb-mini
+
+
+ +
usb-plug-fill
+
+
+ +
usb-plug
+
+
+ +
usb-symbol
+
+
+ +
usb
+
+
+ +
valentine
+
+
+ +
valentine2
+
+
+ +
vector-pen
+
+
+ +
view-list
+
+
+ +
view-stacked
+
+
+ +
vimeo
+
+
+ +
vinyl-fill
+
+
+ +
vinyl
+
+
+ +
voicemail
+
+
+ +
volume-down-fill
+
+
+ +
volume-down
+
+
+ +
volume-mute-fill
+
+
+ +
volume-mute
+
+
+ +
volume-off-fill
+
+
+ +
volume-off
+
+
+ +
volume-up-fill
+
+
+ +
volume-up
+
+
+ +
vr
+
+
+ +
wallet-fill
+
+
+ +
wallet
+
+
+ +
wallet2
+
+
+ +
watch
+
+
+ +
water
+
+
+ +
webcam-fill
+
+
+ +
webcam
+
+
+ +
whatsapp
+
+
+ +
wifi-1
+
+
+ +
wifi-2
+
+
+ +
wifi-off
+
+
+ +
wifi
+
+
+ +
wind
+
+
+ +
window-dash
+
+
+ +
window-desktop
+
+
+ +
window-dock
+
+
+ +
window-fullscreen
+
+
+ +
window-plus
+
+
+ +
window-sidebar
+
+
+ +
window-split
+
+
+ +
window-stack
+
+
+ +
window-x
+
+
+ +
window
+
+
+ +
windows
+
+
+ +
wordpress
+
+
+ +
wrench-adjustable-circle-fill
+
+
+ +
wrench-adjustable-circle
+
+
+ +
wrench-adjustable
+
+
+ +
wrench
+
+
+ +
x-circle-fill
+
+
+ +
x-circle
+
+
+ +
x-diamond-fill
+
+
+ +
x-diamond
+
+
+ +
x-lg
+
+
+ +
x-octagon-fill
+
+
+ +
x-octagon
+
+
+ +
x-square-fill
+
+
+ +
x-square
+
+
+ +
x
+
+
+ +
xbox
+
+
+ +
yin-yang
+
+
+ +
youtube
+
+
+ +
zoom-in
+
+
+ +
zoom-out
+
+
+ + + diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/infinity.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/infinity.svg new file mode 100644 index 0000000..e9dd437 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/infinity.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle-fill.svg new file mode 100644 index 0000000..9d38231 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle.svg new file mode 100644 index 0000000..8f48f86 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-lg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-lg.svg new file mode 100644 index 0000000..d1b988e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-lg.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square-fill.svg new file mode 100644 index 0000000..c2e5a66 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square.svg new file mode 100644 index 0000000..71e2818 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info.svg new file mode 100644 index 0000000..9d061b4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/info.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor-text.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor-text.svg new file mode 100644 index 0000000..f212111 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor-text.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor.svg new file mode 100644 index 0000000..3a89bb7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/input-cursor.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/instagram.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/instagram.svg new file mode 100644 index 0000000..0b5c5ce --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/instagram.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/intersect.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/intersect.svg new file mode 100644 index 0000000..2d8c329 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/intersect.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-album.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-album.svg new file mode 100644 index 0000000..2504b3d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-album.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-down.svg new file mode 100644 index 0000000..79c313d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-up.svg new file mode 100644 index 0000000..8423461 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-arrow-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark-fill.svg new file mode 100644 index 0000000..03e2476 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark.svg new file mode 100644 index 0000000..6652764 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-bookmark.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-check.svg new file mode 100644 index 0000000..41b97e9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-check.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-code.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-code.svg new file mode 100644 index 0000000..82098b9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-code.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-medical.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-medical.svg new file mode 100644 index 0000000..5500110 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-medical.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-minus.svg new file mode 100644 index 0000000..c8cd4d8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-minus.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-plus.svg new file mode 100644 index 0000000..fa6d702 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-plus.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-richtext.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-richtext.svg new file mode 100644 index 0000000..14b0e1f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-richtext.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-text.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-text.svg new file mode 100644 index 0000000..9b66f43 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-text.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-x.svg new file mode 100644 index 0000000..2ca24f4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal-x.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal.svg new file mode 100644 index 0000000..941c987 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journal.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journals.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journals.svg new file mode 100644 index 0000000..03f6dad --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/journals.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/joystick.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/joystick.svg new file mode 100644 index 0000000..a8a9027 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/joystick.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-left.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-left.svg new file mode 100644 index 0000000..68859b8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-right.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-right.svg new file mode 100644 index 0000000..1efe4f3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify.svg new file mode 100644 index 0000000..009bd72 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/justify.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban-fill.svg new file mode 100644 index 0000000..d633a53 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban.svg new file mode 100644 index 0000000..c5cdaaf --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/kanban.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key-fill.svg new file mode 100644 index 0000000..25a6d45 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key.svg new file mode 100644 index 0000000..dbaae3f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/key.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard-fill.svg new file mode 100644 index 0000000..876321d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard.svg new file mode 100644 index 0000000..996c1eb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/keyboard.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ladder.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ladder.svg new file mode 100644 index 0000000..fd9182a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ladder.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp-fill.svg new file mode 100644 index 0000000..ff91f4b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp.svg new file mode 100644 index 0000000..6c50a70 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lamp.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop-fill.svg new file mode 100644 index 0000000..5b1755d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop.svg new file mode 100644 index 0000000..0fc463d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/laptop.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-backward.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-backward.svg new file mode 100644 index 0000000..073034a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-backward.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-forward.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-forward.svg new file mode 100644 index 0000000..ffc6e2a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layer-forward.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-fill.svg new file mode 100644 index 0000000..8af0b1c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-half.svg new file mode 100644 index 0000000..a054e25 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers.svg new file mode 100644 index 0000000..ac2f5b2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layers.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset-reverse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset-reverse.svg new file mode 100644 index 0000000..5b6f324 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset-reverse.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset.svg new file mode 100644 index 0000000..8dc0243 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-inset.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-reverse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-reverse.svg new file mode 100644 index 0000000..8ab9509 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar-reverse.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar.svg new file mode 100644 index 0000000..1cfc86e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-sidebar.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-split.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-split.svg new file mode 100644 index 0000000..71f33d2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-split.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar-reverse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar-reverse.svg new file mode 100644 index 0000000..46252d5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar-reverse.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar.svg new file mode 100644 index 0000000..5effada --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-sidebar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window-reverse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window-reverse.svg new file mode 100644 index 0000000..fb34840 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window-reverse.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window.svg new file mode 100644 index 0000000..0aef110 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-text-window.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-three-columns.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-three-columns.svg new file mode 100644 index 0000000..6d358d6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-three-columns.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-wtf.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-wtf.svg new file mode 100644 index 0000000..b603f8f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/layout-wtf.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/life-preserver.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/life-preserver.svg new file mode 100644 index 0000000..6466ea2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/life-preserver.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-fill.svg new file mode 100644 index 0000000..9903950 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off-fill.svg new file mode 100644 index 0000000..7d9600e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off.svg new file mode 100644 index 0000000..5675e9c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb.svg new file mode 100644 index 0000000..c13f627 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightbulb.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge-fill.svg new file mode 100644 index 0000000..5e197fb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge.svg new file mode 100644 index 0000000..8a97432 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-charge.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-fill.svg new file mode 100644 index 0000000..4d05a2b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning.svg new file mode 100644 index 0000000..8737060 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lightning.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/line.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/line.svg new file mode 100644 index 0000000..bedc051 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/line.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link-45deg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link-45deg.svg new file mode 100644 index 0000000..127956a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link-45deg.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link.svg new file mode 100644 index 0000000..df35bc8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/link.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/linkedin.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/linkedin.svg new file mode 100644 index 0000000..4c4efe5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/linkedin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-check.svg new file mode 100644 index 0000000..34dd420 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns-reverse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns-reverse.svg new file mode 100644 index 0000000..2cb5078 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns-reverse.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns.svg new file mode 100644 index 0000000..d04a30f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-columns.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-nested.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-nested.svg new file mode 100644 index 0000000..21c9a7d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-nested.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ol.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ol.svg new file mode 100644 index 0000000..5782568 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ol.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-stars.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-stars.svg new file mode 100644 index 0000000..88dce52 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-stars.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-task.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-task.svg new file mode 100644 index 0000000..8118190 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-task.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ul.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ul.svg new file mode 100644 index 0000000..217d153 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list-ul.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list.svg new file mode 100644 index 0000000..e039056 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/list.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock-fill.svg new file mode 100644 index 0000000..9fb8f7b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock.svg new file mode 100644 index 0000000..b50a68e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/lock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magic.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magic.svg new file mode 100644 index 0000000..3df2ec0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magic.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet-fill.svg new file mode 100644 index 0000000..9ca1865 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet.svg new file mode 100644 index 0000000..aab1763 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/magnet.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox.svg new file mode 100644 index 0000000..e2ac2f9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox2.svg new file mode 100644 index 0000000..60a523b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mailbox2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map-fill.svg new file mode 100644 index 0000000..6097c5f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map.svg new file mode 100644 index 0000000..f9dbb08 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/map.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown-fill.svg new file mode 100644 index 0000000..b87e236 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown.svg new file mode 100644 index 0000000..f9933a6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/markdown.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mask.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mask.svg new file mode 100644 index 0000000..3bfe141 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mask.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mastodon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mastodon.svg new file mode 100644 index 0000000..23b34f5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mastodon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/medium.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/medium.svg new file mode 100644 index 0000000..cc46876 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/medium.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone-fill.svg new file mode 100644 index 0000000..237e814 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone.svg new file mode 100644 index 0000000..834083c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/megaphone.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/memory.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/memory.svg new file mode 100644 index 0000000..cdc2943 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/memory.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app-fill.svg new file mode 100644 index 0000000..c41c6fb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app.svg new file mode 100644 index 0000000..36e57df --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-app.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-fill.svg new file mode 100644 index 0000000..034b64d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide-fill.svg new file mode 100644 index 0000000..d6e17da --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide.svg new file mode 100644 index 0000000..d67ba6a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button-wide.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button.svg new file mode 100644 index 0000000..4e0fff9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-button.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-down.svg new file mode 100644 index 0000000..b2d84b2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-up.svg new file mode 100644 index 0000000..fb35e8d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/menu-up.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/messenger.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/messenger.svg new file mode 100644 index 0000000..5c6d37d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/messenger.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/meta.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/meta.svg new file mode 100644 index 0000000..2c6885d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/meta.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-fill.svg new file mode 100644 index 0000000..9be58e9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute-fill.svg new file mode 100644 index 0000000..cc325a0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute.svg new file mode 100644 index 0000000..5a520a1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic-mute.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic.svg new file mode 100644 index 0000000..57be2e5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mic.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/microsoft.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/microsoft.svg new file mode 100644 index 0000000..d28281f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/microsoft.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart-loaded.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart-loaded.svg new file mode 100644 index 0000000..8a75457 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart-loaded.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart.svg new file mode 100644 index 0000000..7f3ad00 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/minecart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem-fill.svg new file mode 100644 index 0000000..1fe97be --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem.svg new file mode 100644 index 0000000..873090d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/modem.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moisture.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moisture.svg new file mode 100644 index 0000000..732f4ac --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moisture.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-fill.svg new file mode 100644 index 0000000..1149676 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars-fill.svg new file mode 100644 index 0000000..d2e1d6e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars.svg new file mode 100644 index 0000000..b25ef86 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon-stars.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon.svg new file mode 100644 index 0000000..4cd8820 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/moon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard-fill.svg new file mode 100644 index 0000000..7f5fb48 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard.svg new file mode 100644 index 0000000..ed82b6a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mortarboard.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard-fill.svg new file mode 100644 index 0000000..bf15e96 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard.svg new file mode 100644 index 0000000..ed13d0c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/motherboard.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse-fill.svg new file mode 100644 index 0000000..bd0b5eb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse.svg new file mode 100644 index 0000000..40976e0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2-fill.svg new file mode 100644 index 0000000..283d1cd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2.svg new file mode 100644 index 0000000..359da4d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3-fill.svg new file mode 100644 index 0000000..de6dbc7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3.svg new file mode 100644 index 0000000..d042bfd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/mouse3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-beamed.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-beamed.svg new file mode 100644 index 0000000..04cedf0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-beamed.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-list.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-list.svg new file mode 100644 index 0000000..5c306bd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note-list.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note.svg new file mode 100644 index 0000000..1125a66 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-note.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player-fill.svg new file mode 100644 index 0000000..6619d1e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player.svg new file mode 100644 index 0000000..2d50a63 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/music-player.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/newspaper.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/newspaper.svg new file mode 100644 index 0000000..7d7fa71 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/newspaper.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nintendo-switch.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nintendo-switch.svg new file mode 100644 index 0000000..0f1e2ac --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nintendo-switch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus-fill.svg new file mode 100644 index 0000000..32430b9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus.svg new file mode 100644 index 0000000..b1accd4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-minus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus-fill.svg new file mode 100644 index 0000000..e5ee855 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus.svg new file mode 100644 index 0000000..085f04f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/node-plus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut-fill.svg new file mode 100644 index 0000000..4babc03 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut.svg new file mode 100644 index 0000000..4912d48 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/nut.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-fill.svg new file mode 100644 index 0000000..c128317 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-half.svg new file mode 100644 index 0000000..d95240a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon.svg new file mode 100644 index 0000000..9f3657e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/octagon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio-fill.svg new file mode 100644 index 0000000..5bdfd82 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio.svg new file mode 100644 index 0000000..7a38b83 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/optical-audio.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/option.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/option.svg new file mode 100644 index 0000000..d7702b1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/option.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/outlet.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/outlet.svg new file mode 100644 index 0000000..b48af60 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/outlet.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paint-bucket.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paint-bucket.svg new file mode 100644 index 0000000..ee15d10 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paint-bucket.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette-fill.svg new file mode 100644 index 0000000..7dc5ecd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette.svg new file mode 100644 index 0000000..fea76d9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette2.svg new file mode 100644 index 0000000..5d140b3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/palette2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paperclip.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paperclip.svg new file mode 100644 index 0000000..00f311d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paperclip.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paragraph.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paragraph.svg new file mode 100644 index 0000000..999cb53 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paragraph.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check-fill.svg new file mode 100644 index 0000000..1301415 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check.svg new file mode 100644 index 0000000..2dd799e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation-fill.svg new file mode 100644 index 0000000..fd900c4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation.svg new file mode 100644 index 0000000..153d97d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-exclamation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus-fill.svg new file mode 100644 index 0000000..12f35c2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus.svg new file mode 100644 index 0000000..f6024f9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-minus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus-fill.svg new file mode 100644 index 0000000..1a79d79 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus.svg new file mode 100644 index 0000000..b9a7846 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question-fill.svg new file mode 100644 index 0000000..665588b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question.svg new file mode 100644 index 0000000..ef4ca58 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/patch-question.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn-fill.svg new file mode 100644 index 0000000..efca142 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn.svg new file mode 100644 index 0000000..0e9eb3a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle-fill.svg new file mode 100644 index 0000000..5e3525f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle.svg new file mode 100644 index 0000000..1b6b64a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-fill.svg new file mode 100644 index 0000000..68285b2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause.svg new file mode 100644 index 0000000..22478ea --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pause.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paypal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paypal.svg new file mode 100644 index 0000000..41bd536 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/paypal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display-horizontal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display-horizontal.svg new file mode 100644 index 0000000..2013f15 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display-horizontal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display.svg new file mode 100644 index 0000000..f5d09da --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-display.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-horizontal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-horizontal.svg new file mode 100644 index 0000000..9ae513a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc-horizontal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc.svg new file mode 100644 index 0000000..f0f280d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pc.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pci-card.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pci-card.svg new file mode 100644 index 0000000..600a5d0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pci-card.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace-fill.svg new file mode 100644 index 0000000..c8ed5bd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace.svg new file mode 100644 index 0000000..3e4420b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/peace.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen-fill.svg new file mode 100644 index 0000000..b7bb337 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen.svg new file mode 100644 index 0000000..8eb3be7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pen.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-fill.svg new file mode 100644 index 0000000..59d2830 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-square.svg new file mode 100644 index 0000000..b8c90d5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil.svg new file mode 100644 index 0000000..f8dbfeb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pencil.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-fill.svg new file mode 100644 index 0000000..9c80789 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-half.svg new file mode 100644 index 0000000..305125c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon.svg new file mode 100644 index 0000000..b6f5fe3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pentagon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people-fill.svg new file mode 100644 index 0000000..2c7389d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people.svg new file mode 100644 index 0000000..528933d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/people.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/percent.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/percent.svg new file mode 100644 index 0000000..8af2bc4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/percent.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge-fill.svg new file mode 100644 index 0000000..d9ebe67 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge.svg new file mode 100644 index 0000000..d071d44 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-badge.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-bounding-box.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-bounding-box.svg new file mode 100644 index 0000000..92e662c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-bounding-box.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check-fill.svg new file mode 100644 index 0000000..872497a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check.svg new file mode 100644 index 0000000..c4b1e38 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-circle.svg new file mode 100644 index 0000000..fd7f2c9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash-fill.svg new file mode 100644 index 0000000..fd719f2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash.svg new file mode 100644 index 0000000..4c6cb79 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-dash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-fill.svg new file mode 100644 index 0000000..6e12768 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-heart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-heart.svg new file mode 100644 index 0000000..e9ebbf4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-heart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-hearts.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-hearts.svg new file mode 100644 index 0000000..06970be --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-hearts.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-lines-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-lines-fill.svg new file mode 100644 index 0000000..736421c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-lines-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus-fill.svg new file mode 100644 index 0000000..151ccfe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus.svg new file mode 100644 index 0000000..aac3a67 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-rolodex.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-rolodex.svg new file mode 100644 index 0000000..af898ca --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-rolodex.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-square.svg new file mode 100644 index 0000000..a7eb40e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video.svg new file mode 100644 index 0000000..b8c1995 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video2.svg new file mode 100644 index 0000000..3f4292e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video3.svg new file mode 100644 index 0000000..be38b24 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-video3.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-workspace.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-workspace.svg new file mode 100644 index 0000000..e72bea0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-workspace.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x-fill.svg new file mode 100644 index 0000000..d4903a6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x.svg new file mode 100644 index 0000000..d7ac8f6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person-x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person.svg new file mode 100644 index 0000000..022d1e9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/person.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-fill.svg new file mode 100644 index 0000000..a2dfd03 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-flip.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-flip.svg new file mode 100644 index 0000000..54e2d26 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-flip.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape-fill.svg new file mode 100644 index 0000000..295481c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape.svg new file mode 100644 index 0000000..65cd273 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-landscape.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate-fill.svg new file mode 100644 index 0000000..6e61ecc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate.svg new file mode 100644 index 0000000..f380cab --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone-vibrate.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone.svg new file mode 100644 index 0000000..3f3fd74 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/phone.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart-fill.svg new file mode 100644 index 0000000..6aa71eb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart.svg new file mode 100644 index 0000000..a20f6a7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pie-chart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank-fill.svg new file mode 100644 index 0000000..b44f35d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank.svg new file mode 100644 index 0000000..1d836ce --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/piggy-bank.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle-fill.svg new file mode 100644 index 0000000..3112c0b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle.svg new file mode 100644 index 0000000..a07b038 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-angle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-fill.svg new file mode 100644 index 0000000..f00b790 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map-fill.svg new file mode 100644 index 0000000..b8c8502 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map.svg new file mode 100644 index 0000000..f04129a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin-map.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin.svg new file mode 100644 index 0000000..45fd7de --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pinterest.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pinterest.svg new file mode 100644 index 0000000..b4fbc23 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pinterest.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip-fill.svg new file mode 100644 index 0000000..1869f78 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip.svg new file mode 100644 index 0000000..58f0638 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/pip.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn-fill.svg new file mode 100644 index 0000000..18b9167 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn.svg new file mode 100644 index 0000000..576e30b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle-fill.svg new file mode 100644 index 0000000..511ef37 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle.svg new file mode 100644 index 0000000..c93144a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-fill.svg new file mode 100644 index 0000000..28f2e67 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play.svg new file mode 100644 index 0000000..b3fd3dc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/play.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/playstation.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/playstation.svg new file mode 100644 index 0000000..f8ce05b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/playstation.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug-fill.svg new file mode 100644 index 0000000..d15b8e6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug.svg new file mode 100644 index 0000000..c5e6688 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plug.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plugin.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plugin.svg new file mode 100644 index 0000000..3f179a3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plugin.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-dotted.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-dotted.svg new file mode 100644 index 0000000..c69316e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-dotted.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-fill.svg new file mode 100644 index 0000000..f320116 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle.svg new file mode 100644 index 0000000..66308ef --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-lg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-lg.svg new file mode 100644 index 0000000..f821cc3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-lg.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-slash-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-slash-minus.svg new file mode 100644 index 0000000..44a8e0e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-slash-minus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-dotted.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-dotted.svg new file mode 100644 index 0000000..4ae7ad6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-dotted.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-fill.svg new file mode 100644 index 0000000..0d5e15c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square.svg new file mode 100644 index 0000000..15c4c44 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus.svg new file mode 100644 index 0000000..5b088c0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/plus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-fill.svg new file mode 100644 index 0000000..701a1c6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart-fill.svg new file mode 100644 index 0000000..a268901 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart.svg new file mode 100644 index 0000000..4d22b18 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage-heart.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage.svg new file mode 100644 index 0000000..cc49c70 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postage.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-fill.svg new file mode 100644 index 0000000..01b54dd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart-fill.svg new file mode 100644 index 0000000..5e551fb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart.svg new file mode 100644 index 0000000..e0f2f05 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard-heart.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard.svg new file mode 100644 index 0000000..827180e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/postcard.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/power.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/power.svg new file mode 100644 index 0000000..6fb9756 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/power.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer-fill.svg new file mode 100644 index 0000000..485d987 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer.svg new file mode 100644 index 0000000..60196bc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/printer.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector-fill.svg new file mode 100644 index 0000000..ff6a341 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector.svg new file mode 100644 index 0000000..218c6a5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/projector.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle-fill.svg new file mode 100644 index 0000000..e9bbfae --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle.svg new file mode 100644 index 0000000..c9b07a2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/puzzle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code-scan.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code-scan.svg new file mode 100644 index 0000000..7eb599e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code-scan.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code.svg new file mode 100644 index 0000000..bf5570d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/qr-code.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle-fill.svg new file mode 100644 index 0000000..d8e5e06 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle.svg new file mode 100644 index 0000000..1c8cbe7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond-fill.svg new file mode 100644 index 0000000..a86583b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond.svg new file mode 100644 index 0000000..a7d8233 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-diamond.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-lg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-lg.svg new file mode 100644 index 0000000..fa3452e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-lg.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon-fill.svg new file mode 100644 index 0000000..2ff954e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon.svg new file mode 100644 index 0000000..02e8ffe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-octagon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square-fill.svg new file mode 100644 index 0000000..dd72410 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square.svg new file mode 100644 index 0000000..d0a56ff --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question.svg new file mode 100644 index 0000000..05abe29 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/question.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quora.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quora.svg new file mode 100644 index 0000000..e90e571 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quora.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quote.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quote.svg new file mode 100644 index 0000000..03b45bf --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/quote.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/radioactive.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/radioactive.svg new file mode 100644 index 0000000..1b1072f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/radioactive.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rainbow.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rainbow.svg new file mode 100644 index 0000000..8e8aea7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rainbow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt-cutoff.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt-cutoff.svg new file mode 100644 index 0000000..27be3c0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt-cutoff.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt.svg new file mode 100644 index 0000000..9ea7283 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/receipt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-0.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-0.svg new file mode 100644 index 0000000..885bf3b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-0.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-1.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-1.svg new file mode 100644 index 0000000..3deafb6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-1.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-2.svg new file mode 100644 index 0000000..7dca57a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-3.svg new file mode 100644 index 0000000..b30d5fb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-4.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-4.svg new file mode 100644 index 0000000..611bdf1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reception-4.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn-fill.svg new file mode 100644 index 0000000..caa3ea1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn.svg new file mode 100644 index 0000000..4fd261c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle-fill.svg new file mode 100644 index 0000000..2c2429a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle.svg new file mode 100644 index 0000000..d45d91c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-fill.svg new file mode 100644 index 0000000..d474393 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record.svg new file mode 100644 index 0000000..27f82a9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2-fill.svg new file mode 100644 index 0000000..7648928 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2.svg new file mode 100644 index 0000000..43a1150 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/record2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/recycle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/recycle.svg new file mode 100644 index 0000000..e4fa6c0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/recycle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reddit.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reddit.svg new file mode 100644 index 0000000..b1c9cfe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reddit.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all-fill.svg new file mode 100644 index 0000000..7b77b06 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all.svg new file mode 100644 index 0000000..c95025b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-all.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-fill.svg new file mode 100644 index 0000000..b5a8722 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply.svg new file mode 100644 index 0000000..c2dc098 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/reply.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/robot.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/robot.svg new file mode 100644 index 0000000..526cb99 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/robot.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router-fill.svg new file mode 100644 index 0000000..de050cf --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router-fill.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router.svg new file mode 100644 index 0000000..8fa22d0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/router.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss-fill.svg new file mode 100644 index 0000000..39bef06 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss.svg new file mode 100644 index 0000000..be41f20 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rss.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rulers.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rulers.svg new file mode 100644 index 0000000..e9891c9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/rulers.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe-fill.svg new file mode 100644 index 0000000..1036d67 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe.svg new file mode 100644 index 0000000..fb5b7cb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2-fill.svg new file mode 100644 index 0000000..d1d37f2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2.svg new file mode 100644 index 0000000..37bfbe8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/safe2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save-fill.svg new file mode 100644 index 0000000..0a43dc1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save.svg new file mode 100644 index 0000000..26b8aed --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2-fill.svg new file mode 100644 index 0000000..45feb59 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2.svg new file mode 100644 index 0000000..52bc9e4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/save2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/scissors.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/scissors.svg new file mode 100644 index 0000000..ab71b0d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/scissors.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/screwdriver.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/screwdriver.svg new file mode 100644 index 0000000..dc9c374 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/screwdriver.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card-fill.svg new file mode 100644 index 0000000..9fe36b6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card.svg new file mode 100644 index 0000000..12ed59f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sd-card.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart-fill.svg new file mode 100644 index 0000000..54e31c7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart.svg new file mode 100644 index 0000000..92ea059 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search-heart.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search.svg new file mode 100644 index 0000000..d3dc7ca --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/search.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/segmented-nav.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/segmented-nav.svg new file mode 100644 index 0000000..42323b2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/segmented-nav.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check-fill.svg new file mode 100644 index 0000000..4b0a56a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check.svg new file mode 100644 index 0000000..581ebbe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash-fill.svg new file mode 100644 index 0000000..254329c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash.svg new file mode 100644 index 0000000..abfbad3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-dash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation-fill.svg new file mode 100644 index 0000000..5a77e98 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation.svg new file mode 100644 index 0000000..149a7f7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-exclamation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-fill.svg new file mode 100644 index 0000000..2a84015 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus-fill.svg new file mode 100644 index 0000000..bea3738 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus.svg new file mode 100644 index 0000000..4120228 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash-fill.svg new file mode 100644 index 0000000..3345687 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash.svg new file mode 100644 index 0000000..782daf3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-slash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x-fill.svg new file mode 100644 index 0000000..ce102ba --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x.svg new file mode 100644 index 0000000..c8bc8bf --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send-x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send.svg new file mode 100644 index 0000000..c81fc95 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/send.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/server.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/server.svg new file mode 100644 index 0000000..ff85feb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/server.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share-fill.svg new file mode 100644 index 0000000..8b0ee88 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share.svg new file mode 100644 index 0000000..79d3075 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/share.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-check.svg new file mode 100644 index 0000000..ecbf543 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-check.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-exclamation.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-exclamation.svg new file mode 100644 index 0000000..825de04 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-exclamation.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-check.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-check.svg new file mode 100644 index 0000000..a72b2ba --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-check.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-exclamation.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-exclamation.svg new file mode 100644 index 0000000..b489a68 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-exclamation.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-minus.svg new file mode 100644 index 0000000..b9b9129 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-minus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-plus.svg new file mode 100644 index 0000000..aec96d1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-plus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-x.svg new file mode 100644 index 0000000..d384af4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill-x.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill.svg new file mode 100644 index 0000000..d1d877d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock-fill.svg new file mode 100644 index 0000000..e4c96b4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock.svg new file mode 100644 index 0000000..ff38425 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-lock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-minus.svg new file mode 100644 index 0000000..d1cedfd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-minus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-plus.svg new file mode 100644 index 0000000..77bcb1a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-shaded.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-shaded.svg new file mode 100644 index 0000000..9c4af1a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-shaded.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash-fill.svg new file mode 100644 index 0000000..015d11b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash.svg new file mode 100644 index 0000000..234afa2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-slash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-x.svg new file mode 100644 index 0000000..3fe1666 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield-x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield.svg new file mode 100644 index 0000000..18309d1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shield.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift-fill.svg new file mode 100644 index 0000000..da897bc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift.svg new file mode 100644 index 0000000..59a88ef --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shift.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop-window.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop-window.svg new file mode 100644 index 0000000..a306cfa --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop-window.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop.svg new file mode 100644 index 0000000..223d77b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shop.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shuffle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shuffle.svg new file mode 100644 index 0000000..83bf20c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/shuffle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signal.svg new file mode 100644 index 0000000..4220d48 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2-fill.svg new file mode 100644 index 0000000..cc51e51 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2.svg new file mode 100644 index 0000000..6a18b3b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-fill.svg new file mode 100644 index 0000000..f95f257 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split-fill.svg new file mode 100644 index 0000000..86aa086 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split.svg new file mode 100644 index 0000000..0168ae5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost-split.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost.svg new file mode 100644 index 0000000..90a8882 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/signpost.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim-fill.svg new file mode 100644 index 0000000..c8e2c29 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim.svg new file mode 100644 index 0000000..cc0e869 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sim.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn-fill.svg new file mode 100644 index 0000000..bf06429 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn.svg new file mode 100644 index 0000000..b04455e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle-fill.svg new file mode 100644 index 0000000..f6b6e4d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle.svg new file mode 100644 index 0000000..63e2a19 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-fill.svg new file mode 100644 index 0000000..a0ce53c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward.svg new file mode 100644 index 0000000..9be60fe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-backward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn-fill.svg new file mode 100644 index 0000000..55bf1ba --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn.svg new file mode 100644 index 0000000..6c5b044 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle-fill.svg new file mode 100644 index 0000000..e303750 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle.svg new file mode 100644 index 0000000..39e8cd3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-fill.svg new file mode 100644 index 0000000..fa90d3f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end.svg new file mode 100644 index 0000000..40d6fa9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-end.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn-fill.svg new file mode 100644 index 0000000..b767e9c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn.svg new file mode 100644 index 0000000..f67d3a8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle-fill.svg new file mode 100644 index 0000000..00cea35 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle.svg new file mode 100644 index 0000000..3b55d7e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-fill.svg new file mode 100644 index 0000000..c4071aa --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward.svg new file mode 100644 index 0000000..a1c4720 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-forward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn-fill.svg new file mode 100644 index 0000000..56a1370 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn.svg new file mode 100644 index 0000000..c86afbe --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle-fill.svg new file mode 100644 index 0000000..b6d13b0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle.svg new file mode 100644 index 0000000..f9664d9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-fill.svg new file mode 100644 index 0000000..c4295fc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start.svg new file mode 100644 index 0000000..a178e0e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skip-start.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skype.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skype.svg new file mode 100644 index 0000000..b3beaf9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/skype.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slack.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slack.svg new file mode 100644 index 0000000..f4aa6e6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slack.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle-fill.svg new file mode 100644 index 0000000..f703101 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle.svg new file mode 100644 index 0000000..4c1344b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-lg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-lg.svg new file mode 100644 index 0000000..161b6ec --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-lg.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square-fill.svg new file mode 100644 index 0000000..c7a3935 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square.svg new file mode 100644 index 0000000..ccf42bd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash.svg new file mode 100644 index 0000000..9616561 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/slash.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders.svg new file mode 100644 index 0000000..da4b835 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2-vertical.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2-vertical.svg new file mode 100644 index 0000000..c474281 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2-vertical.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2.svg new file mode 100644 index 0000000..86fa70c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sliders2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/smartwatch.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/smartwatch.svg new file mode 100644 index 0000000..696bd33 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/smartwatch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snapchat.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snapchat.svg new file mode 100644 index 0000000..505f55a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snapchat.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow.svg new file mode 100644 index 0000000..9b648a5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow2.svg new file mode 100644 index 0000000..cede335 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow3.svg new file mode 100644 index 0000000..75e5ef2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/snow3.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down-alt.svg new file mode 100644 index 0000000..fa4f4fa --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down-alt.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down.svg new file mode 100644 index 0000000..e0fcad0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-down.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up-alt.svg new file mode 100644 index 0000000..69c1a39 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up-alt.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up.svg new file mode 100644 index 0000000..0be5e68 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-alpha-up.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down-alt.svg new file mode 100644 index 0000000..d7f7fc8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down-alt.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down.svg new file mode 100644 index 0000000..848834c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down-alt.svg new file mode 100644 index 0000000..8c39a5a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down-alt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down.svg new file mode 100644 index 0000000..57a3fb0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-down.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up-alt.svg new file mode 100644 index 0000000..e8edf88 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up-alt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up.svg new file mode 100644 index 0000000..1cd0a37 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-numeric-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up-alt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up-alt.svg new file mode 100644 index 0000000..96650d5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up-alt.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up.svg new file mode 100644 index 0000000..2158801 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sort-up.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/soundwave.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/soundwave.svg new file mode 100644 index 0000000..288f108 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/soundwave.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker-fill.svg new file mode 100644 index 0000000..bae80e2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker.svg new file mode 100644 index 0000000..461626d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speaker.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer.svg new file mode 100644 index 0000000..5a0a43c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer2.svg new file mode 100644 index 0000000..d5676df --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/speedometer2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spellcheck.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spellcheck.svg new file mode 100644 index 0000000..029950f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spellcheck.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spotify.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spotify.svg new file mode 100644 index 0000000..31b4238 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/spotify.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-fill.svg new file mode 100644 index 0000000..31bae4f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-half.svg new file mode 100644 index 0000000..3f8179d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square.svg new file mode 100644 index 0000000..ded82d4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/square.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack-overflow.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack-overflow.svg new file mode 100644 index 0000000..b7d482d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack-overflow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack.svg new file mode 100644 index 0000000..b8a9c94 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stack.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-fill.svg new file mode 100644 index 0000000..de09c4a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-half.svg new file mode 100644 index 0000000..8d30e7e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star.svg new file mode 100644 index 0000000..742b5e2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/star.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stars.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stars.svg new file mode 100644 index 0000000..2c16677 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stars.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/steam.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/steam.svg new file mode 100644 index 0000000..aecd433 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/steam.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies-fill.svg new file mode 100644 index 0000000..a0252da --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies.svg new file mode 100644 index 0000000..8252c49 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stickies.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky-fill.svg new file mode 100644 index 0000000..acd42b9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky.svg new file mode 100644 index 0000000..dba0142 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sticky.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn-fill.svg new file mode 100644 index 0000000..58b6c02 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn.svg new file mode 100644 index 0000000..5c392ec --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-btn.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle-fill.svg new file mode 100644 index 0000000..ac711e0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle.svg new file mode 100644 index 0000000..441613c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-fill.svg new file mode 100644 index 0000000..e00085a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop.svg new file mode 100644 index 0000000..2b86647 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stop.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights-fill.svg new file mode 100644 index 0000000..a18566b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights.svg new file mode 100644 index 0000000..f765ab2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stoplights.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch-fill.svg new file mode 100644 index 0000000..2d2ed11 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch.svg new file mode 100644 index 0000000..964dbb8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/stopwatch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/strava.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/strava.svg new file mode 100644 index 0000000..7e3237d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/strava.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/subtract.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/subtract.svg new file mode 100644 index 0000000..e1d878a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/subtract.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club-fill.svg new file mode 100644 index 0000000..d4d311a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club.svg new file mode 100644 index 0000000..75e5e85 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-club.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond-fill.svg new file mode 100644 index 0000000..2be1b7f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond.svg new file mode 100644 index 0000000..9192a27 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-diamond.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart-fill.svg new file mode 100644 index 0000000..0dd86f9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart.svg new file mode 100644 index 0000000..c761ef4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-heart.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade-fill.svg new file mode 100644 index 0000000..63bb0c6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade.svg new file mode 100644 index 0000000..8f14427 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/suit-spade.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun-fill.svg new file mode 100644 index 0000000..cc1a60e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun.svg new file mode 100644 index 0000000..c311208 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sun.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunglasses.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunglasses.svg new file mode 100644 index 0000000..3f7dad0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunglasses.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise-fill.svg new file mode 100644 index 0000000..eb6a668 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise.svg new file mode 100644 index 0000000..53d670d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunrise.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset-fill.svg new file mode 100644 index 0000000..7f5b60e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset.svg new file mode 100644 index 0000000..91041cf --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/sunset.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-horizontal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-horizontal.svg new file mode 100644 index 0000000..7e46d90 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-horizontal.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-vertical.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-vertical.svg new file mode 100644 index 0000000..a18fa2f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/symmetry-vertical.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/table.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/table.svg new file mode 100644 index 0000000..5e70d22 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/table.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-fill.svg new file mode 100644 index 0000000..571ae8f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape-fill.svg new file mode 100644 index 0000000..a4a6048 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape.svg new file mode 100644 index 0000000..b36f7d4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet-landscape.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet.svg new file mode 100644 index 0000000..be81ff5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tablet.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag-fill.svg new file mode 100644 index 0000000..1502792 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag.svg new file mode 100644 index 0000000..ab34fdd --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tag.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags-fill.svg new file mode 100644 index 0000000..f92a361 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags.svg new file mode 100644 index 0000000..9f6d676 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tags.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telegram.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telegram.svg new file mode 100644 index 0000000..139af07 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telegram.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-fill.svg new file mode 100644 index 0000000..efc72c0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward-fill.svg new file mode 100644 index 0000000..f4ce483 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward.svg new file mode 100644 index 0000000..17ec9ce --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-forward.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound-fill.svg new file mode 100644 index 0000000..998c8fb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound.svg new file mode 100644 index 0000000..460fe9f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-inbound.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus-fill.svg new file mode 100644 index 0000000..bc17abb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus.svg new file mode 100644 index 0000000..4f4d93c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-minus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound-fill.svg new file mode 100644 index 0000000..16013a5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound.svg new file mode 100644 index 0000000..1382886 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-outbound.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus-fill.svg new file mode 100644 index 0000000..6d8c58f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus.svg new file mode 100644 index 0000000..21ef909 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x-fill.svg new file mode 100644 index 0000000..c8ef894 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x.svg new file mode 100644 index 0000000..5aa3f95 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone-x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone.svg new file mode 100644 index 0000000..8e359b8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/telephone.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-dash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-dash.svg new file mode 100644 index 0000000..9049b5e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-dash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-fill.svg new file mode 100644 index 0000000..d3c6394 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-plus.svg new file mode 100644 index 0000000..be268c8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-plus.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-split.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-split.svg new file mode 100644 index 0000000..f65d2c7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-split.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-x.svg new file mode 100644 index 0000000..5128f11 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal-x.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal.svg new file mode 100644 index 0000000..e12c9f8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/terminal.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-center.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-center.svg new file mode 100644 index 0000000..2887a99 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-center.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-left.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-left.svg new file mode 100644 index 0000000..34d8c55 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-right.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-right.svg new file mode 100644 index 0000000..fdd837f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-indent-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-left.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-left.svg new file mode 100644 index 0000000..0452611 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-left.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-paragraph.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-paragraph.svg new file mode 100644 index 0000000..9779bea --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-paragraph.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-right.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-right.svg new file mode 100644 index 0000000..34686b0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/text-right.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-resize.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-resize.svg new file mode 100644 index 0000000..c4a9d9f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-resize.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-t.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-t.svg new file mode 100644 index 0000000..dc7e17c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea-t.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea.svg new file mode 100644 index 0000000..9aa5445 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/textarea.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-half.svg new file mode 100644 index 0000000..cafefd2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-half.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-high.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-high.svg new file mode 100644 index 0000000..15acf4c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-high.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-low.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-low.svg new file mode 100644 index 0000000..ce540e0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-low.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-snow.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-snow.svg new file mode 100644 index 0000000..0e1b400 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-snow.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-sun.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-sun.svg new file mode 100644 index 0000000..07c3290 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer-sun.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer.svg new file mode 100644 index 0000000..748813e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thermometer.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots-vertical.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots-vertical.svg new file mode 100644 index 0000000..cd0c79a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots-vertical.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots.svg new file mode 100644 index 0000000..ea92369 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/three-dots.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt-fill.svg new file mode 100644 index 0000000..85c437e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt.svg new file mode 100644 index 0000000..b8356da --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/thunderbolt.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed-fill.svg new file mode 100644 index 0000000..bc5d192 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed.svg new file mode 100644 index 0000000..c2701bb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-detailed.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-fill.svg new file mode 100644 index 0000000..73728b6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated-fill.svg new file mode 100644 index 0000000..2ec1d57 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated.svg new file mode 100644 index 0000000..194ae05 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket-perforated.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket.svg new file mode 100644 index 0000000..f24a93e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ticket.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tiktok.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tiktok.svg new file mode 100644 index 0000000..7edac4e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tiktok.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-off.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-off.svg new file mode 100644 index 0000000..97d6dab --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-on.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-on.svg new file mode 100644 index 0000000..d13b495 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle-on.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-off.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-off.svg new file mode 100644 index 0000000..a8fee6b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-off.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-on.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-on.svg new file mode 100644 index 0000000..993ec33 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggle2-on.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles.svg new file mode 100644 index 0000000..d53ae01 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles2.svg new file mode 100644 index 0000000..862fc9f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/toggles2.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tools.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tools.svg new file mode 100644 index 0000000..fcc8362 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tools.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tornado.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tornado.svg new file mode 100644 index 0000000..5bb53a2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tornado.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/translate.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/translate.svg new file mode 100644 index 0000000..39a17d2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/translate.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash-fill.svg new file mode 100644 index 0000000..1a20e6a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash.svg new file mode 100644 index 0000000..0ba7218 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2-fill.svg new file mode 100644 index 0000000..bc78b6d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2.svg new file mode 100644 index 0000000..6e6468e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3-fill.svg new file mode 100644 index 0000000..e0e81f1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3.svg new file mode 100644 index 0000000..1d5f42e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trash3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree-fill.svg new file mode 100644 index 0000000..4d45dd4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree.svg new file mode 100644 index 0000000..b97eb64 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tree.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-fill.svg new file mode 100644 index 0000000..654787f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-half.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-half.svg new file mode 100644 index 0000000..8f86f28 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle-half.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle.svg new file mode 100644 index 0000000..1fa1898 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/triangle.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy-fill.svg new file mode 100644 index 0000000..e29f001 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy.svg new file mode 100644 index 0000000..adfa108 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/trophy.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tropical-storm.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tropical-storm.svg new file mode 100644 index 0000000..c16188d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tropical-storm.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck-flatbed.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck-flatbed.svg new file mode 100644 index 0000000..5a37c8d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck-flatbed.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck.svg new file mode 100644 index 0000000..1afc549 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/truck.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tsunami.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tsunami.svg new file mode 100644 index 0000000..cf57486 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tsunami.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv-fill.svg new file mode 100644 index 0000000..bf9830f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv.svg new file mode 100644 index 0000000..bba3da1 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/tv.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitch.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitch.svg new file mode 100644 index 0000000..2975f80 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitter.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitter.svg new file mode 100644 index 0000000..8a83fa6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/twitter.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-bold.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-bold.svg new file mode 100644 index 0000000..276d133 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-bold.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h1.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h1.svg new file mode 100644 index 0000000..4c89181 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h1.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h2.svg new file mode 100644 index 0000000..b6ab765 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h3.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h3.svg new file mode 100644 index 0000000..154c293 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-h3.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-italic.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-italic.svg new file mode 100644 index 0000000..3ac6b09 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-italic.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-strikethrough.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-strikethrough.svg new file mode 100644 index 0000000..1c940e4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-strikethrough.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-underline.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-underline.svg new file mode 100644 index 0000000..c299b8b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type-underline.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type.svg new file mode 100644 index 0000000..9ab1e4c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/type.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks-grid.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks-grid.svg new file mode 100644 index 0000000..a32d424 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks-grid.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks.svg new file mode 100644 index 0000000..9b659e2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-checks.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios-grid.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios-grid.svg new file mode 100644 index 0000000..00c7b08 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios-grid.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios.svg new file mode 100644 index 0000000..da779af --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/ui-radios.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella-fill.svg new file mode 100644 index 0000000..c4886e9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella.svg new file mode 100644 index 0000000..94f32f9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/umbrella.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/union.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/union.svg new file mode 100644 index 0000000..b629b88 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/union.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock-fill.svg new file mode 100644 index 0000000..f053354 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock.svg new file mode 100644 index 0000000..8eb0925 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/unlock.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc-scan.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc-scan.svg new file mode 100644 index 0000000..2a9a6af --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc-scan.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc.svg new file mode 100644 index 0000000..6669ef7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upc.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upload.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upload.svg new file mode 100644 index 0000000..be3f8e3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/upload.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c-fill.svg new file mode 100644 index 0000000..0e50ac6 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c.svg new file mode 100644 index 0000000..c17d4ca --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-c.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive-fill.svg new file mode 100644 index 0000000..834614d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive.svg new file mode 100644 index 0000000..ca08df5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-drive.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-fill.svg new file mode 100644 index 0000000..443c91a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro-fill.svg new file mode 100644 index 0000000..67ad744 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro.svg new file mode 100644 index 0000000..945b6e7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-micro.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini-fill.svg new file mode 100644 index 0000000..7235636 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini.svg new file mode 100644 index 0000000..7cc383f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-mini.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug-fill.svg new file mode 100644 index 0000000..2f1c185 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug.svg new file mode 100644 index 0000000..68f5f97 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-plug.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-symbol.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-symbol.svg new file mode 100644 index 0000000..eb02d87 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb-symbol.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb.svg new file mode 100644 index 0000000..e82324c --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/usb.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine.svg new file mode 100644 index 0000000..5542055 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine2.svg new file mode 100644 index 0000000..c70e274 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/valentine2.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vector-pen.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vector-pen.svg new file mode 100644 index 0000000..013acc2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vector-pen.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-list.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-list.svg new file mode 100644 index 0000000..3d1a972 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-list.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-stacked.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-stacked.svg new file mode 100644 index 0000000..7f59bb9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/view-stacked.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vimeo.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vimeo.svg new file mode 100644 index 0000000..34eea6d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vimeo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl-fill.svg new file mode 100644 index 0000000..a5ab73d --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl.svg new file mode 100644 index 0000000..75c2681 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vinyl.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/voicemail.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/voicemail.svg new file mode 100644 index 0000000..ff7ce86 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/voicemail.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down-fill.svg new file mode 100644 index 0000000..4879b5a --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down.svg new file mode 100644 index 0000000..996dbef --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute-fill.svg new file mode 100644 index 0000000..7ab7684 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute.svg new file mode 100644 index 0000000..12659d9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-mute.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off-fill.svg new file mode 100644 index 0000000..4941870 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off.svg new file mode 100644 index 0000000..08bb6b9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up-fill.svg new file mode 100644 index 0000000..495ee98 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up-fill.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up.svg new file mode 100644 index 0000000..3840310 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/volume-up.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vr.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vr.svg new file mode 100644 index 0000000..cf2ea37 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/vr.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet-fill.svg new file mode 100644 index 0000000..d44e5c8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet.svg new file mode 100644 index 0000000..d18441b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet2.svg new file mode 100644 index 0000000..e646d94 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wallet2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/watch.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/watch.svg new file mode 100644 index 0000000..8c3ee98 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/watch.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/water.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/water.svg new file mode 100644 index 0000000..18e0825 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/water.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam-fill.svg new file mode 100644 index 0000000..04b835b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam.svg new file mode 100644 index 0000000..da7ef71 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/webcam.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/whatsapp.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/whatsapp.svg new file mode 100644 index 0000000..6242d05 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/whatsapp.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-1.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-1.svg new file mode 100644 index 0000000..4d75ef5 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-1.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-2.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-2.svg new file mode 100644 index 0000000..377c1fc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-2.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-off.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-off.svg new file mode 100644 index 0000000..4399861 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi.svg new file mode 100644 index 0000000..8cb1f71 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wifi.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wind.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wind.svg new file mode 100644 index 0000000..d350ea4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wind.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dash.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dash.svg new file mode 100644 index 0000000..191fbd7 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dash.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-desktop.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-desktop.svg new file mode 100644 index 0000000..a044521 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-desktop.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dock.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dock.svg new file mode 100644 index 0000000..dbffecb --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-dock.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-fullscreen.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-fullscreen.svg new file mode 100644 index 0000000..22a8d20 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-fullscreen.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-plus.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-plus.svg new file mode 100644 index 0000000..08444f3 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-plus.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-sidebar.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-sidebar.svg new file mode 100644 index 0000000..98476ce --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-sidebar.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-split.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-split.svg new file mode 100644 index 0000000..21862f2 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-split.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-stack.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-stack.svg new file mode 100644 index 0000000..592e5c8 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-stack.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-x.svg new file mode 100644 index 0000000..e7a97dc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window-x.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window.svg new file mode 100644 index 0000000..ad6166e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/window.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/windows.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/windows.svg new file mode 100644 index 0000000..b280560 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/windows.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wordpress.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wordpress.svg new file mode 100644 index 0000000..4c8cbc4 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wordpress.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle-fill.svg new file mode 100644 index 0000000..b723d7f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle-fill.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle.svg new file mode 100644 index 0000000..a5a6f0b --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable.svg new file mode 100644 index 0000000..4ec8082 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench-adjustable.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench.svg new file mode 100644 index 0000000..bef0713 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/wrench.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle-fill.svg new file mode 100644 index 0000000..448fdee --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle.svg new file mode 100644 index 0000000..ce37cdc --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-circle.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond-fill.svg new file mode 100644 index 0000000..2de6403 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond.svg new file mode 100644 index 0000000..0ade536 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-diamond.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-lg.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-lg.svg new file mode 100644 index 0000000..53aec00 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-lg.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon-fill.svg new file mode 100644 index 0000000..7872889 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon.svg new file mode 100644 index 0000000..794afd9 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-octagon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square-fill.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square-fill.svg new file mode 100644 index 0000000..ddfd727 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square-fill.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square.svg new file mode 100644 index 0000000..9d7852f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x-square.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x.svg new file mode 100644 index 0000000..c865d88 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/x.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/xbox.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/xbox.svg new file mode 100644 index 0000000..9d84973 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/xbox.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/yin-yang.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/yin-yang.svg new file mode 100644 index 0000000..cf1da48 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/yin-yang.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/youtube.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/youtube.svg new file mode 100644 index 0000000..86fa490 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/youtube.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-in.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-in.svg new file mode 100644 index 0000000..6cde1a0 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-in.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-out.svg b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-out.svg new file mode 100644 index 0000000..b965f8e --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap-icons/zoom-out.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css new file mode 100644 index 0000000..596784f --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! + * Bootstrap v5.3.0-alpha1 (https://getbootstrap.com/) + * Copyright 2011-2022 The Bootstrap Authors + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */:root,[data-bs-theme=light]{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-black:#000;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-gray-100:#f8f9fa;--bs-gray-200:#e9ecef;--bs-gray-300:#dee2e6;--bs-gray-400:#ced4da;--bs-gray-500:#adb5bd;--bs-gray-600:#6c757d;--bs-gray-700:#495057;--bs-gray-800:#343a40;--bs-gray-900:#212529;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-primary-rgb:13,110,253;--bs-secondary-rgb:108,117,125;--bs-success-rgb:25,135,84;--bs-info-rgb:13,202,240;--bs-warning-rgb:255,193,7;--bs-danger-rgb:220,53,69;--bs-light-rgb:248,249,250;--bs-dark-rgb:33,37,41;--bs-primary-text:#0a58ca;--bs-secondary-text:#6c757d;--bs-success-text:#146c43;--bs-info-text:#087990;--bs-warning-text:#997404;--bs-danger-text:#b02a37;--bs-light-text:#6c757d;--bs-dark-text:#495057;--bs-primary-bg-subtle:#cfe2ff;--bs-secondary-bg-subtle:#f8f9fa;--bs-success-bg-subtle:#d1e7dd;--bs-info-bg-subtle:#cff4fc;--bs-warning-bg-subtle:#fff3cd;--bs-danger-bg-subtle:#f8d7da;--bs-light-bg-subtle:#fcfcfd;--bs-dark-bg-subtle:#ced4da;--bs-primary-border-subtle:#9ec5fe;--bs-secondary-border-subtle:#e9ecef;--bs-success-border-subtle:#a3cfbb;--bs-info-border-subtle:#9eeaf9;--bs-warning-border-subtle:#ffe69c;--bs-danger-border-subtle:#f1aeb5;--bs-light-border-subtle:#e9ecef;--bs-dark-border-subtle:#adb5bd;--bs-white-rgb:255,255,255;--bs-black-rgb:0,0,0;--bs-body-color-rgb:33,37,41;--bs-body-bg-rgb:255,255,255;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue","Noto Sans","Liberation Sans",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-body-font-family:var(--bs-font-sans-serif);--bs-body-font-size:1rem;--bs-body-font-weight:400;--bs-body-line-height:1.5;--bs-body-color:#212529;--bs-emphasis-color:#000;--bs-emphasis-color-rgb:0,0,0;--bs-secondary-color:rgba(33, 37, 41, 0.75);--bs-secondary-color-rgb:33,37,41;--bs-secondary-bg:#e9ecef;--bs-secondary-bg-rgb:233,236,239;--bs-tertiary-color:rgba(33, 37, 41, 0.5);--bs-tertiary-color-rgb:33,37,41;--bs-tertiary-bg:#f8f9fa;--bs-tertiary-bg-rgb:248,249,250;--bs-body-bg:#fff;--bs-body-bg-rgb:255,255,255;--bs-link-color:#0d6efd;--bs-link-color-rgb:13,110,253;--bs-link-decoration:underline;--bs-link-hover-color:#0a58ca;--bs-link-hover-color-rgb:10,88,202;--bs-code-color:#d63384;--bs-highlight-bg:#fff3cd;--bs-border-width:1px;--bs-border-style:solid;--bs-border-color:#dee2e6;--bs-border-color-translucent:rgba(0, 0, 0, 0.175);--bs-border-radius:0.375rem;--bs-border-radius-sm:0.25rem;--bs-border-radius-lg:0.5rem;--bs-border-radius-xl:1rem;--bs-border-radius-2xl:2rem;--bs-border-radius-pill:50rem;--bs-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-box-shadow-sm:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-box-shadow-lg:0 1rem 3rem rgba(var(--bs-body-color-rgb), 0.175);--bs-box-shadow-inset:inset 0 1px 2px rgba(var(--bs-body-color-rgb), 0.075);--bs-emphasis-color:#000;--bs-form-control-bg:var(--bs-body-bg);--bs-form-control-disabled-bg:var(--bs-secondary-bg);--bs-highlight-bg:#fff3cd;--bs-breakpoint-xs:0;--bs-breakpoint-sm:576px;--bs-breakpoint-md:768px;--bs-breakpoint-lg:992px;--bs-breakpoint-xl:1200px;--bs-breakpoint-xxl:1400px}[data-bs-theme=dark]{--bs-body-color:#adb5bd;--bs-body-color-rgb:173,181,189;--bs-body-bg:#212529;--bs-body-bg-rgb:33,37,41;--bs-emphasis-color:#f8f9fa;--bs-emphasis-color-rgb:248,249,250;--bs-secondary-color:rgba(173, 181, 189, 0.75);--bs-secondary-color-rgb:173,181,189;--bs-secondary-bg:#343a40;--bs-secondary-bg-rgb:52,58,64;--bs-tertiary-color:rgba(173, 181, 189, 0.5);--bs-tertiary-color-rgb:173,181,189;--bs-tertiary-bg:#2b3035;--bs-tertiary-bg-rgb:43,48,53;--bs-emphasis-color:#fff;--bs-primary-text:#6ea8fe;--bs-secondary-text:#dee2e6;--bs-success-text:#75b798;--bs-info-text:#6edff6;--bs-warning-text:#ffda6a;--bs-danger-text:#ea868f;--bs-light-text:#f8f9fa;--bs-dark-text:#dee2e6;--bs-primary-bg-subtle:#031633;--bs-secondary-bg-subtle:#212529;--bs-success-bg-subtle:#051b11;--bs-info-bg-subtle:#032830;--bs-warning-bg-subtle:#332701;--bs-danger-bg-subtle:#2c0b0e;--bs-light-bg-subtle:#343a40;--bs-dark-bg-subtle:#1a1d20;--bs-primary-border-subtle:#084298;--bs-secondary-border-subtle:#495057;--bs-success-border-subtle:#0f5132;--bs-info-border-subtle:#055160;--bs-warning-border-subtle:#664d03;--bs-danger-border-subtle:#842029;--bs-light-border-subtle:#495057;--bs-dark-border-subtle:#343a40;--bs-heading-color:#fff;--bs-link-color:#6ea8fe;--bs-link-hover-color:#9ec5fe;--bs-link-color-rgb:110,168,254;--bs-link-hover-color-rgb:158,197,254;--bs-code-color:#e685b5;--bs-border-color:#495057;--bs-border-color-translucent:rgba(255, 255, 255, 0.15)}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;border:0;border-top:var(--bs-border-width) solid;opacity:.25}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2;color:var(--bs-heading-color,inherit)}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.1875em;background-color:var(--bs-highlight-bg)}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:rgba(var(--bs-link-color-rgb),var(--bs-link-opacity,1));text-decoration:underline}a:hover{--bs-link-color-rgb:var(--bs-link-hover-color-rgb)}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:var(--bs-code-color);word-wrap:break-word}a>code{color:inherit}kbd{padding:.1875rem .375rem;font-size:.875em;color:var(--bs-body-bg);background-color:var(--bs-body-color);border-radius:.25rem}kbd kbd{padding:0;font-size:1em}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-secondary-color);text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator{display:none!important}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}::file-selector-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:var(--bs-body-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:var(--bs-border-radius);max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:var(--bs-secondary-color)}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{--bs-gutter-x:1.5rem;--bs-gutter-y:0;width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(-1 * var(--bs-gutter-y));margin-right:calc(-.5 * var(--bs-gutter-x));margin-left:calc(-.5 * var(--bs-gutter-x))}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-color:var(--bs-body-color);--bs-table-bg:transparent;--bs-table-border-color:var(--bs-border-color);--bs-table-accent-bg:transparent;--bs-table-striped-color:var(--bs-body-color);--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:var(--bs-body-color);--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:var(--bs-body-color);--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:var(--bs-table-color);vertical-align:top;border-color:var(--bs-table-border-color)}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:var(--bs-border-width);box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table-group-divider{border-top:calc(var(--bs-border-width) * 2) solid currentcolor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:var(--bs-border-width) 0}.table-bordered>:not(caption)>*>*{border-width:0 var(--bs-border-width)}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-striped-columns>:not(caption)>tr>:nth-child(2n){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-color:#000;--bs-table-bg:#cfe2ff;--bs-table-border-color:#bacbe6;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-secondary{--bs-table-color:#000;--bs-table-bg:#e2e3e5;--bs-table-border-color:#cbccce;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-success{--bs-table-color:#000;--bs-table-bg:#d1e7dd;--bs-table-border-color:#bcd0c7;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-info{--bs-table-color:#000;--bs-table-bg:#cff4fc;--bs-table-border-color:#badce3;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-warning{--bs-table-color:#000;--bs-table-bg:#fff3cd;--bs-table-border-color:#e6dbb9;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-danger{--bs-table-color:#000;--bs-table-bg:#f8d7da;--bs-table-border-color:#dfc2c4;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-light{--bs-table-color:#000;--bs-table-bg:#f8f9fa;--bs-table-border-color:#dfe0e1;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-dark{--bs-table-color:#fff;--bs-table-bg:#212529;--bs-table-border-color:#373b3e;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:var(--bs-table-color);border-color:var(--bs-table-border-color)}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + var(--bs-border-width));padding-bottom:calc(.375rem + var(--bs-border-width));margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + var(--bs-border-width));padding-bottom:calc(.5rem + var(--bs-border-width));font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + var(--bs-border-width));padding-bottom:calc(.25rem + var(--bs-border-width));font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:var(--bs-secondary-color)}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-clip:padding-box;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:var(--bs-body-color);background-color:var(--bs-form-control-bg);border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-webkit-datetime-edit{display:block;padding:0}.form-control::-moz-placeholder{color:var(--bs-secondary-color);opacity:1}.form-control::placeholder{color:var(--bs-secondary-color);opacity:1}.form-control:disabled{background-color:var(--bs-form-control-disabled-bg);opacity:1}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:var(--bs-body-color);background-color:var(--bs-tertiary-bg);pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:var(--bs-border-width);border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:var(--bs-secondary-bg)}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:var(--bs-secondary-bg)}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:var(--bs-body-color);background-color:transparent;border:solid transparent;border-width:var(--bs-border-width) 0}.form-control-plaintext:focus{outline:0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2));padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2))}textarea.form-control-sm{min-height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}textarea.form-control-lg{min-height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-control-color{width:3rem;height:calc(1.5em + .75rem + calc(var(--bs-border-width) * 2));padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{border:0!important;border-radius:.375rem}.form-control-color::-webkit-color-swatch{border-radius:.375rem}.form-control-color.form-control-sm{height:calc(1.5em + .5rem + calc(var(--bs-border-width) * 2))}.form-control-color.form-control-lg{height:calc(1.5em + 1rem + calc(var(--bs-border-width) * 2))}.form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);background-color:var(--bs-form-control-bg);background-image:var(--bs-form-select-bg-img),var(--bs-form-select-bg-icon,none);background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:var(--bs-form-control-disabled-bg)}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 var(--bs-body-color)}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem;border-radius:.25rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem;border-radius:.5rem}[data-bs-theme=dark] .form-select{--bs-form-select-bg-img:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e")}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-reverse{padding-right:1.5em;padding-left:0;text-align:right}.form-check-reverse .form-check-input{float:right;margin-right:-1.5em;margin-left:0}.form-check-input{--bs-form-check-bg:var(--bs-form-control-bg);width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:var(--bs-form-check-bg);background-image:var(--bs-form-check-bg-image);background-repeat:no-repeat;background-position:center;background-size:contain;border:var(--bs-border-width) solid var(--bs-border-color);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact;print-color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;--bs-form-check-bg-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{cursor:default;opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");width:2em;margin-left:-2.5em;background-image:var(--bs-form-switch-bg);background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-switch.form-check-reverse{padding-right:2.5em;padding-left:0}.form-switch.form-check-reverse .form-check-input{margin-right:-2.5em;margin-left:0}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus){--bs-form-switch-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e")}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:var(--bs-tertiary-bg);border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:var(--bs-secondary-color)}.form-range:disabled::-moz-range-thumb{background-color:var(--bs-secondary-color)}.form-floating{position:relative}.form-floating::before:not(.form-control:disabled){position:absolute;top:var(--bs-border-width);left:var(--bs-border-width);width:calc(100% - (calc(calc(.375em + .1875rem) + calc(.75em + .375rem))));height:1.875em;content:"";background-color:var(--bs-form-control-bg);border-radius:.375rem}.form-floating>.form-control,.form-floating>.form-control-plaintext,.form-floating>.form-select{height:calc(3.5rem + calc(var(--bs-border-width) * 2));line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;width:100%;height:100%;padding:1rem .75rem;overflow:hidden;text-align:start;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;border:var(--bs-border-width) solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control,.form-floating>.form-control-plaintext{padding:1rem .75rem}.form-floating>.form-control-plaintext::-moz-placeholder,.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control-plaintext::placeholder,.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control-plaintext:not(:-moz-placeholder-shown),.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:focus,.form-floating>.form-control-plaintext:not(:placeholder-shown),.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control-plaintext:-webkit-autofill,.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label,.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control-plaintext~label{border-width:var(--bs-border-width) 0}.form-floating>.form-control:disabled~label{color:#6c757d}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-floating,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-floating:focus-within,.input-group>.form-select:focus{z-index:5}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:5}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:var(--bs-body-color);text-align:center;white-space:nowrap;background-color:var(--bs-tertiary-bg);border:var(--bs-border-width) solid var(--bs-border-color);border-radius:.375rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.5rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.25rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-control,.input-group:not(.has-validation)>.form-floating:not(:last-child)>.form-select,.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-control,.input-group.has-validation>.form-floating:nth-last-child(n+3)>.form-select,.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:calc(var(--bs-border-width) * -1);border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.form-floating:not(:first-child)>.form-control,.input-group>.form-floating:not(:first-child)>.form-select{border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-success-text)}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-success);border-radius:var(--bs-border-radius)}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:var(--bs-success);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:var(--bs-success)}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:var(--bs-success);box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-control-color.is-valid,.was-validated .form-control-color:valid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:var(--bs-success)}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:var(--bs-success-text)}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-success-rgb),.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:var(--bs-success-text)}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-valid,.input-group>.form-floating:not(:focus-within).is-valid,.input-group>.form-select:not(:focus).is-valid,.was-validated .input-group>.form-control:not(:focus):valid,.was-validated .input-group>.form-floating:not(:focus-within):valid,.was-validated .input-group>.form-select:not(:focus):valid{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:var(--bs-danger-text)}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:var(--bs-danger);border-radius:var(--bs-border-radius)}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:var(--bs-danger);padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:var(--bs-danger)}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{--bs-form-select-bg-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");padding-right:4.125rem;background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:var(--bs-danger);box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-control-color.is-invalid,.was-validated .form-control-color:invalid{width:calc(3rem + calc(1.5em + .75rem))}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:var(--bs-danger)}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:var(--bs-danger-text)}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(var(--bs-danger-rgb),.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:var(--bs-danger-text)}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group>.form-control:not(:focus).is-invalid,.input-group>.form-floating:not(:focus-within).is-invalid,.input-group>.form-select:not(:focus).is-invalid,.was-validated .input-group>.form-control:not(:focus):invalid,.was-validated .input-group>.form-floating:not(:focus-within):invalid,.was-validated .input-group>.form-select:not(:focus):invalid{z-index:4}.btn{--bs-btn-padding-x:0.75rem;--bs-btn-padding-y:0.375rem;--bs-btn-font-family: ;--bs-btn-font-size:1rem;--bs-btn-font-weight:400;--bs-btn-line-height:1.5;--bs-btn-color:#212529;--bs-btn-bg:transparent;--bs-btn-border-width:var(--bs-border-width);--bs-btn-border-color:transparent;--bs-btn-border-radius:0.375rem;--bs-btn-hover-border-color:transparent;--bs-btn-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.15),0 1px 1px rgba(0, 0, 0, 0.075);--bs-btn-disabled-opacity:0.65;--bs-btn-focus-box-shadow:0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);display:inline-block;padding:var(--bs-btn-padding-y) var(--bs-btn-padding-x);font-family:var(--bs-btn-font-family);font-size:var(--bs-btn-font-size);font-weight:var(--bs-btn-font-weight);line-height:var(--bs-btn-line-height);color:var(--bs-btn-color);text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;border:var(--bs-btn-border-width) solid var(--bs-btn-border-color);border-radius:var(--bs-btn-border-radius);background-color:var(--bs-btn-bg);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color)}.btn-check+.btn:hover{color:var(--bs-btn-color);background-color:var(--bs-btn-bg);border-color:var(--bs-btn-border-color)}.btn:focus-visible{color:var(--bs-btn-hover-color);background-color:var(--bs-btn-hover-bg);border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:focus-visible+.btn{border-color:var(--bs-btn-hover-border-color);outline:0;box-shadow:var(--bs-btn-focus-box-shadow)}.btn-check:checked+.btn,.btn.active,.btn.show,.btn:first-child:active,:not(.btn-check)+.btn:active{color:var(--bs-btn-active-color);background-color:var(--bs-btn-active-bg);border-color:var(--bs-btn-active-border-color)}.btn-check:checked+.btn:focus-visible,.btn.active:focus-visible,.btn.show:focus-visible,.btn:first-child:active:focus-visible,:not(.btn-check)+.btn:active:focus-visible{box-shadow:var(--bs-btn-focus-box-shadow)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{color:var(--bs-btn-disabled-color);pointer-events:none;background-color:var(--bs-btn-disabled-bg);border-color:var(--bs-btn-disabled-border-color);opacity:var(--bs-btn-disabled-opacity)}.btn-primary{--bs-btn-color:#fff;--bs-btn-bg:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0b5ed7;--bs-btn-hover-border-color:#0a58ca;--bs-btn-focus-shadow-rgb:49,132,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0a58ca;--bs-btn-active-border-color:#0a53be;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#0d6efd;--bs-btn-disabled-border-color:#0d6efd}.btn-secondary{--bs-btn-color:#fff;--bs-btn-bg:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#5c636a;--bs-btn-hover-border-color:#565e64;--bs-btn-focus-shadow-rgb:130,138,145;--bs-btn-active-color:#fff;--bs-btn-active-bg:#565e64;--bs-btn-active-border-color:#51585e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#6c757d;--bs-btn-disabled-border-color:#6c757d}.btn-success{--bs-btn-color:#fff;--bs-btn-bg:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#157347;--bs-btn-hover-border-color:#146c43;--bs-btn-focus-shadow-rgb:60,153,110;--bs-btn-active-color:#fff;--bs-btn-active-bg:#146c43;--bs-btn-active-border-color:#13653f;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#198754;--bs-btn-disabled-border-color:#198754}.btn-info{--bs-btn-color:#000;--bs-btn-bg:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#31d2f2;--bs-btn-hover-border-color:#25cff2;--bs-btn-focus-shadow-rgb:11,172,204;--bs-btn-active-color:#000;--bs-btn-active-bg:#3dd5f3;--bs-btn-active-border-color:#25cff2;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#0dcaf0;--bs-btn-disabled-border-color:#0dcaf0}.btn-warning{--bs-btn-color:#000;--bs-btn-bg:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffca2c;--bs-btn-hover-border-color:#ffc720;--bs-btn-focus-shadow-rgb:217,164,6;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffcd39;--bs-btn-active-border-color:#ffc720;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#ffc107;--bs-btn-disabled-border-color:#ffc107}.btn-danger{--bs-btn-color:#fff;--bs-btn-bg:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#bb2d3b;--bs-btn-hover-border-color:#b02a37;--bs-btn-focus-shadow-rgb:225,83,97;--bs-btn-active-color:#fff;--bs-btn-active-bg:#b02a37;--bs-btn-active-border-color:#a52834;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#dc3545;--bs-btn-disabled-border-color:#dc3545}.btn-light{--bs-btn-color:#000;--bs-btn-bg:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#d3d4d5;--bs-btn-hover-border-color:#c6c7c8;--bs-btn-focus-shadow-rgb:211,212,213;--bs-btn-active-color:#000;--bs-btn-active-bg:#c6c7c8;--bs-btn-active-border-color:#babbbc;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#000;--bs-btn-disabled-bg:#f8f9fa;--bs-btn-disabled-border-color:#f8f9fa}.btn-dark{--bs-btn-color:#fff;--bs-btn-bg:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#424649;--bs-btn-hover-border-color:#373b3e;--bs-btn-focus-shadow-rgb:66,70,73;--bs-btn-active-color:#fff;--bs-btn-active-bg:#4d5154;--bs-btn-active-border-color:#373b3e;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#fff;--bs-btn-disabled-bg:#212529;--bs-btn-disabled-border-color:#212529}.btn-outline-primary{--bs-btn-color:#0d6efd;--bs-btn-border-color:#0d6efd;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#0d6efd;--bs-btn-hover-border-color:#0d6efd;--bs-btn-focus-shadow-rgb:13,110,253;--bs-btn-active-color:#fff;--bs-btn-active-bg:#0d6efd;--bs-btn-active-border-color:#0d6efd;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0d6efd;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0d6efd;--bs-gradient:none}.btn-outline-secondary{--bs-btn-color:#6c757d;--bs-btn-border-color:#6c757d;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#6c757d;--bs-btn-hover-border-color:#6c757d;--bs-btn-focus-shadow-rgb:108,117,125;--bs-btn-active-color:#fff;--bs-btn-active-bg:#6c757d;--bs-btn-active-border-color:#6c757d;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#6c757d;--bs-gradient:none}.btn-outline-success{--bs-btn-color:#198754;--bs-btn-border-color:#198754;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#198754;--bs-btn-hover-border-color:#198754;--bs-btn-focus-shadow-rgb:25,135,84;--bs-btn-active-color:#fff;--bs-btn-active-bg:#198754;--bs-btn-active-border-color:#198754;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#198754;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#198754;--bs-gradient:none}.btn-outline-info{--bs-btn-color:#0dcaf0;--bs-btn-border-color:#0dcaf0;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#0dcaf0;--bs-btn-hover-border-color:#0dcaf0;--bs-btn-focus-shadow-rgb:13,202,240;--bs-btn-active-color:#000;--bs-btn-active-bg:#0dcaf0;--bs-btn-active-border-color:#0dcaf0;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#0dcaf0;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#0dcaf0;--bs-gradient:none}.btn-outline-warning{--bs-btn-color:#ffc107;--bs-btn-border-color:#ffc107;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#ffc107;--bs-btn-hover-border-color:#ffc107;--bs-btn-focus-shadow-rgb:255,193,7;--bs-btn-active-color:#000;--bs-btn-active-bg:#ffc107;--bs-btn-active-border-color:#ffc107;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#ffc107;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#ffc107;--bs-gradient:none}.btn-outline-danger{--bs-btn-color:#dc3545;--bs-btn-border-color:#dc3545;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#dc3545;--bs-btn-hover-border-color:#dc3545;--bs-btn-focus-shadow-rgb:220,53,69;--bs-btn-active-color:#fff;--bs-btn-active-bg:#dc3545;--bs-btn-active-border-color:#dc3545;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#dc3545;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#dc3545;--bs-gradient:none}.btn-outline-light{--bs-btn-color:#f8f9fa;--bs-btn-border-color:#f8f9fa;--bs-btn-hover-color:#000;--bs-btn-hover-bg:#f8f9fa;--bs-btn-hover-border-color:#f8f9fa;--bs-btn-focus-shadow-rgb:248,249,250;--bs-btn-active-color:#000;--bs-btn-active-bg:#f8f9fa;--bs-btn-active-border-color:#f8f9fa;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#f8f9fa;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#f8f9fa;--bs-gradient:none}.btn-outline-dark{--bs-btn-color:#212529;--bs-btn-border-color:#212529;--bs-btn-hover-color:#fff;--bs-btn-hover-bg:#212529;--bs-btn-hover-border-color:#212529;--bs-btn-focus-shadow-rgb:33,37,41;--bs-btn-active-color:#fff;--bs-btn-active-bg:#212529;--bs-btn-active-border-color:#212529;--bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);--bs-btn-disabled-color:#212529;--bs-btn-disabled-bg:transparent;--bs-btn-disabled-border-color:#212529;--bs-gradient:none}.btn-link{--bs-btn-font-weight:400;--bs-btn-color:var(--bs-link-color);--bs-btn-bg:transparent;--bs-btn-border-color:transparent;--bs-btn-hover-color:var(--bs-link-hover-color);--bs-btn-hover-border-color:transparent;--bs-btn-active-color:var(--bs-link-hover-color);--bs-btn-active-border-color:transparent;--bs-btn-disabled-color:#6c757d;--bs-btn-disabled-border-color:transparent;--bs-btn-box-shadow:none;--bs-btn-focus-shadow-rgb:49,132,253;text-decoration:underline}.btn-link:focus-visible{color:var(--bs-btn-color)}.btn-link:hover{color:var(--bs-btn-hover-color)}.btn-group-lg>.btn,.btn-lg{--bs-btn-padding-y:0.5rem;--bs-btn-padding-x:1rem;--bs-btn-font-size:1.25rem;--bs-btn-border-radius:0.5rem}.btn-group-sm>.btn,.btn-sm{--bs-btn-padding-y:0.25rem;--bs-btn-padding-x:0.5rem;--bs-btn-font-size:0.875rem;--bs-btn-border-radius:0.25rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media (prefers-reduced-motion:reduce){.collapsing.collapse-horizontal{transition:none}}.dropdown,.dropdown-center,.dropend,.dropstart,.dropup,.dropup-center{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{--bs-dropdown-zindex:1000;--bs-dropdown-min-width:10rem;--bs-dropdown-padding-x:0;--bs-dropdown-padding-y:0.5rem;--bs-dropdown-spacer:0.125rem;--bs-dropdown-font-size:1rem;--bs-dropdown-color:var(--bs-body-color);--bs-dropdown-bg:var(--bs-body-bg);--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-border-radius:0.375rem;--bs-dropdown-border-width:var(--bs-border-width);--bs-dropdown-inner-border-radius:calc(0.375rem - var(--bs-border-width));--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-divider-margin-y:0.5rem;--bs-dropdown-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-dropdown-link-color:var(--bs-body-color);--bs-dropdown-link-hover-color:var(--bs-body-color);--bs-dropdown-link-hover-bg:var(--bs-tertiary-bg);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-item-padding-x:1rem;--bs-dropdown-item-padding-y:0.25rem;--bs-dropdown-header-color:#6c757d;--bs-dropdown-header-padding-x:1rem;--bs-dropdown-header-padding-y:0.5rem;position:absolute;z-index:var(--bs-dropdown-zindex);display:none;min-width:var(--bs-dropdown-min-width);padding:var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);margin:0;font-size:var(--bs-dropdown-font-size);color:var(--bs-dropdown-color);text-align:left;list-style:none;background-color:var(--bs-dropdown-bg);background-clip:padding-box;border:var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);border-radius:var(--bs-dropdown-border-radius)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:var(--bs-dropdown-spacer)}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:var(--bs-dropdown-spacer)}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:var(--bs-dropdown-spacer)}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:var(--bs-dropdown-spacer)}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:var(--bs-dropdown-divider-margin-y) 0;overflow:hidden;border-top:1px solid var(--bs-dropdown-divider-bg);opacity:1}.dropdown-item{display:block;width:100%;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);clear:both;font-weight:400;color:var(--bs-dropdown-link-color);text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0;border-radius:var(--bs-dropdown-item-border-radius,0)}.dropdown-item:focus,.dropdown-item:hover{color:var(--bs-dropdown-link-hover-color);background-color:var(--bs-dropdown-link-hover-bg)}.dropdown-item.active,.dropdown-item:active{color:var(--bs-dropdown-link-active-color);text-decoration:none;background-color:var(--bs-dropdown-link-active-bg)}.dropdown-item.disabled,.dropdown-item:disabled{color:var(--bs-dropdown-link-disabled-color);pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);margin-bottom:0;font-size:.875rem;color:var(--bs-dropdown-header-color);white-space:nowrap}.dropdown-item-text{display:block;padding:var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);color:var(--bs-dropdown-link-color)}.dropdown-menu-dark{--bs-dropdown-color:#dee2e6;--bs-dropdown-bg:#343a40;--bs-dropdown-border-color:var(--bs-border-color-translucent);--bs-dropdown-box-shadow: ;--bs-dropdown-link-color:#dee2e6;--bs-dropdown-link-hover-color:#fff;--bs-dropdown-divider-bg:var(--bs-border-color-translucent);--bs-dropdown-link-hover-bg:rgba(255, 255, 255, 0.15);--bs-dropdown-link-active-color:#fff;--bs-dropdown-link-active-bg:#0d6efd;--bs-dropdown-link-disabled-color:#adb5bd;--bs-dropdown-header-color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group{border-radius:.375rem}.btn-group>.btn-group:not(:first-child),.btn-group>:not(.btn-check:first-child)+.btn{margin-left:calc(var(--bs-border-width) * -1)}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn.dropdown-toggle-split:first-child,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:calc(var(--bs-border-width) * -1)}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{--bs-nav-link-padding-x:1rem;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-link-color);--bs-nav-link-hover-color:var(--bs-link-hover-color);--bs-nav-link-disabled-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);font-size:var(--bs-nav-link-font-size);font-weight:var(--bs-nav-link-font-weight);color:var(--bs-nav-link-color);text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:var(--bs-nav-link-hover-color)}.nav-link.disabled{color:var(--bs-nav-link-disabled-color);pointer-events:none;cursor:default}.nav-tabs{--bs-nav-tabs-border-width:var(--bs-border-width);--bs-nav-tabs-border-color:var(--bs-border-color);--bs-nav-tabs-border-radius:var(--bs-border-radius);--bs-nav-tabs-link-hover-border-color:var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);--bs-nav-tabs-link-active-color:var(--bs-emphasis-color);--bs-nav-tabs-link-active-bg:var(--bs-body-bg);--bs-nav-tabs-link-active-border-color:var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);border-bottom:var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color)}.nav-tabs .nav-link{margin-bottom:calc(-1 * var(--bs-nav-tabs-border-width));background:0 0;border:var(--bs-nav-tabs-border-width) solid transparent;border-top-left-radius:var(--bs-nav-tabs-border-radius);border-top-right-radius:var(--bs-nav-tabs-border-radius)}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{isolation:isolate;border-color:var(--bs-nav-tabs-link-hover-border-color)}.nav-tabs .nav-link.disabled,.nav-tabs .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:var(--bs-nav-tabs-link-active-color);background-color:var(--bs-nav-tabs-link-active-bg);border-color:var(--bs-nav-tabs-link-active-border-color)}.nav-tabs .dropdown-menu{margin-top:calc(-1 * var(--bs-nav-tabs-border-width));border-top-left-radius:0;border-top-right-radius:0}.nav-pills{--bs-nav-pills-border-radius:0.375rem;--bs-nav-pills-link-active-color:#fff;--bs-nav-pills-link-active-bg:#0d6efd}.nav-pills .nav-link{background:0 0;border:0;border-radius:var(--bs-nav-pills-border-radius)}.nav-pills .nav-link:disabled{color:var(--bs-nav-link-disabled-color);background-color:transparent;border-color:transparent}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:var(--bs-nav-pills-link-active-color);background-color:var(--bs-nav-pills-link-active-bg)}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{--bs-navbar-padding-x:0;--bs-navbar-padding-y:0.5rem;--bs-navbar-color:rgba(var(--bs-emphasis-color-rgb), 0.65);--bs-navbar-hover-color:rgba(var(--bs-emphasis-color-rgb), 0.8);--bs-navbar-disabled-color:rgba(var(--bs-emphasis-color-rgb), 0.3);--bs-navbar-active-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-padding-y:0.3125rem;--bs-navbar-brand-margin-end:1rem;--bs-navbar-brand-font-size:1.25rem;--bs-navbar-brand-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-brand-hover-color:rgba(var(--bs-emphasis-color-rgb), 1);--bs-navbar-nav-link-padding-x:0.5rem;--bs-navbar-toggler-padding-y:0.25rem;--bs-navbar-toggler-padding-x:0.75rem;--bs-navbar-toggler-font-size:1.25rem;--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");--bs-navbar-toggler-border-color:rgba(var(--bs-emphasis-color-rgb), 0.15);--bs-navbar-toggler-border-radius:0.375rem;--bs-navbar-toggler-focus-width:0.25rem;--bs-navbar-toggler-transition:box-shadow 0.15s ease-in-out;position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding:var(--bs-navbar-padding-y) var(--bs-navbar-padding-x)}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:var(--bs-navbar-brand-padding-y);padding-bottom:var(--bs-navbar-brand-padding-y);margin-right:var(--bs-navbar-brand-margin-end);font-size:var(--bs-navbar-brand-font-size);color:var(--bs-navbar-brand-color);text-decoration:none;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{color:var(--bs-navbar-brand-hover-color)}.navbar-nav{--bs-nav-link-padding-x:0;--bs-nav-link-padding-y:0.5rem;--bs-nav-link-font-weight: ;--bs-nav-link-color:var(--bs-navbar-color);--bs-nav-link-hover-color:var(--bs-navbar-hover-color);--bs-nav-link-disabled-color:var(--bs-navbar-disabled-color);display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link.active,.navbar-nav .show>.nav-link{color:var(--bs-navbar-active-color)}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem;color:var(--bs-navbar-color)}.navbar-text a,.navbar-text a:focus,.navbar-text a:hover{color:var(--bs-navbar-active-color)}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);font-size:var(--bs-navbar-toggler-font-size);line-height:1;color:var(--bs-navbar-color);background-color:transparent;border:var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);border-radius:var(--bs-navbar-toggler-border-radius);transition:var(--bs-navbar-toggler-transition)}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 var(--bs-navbar-toggler-focus-width)}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-image:var(--bs-navbar-toggler-icon-bg);background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-sm .offcanvas .offcanvas-header{display:none}.navbar-expand-sm .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-md .offcanvas .offcanvas-header{display:none}.navbar-expand-md .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-lg .offcanvas .offcanvas-header{display:none}.navbar-expand-lg .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xl .offcanvas .offcanvas-header{display:none}.navbar-expand-xl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand-xxl .offcanvas .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:var(--bs-navbar-nav-link-padding-x);padding-left:var(--bs-navbar-nav-link-padding-x)}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas{position:static;z-index:auto;flex-grow:1;width:auto!important;height:auto!important;visibility:visible!important;background-color:transparent!important;border:0!important;transform:none!important;transition:none}.navbar-expand .offcanvas .offcanvas-header{display:none}.navbar-expand .offcanvas .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible}.navbar-dark{--bs-navbar-color:rgba(255, 255, 255, 0.55);--bs-navbar-hover-color:rgba(255, 255, 255, 0.75);--bs-navbar-disabled-color:rgba(255, 255, 255, 0.25);--bs-navbar-active-color:#fff;--bs-navbar-brand-color:#fff;--bs-navbar-brand-hover-color:#fff;--bs-navbar-toggler-border-color:rgba(255, 255, 255, 0.1);--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}[data-bs-theme=dark] .navbar{--bs-navbar-toggler-icon-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.card{--bs-card-spacer-y:1rem;--bs-card-spacer-x:1rem;--bs-card-title-spacer-y:0.5rem;--bs-card-title-color: ;--bs-card-subtitle-color: ;--bs-card-border-width:var(--bs-border-width);--bs-card-border-color:var(--bs-border-color-translucent);--bs-card-border-radius:var(--bs-border-radius);--bs-card-box-shadow: ;--bs-card-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-card-cap-padding-y:0.5rem;--bs-card-cap-padding-x:1rem;--bs-card-cap-bg:rgba(var(--bs-body-color-rgb), 0.03);--bs-card-cap-color: ;--bs-card-height: ;--bs-card-color: ;--bs-card-bg:var(--bs-body-bg);--bs-card-img-overlay-padding:1rem;--bs-card-group-margin:0.75rem;position:relative;display:flex;flex-direction:column;min-width:0;height:var(--bs-card-height);word-wrap:break-word;background-color:var(--bs-card-bg);background-clip:border-box;border:var(--bs-card-border-width) solid var(--bs-card-border-color);border-radius:var(--bs-card-border-radius)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:var(--bs-card-spacer-y) var(--bs-card-spacer-x);color:var(--bs-card-color)}.card-title{margin-bottom:var(--bs-card-title-spacer-y);color:var(--bs-card-title-color)}.card-subtitle{margin-top:calc(-.5 * var(--bs-card-title-spacer-y));margin-bottom:0;color:var(--bs-card-subtitle-color)}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:var(--bs-card-spacer-x)}.card-header{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);margin-bottom:0;color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-bottom:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-header:first-child{border-radius:var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0}.card-footer{padding:var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);color:var(--bs-card-cap-color);background-color:var(--bs-card-cap-bg);border-top:var(--bs-card-border-width) solid var(--bs-card-border-color)}.card-footer:last-child{border-radius:0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius)}.card-header-tabs{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-bottom:calc(-1 * var(--bs-card-cap-padding-y));margin-left:calc(-.5 * var(--bs-card-cap-padding-x));border-bottom:0}.card-header-tabs .nav-link.active{background-color:var(--bs-card-bg);border-bottom-color:var(--bs-card-bg)}.card-header-pills{margin-right:calc(-.5 * var(--bs-card-cap-padding-x));margin-left:calc(-.5 * var(--bs-card-cap-padding-x))}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:var(--bs-card-img-overlay-padding);border-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:var(--bs-card-inner-border-radius);border-top-right-radius:var(--bs-card-inner-border-radius)}.card-img,.card-img-bottom{border-bottom-right-radius:var(--bs-card-inner-border-radius);border-bottom-left-radius:var(--bs-card-inner-border-radius)}.card-group>.card{margin-bottom:var(--bs-card-group-margin)}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion{--bs-accordion-color:var(--bs-body-color);--bs-accordion-bg:var(--bs-body-bg);--bs-accordion-transition:color 0.15s ease-in-out,background-color 0.15s ease-in-out,border-color 0.15s ease-in-out,box-shadow 0.15s ease-in-out,border-radius 0.15s ease;--bs-accordion-border-color:var(--bs-border-color);--bs-accordion-border-width:var(--bs-border-width);--bs-accordion-border-radius:var(--bs-border-radius);--bs-accordion-inner-border-radius:calc(var(--bs-border-radius) - (var(--bs-border-width)));--bs-accordion-btn-padding-x:1.25rem;--bs-accordion-btn-padding-y:1rem;--bs-accordion-btn-color:var(--bs-body-color);--bs-accordion-btn-bg:var(--bs-accordion-bg);--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-icon-width:1.25rem;--bs-accordion-btn-icon-transform:rotate(-180deg);--bs-accordion-btn-icon-transition:transform 0.2s ease-in-out;--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230a58ca'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-focus-border-color:#86b7fe;--bs-accordion-btn-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-accordion-body-padding-x:1.25rem;--bs-accordion-body-padding-y:1rem;--bs-accordion-active-color:var(--bs-primary-text);--bs-accordion-active-bg:var(--bs-primary-bg-subtle)}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);font-size:1rem;color:var(--bs-accordion-btn-color);text-align:left;background-color:var(--bs-accordion-btn-bg);border:0;border-radius:0;overflow-anchor:none;transition:var(--bs-accordion-transition)}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:var(--bs-accordion-active-color);background-color:var(--bs-accordion-active-bg);box-shadow:inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color)}.accordion-button:not(.collapsed)::after{background-image:var(--bs-accordion-btn-active-icon);transform:var(--bs-accordion-btn-icon-transform)}.accordion-button::after{flex-shrink:0;width:var(--bs-accordion-btn-icon-width);height:var(--bs-accordion-btn-icon-width);margin-left:auto;content:"";background-image:var(--bs-accordion-btn-icon);background-repeat:no-repeat;background-size:var(--bs-accordion-btn-icon-width);transition:var(--bs-accordion-btn-icon-transition)}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:var(--bs-accordion-btn-focus-border-color);outline:0;box-shadow:var(--bs-accordion-btn-focus-box-shadow)}.accordion-header{margin-bottom:0}.accordion-item{color:var(--bs-accordion-color);background-color:var(--bs-accordion-bg);border:var(--bs-accordion-border-width) solid var(--bs-accordion-border-color)}.accordion-item:first-of-type{border-top-left-radius:var(--bs-accordion-border-radius);border-top-right-radius:var(--bs-accordion-border-radius)}.accordion-item:first-of-type .accordion-button{border-top-left-radius:var(--bs-accordion-inner-border-radius);border-top-right-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:var(--bs-accordion-inner-border-radius);border-bottom-left-radius:var(--bs-accordion-inner-border-radius)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:var(--bs-accordion-border-radius);border-bottom-left-radius:var(--bs-accordion-border-radius)}.accordion-body{padding:var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x)}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button,.accordion-flush .accordion-item .accordion-button.collapsed{border-radius:0}[data-bs-theme=dark] .accordion-button::after{--bs-accordion-btn-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");--bs-accordion-btn-active-icon:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.breadcrumb{--bs-breadcrumb-padding-x:0;--bs-breadcrumb-padding-y:0;--bs-breadcrumb-margin-bottom:1rem;--bs-breadcrumb-bg: ;--bs-breadcrumb-border-radius: ;--bs-breadcrumb-divider-color:var(--bs-secondary-color);--bs-breadcrumb-item-padding-x:0.5rem;--bs-breadcrumb-item-active-color:var(--bs-secondary-color);display:flex;flex-wrap:wrap;padding:var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);margin-bottom:var(--bs-breadcrumb-margin-bottom);font-size:var(--bs-breadcrumb-font-size);list-style:none;background-color:var(--bs-breadcrumb-bg);border-radius:var(--bs-breadcrumb-border-radius)}.breadcrumb-item+.breadcrumb-item{padding-left:var(--bs-breadcrumb-item-padding-x)}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:var(--bs-breadcrumb-item-padding-x);color:var(--bs-breadcrumb-divider-color);content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:var(--bs-breadcrumb-item-active-color)}.pagination{--bs-pagination-padding-x:0.75rem;--bs-pagination-padding-y:0.375rem;--bs-pagination-font-size:1rem;--bs-pagination-color:var(--bs-link-color);--bs-pagination-bg:var(--bs-body-bg);--bs-pagination-border-width:var(--bs-border-width);--bs-pagination-border-color:var(--bs-border-color);--bs-pagination-border-radius:var(--bs-border-radius);--bs-pagination-hover-color:var(--bs-link-hover-color);--bs-pagination-hover-bg:var(--bs-tertiary-bg);--bs-pagination-hover-border-color:var(--bs-border-color);--bs-pagination-focus-color:var(--bs-link-hover-color);--bs-pagination-focus-bg:var(--bs-secondary-bg);--bs-pagination-focus-box-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-pagination-active-color:#fff;--bs-pagination-active-bg:#0d6efd;--bs-pagination-active-border-color:#0d6efd;--bs-pagination-disabled-color:var(--bs-secondary-color);--bs-pagination-disabled-bg:var(--bs-secondary-bg);--bs-pagination-disabled-border-color:var(--bs-border-color);display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;padding:var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);font-size:var(--bs-pagination-font-size);color:var(--bs-pagination-color);text-decoration:none;background-color:var(--bs-pagination-bg);border:var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:var(--bs-pagination-hover-color);background-color:var(--bs-pagination-hover-bg);border-color:var(--bs-pagination-hover-border-color)}.page-link:focus{z-index:3;color:var(--bs-pagination-focus-color);background-color:var(--bs-pagination-focus-bg);outline:0;box-shadow:var(--bs-pagination-focus-box-shadow)}.active>.page-link,.page-link.active{z-index:3;color:var(--bs-pagination-active-color);background-color:var(--bs-pagination-active-bg);border-color:var(--bs-pagination-active-border-color)}.disabled>.page-link,.page-link.disabled{color:var(--bs-pagination-disabled-color);pointer-events:none;background-color:var(--bs-pagination-disabled-bg);border-color:var(--bs-pagination-disabled-border-color)}.page-item:not(:first-child) .page-link{margin-left:calc(var(--bs-border-width) * -1)}.page-item:first-child .page-link{border-top-left-radius:var(--bs-pagination-border-radius);border-bottom-left-radius:var(--bs-pagination-border-radius)}.page-item:last-child .page-link{border-top-right-radius:var(--bs-pagination-border-radius);border-bottom-right-radius:var(--bs-pagination-border-radius)}.pagination-lg{--bs-pagination-padding-x:1.5rem;--bs-pagination-padding-y:0.75rem;--bs-pagination-font-size:1.25rem;--bs-pagination-border-radius:0.5rem}.pagination-sm{--bs-pagination-padding-x:0.5rem;--bs-pagination-padding-y:0.25rem;--bs-pagination-font-size:0.875rem;--bs-pagination-border-radius:0.25rem}.badge{--bs-badge-padding-x:0.65em;--bs-badge-padding-y:0.35em;--bs-badge-font-size:0.75em;--bs-badge-font-weight:700;--bs-badge-color:#fff;--bs-badge-border-radius:0.375rem;display:inline-block;padding:var(--bs-badge-padding-y) var(--bs-badge-padding-x);font-size:var(--bs-badge-font-size);font-weight:var(--bs-badge-font-weight);line-height:1;color:var(--bs-badge-color);text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:var(--bs-badge-border-radius)}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{--bs-alert-bg:transparent;--bs-alert-padding-x:1rem;--bs-alert-padding-y:1rem;--bs-alert-margin-bottom:1rem;--bs-alert-color:inherit;--bs-alert-border-color:transparent;--bs-alert-border:var(--bs-border-width) solid var(--bs-alert-border-color);--bs-alert-border-radius:0.375rem;--bs-alert-link-color:inherit;position:relative;padding:var(--bs-alert-padding-y) var(--bs-alert-padding-x);margin-bottom:var(--bs-alert-margin-bottom);color:var(--bs-alert-color);background-color:var(--bs-alert-bg);border:var(--bs-alert-border);border-radius:var(--bs-alert-border-radius)}.alert-heading{color:inherit}.alert-link{font-weight:700;color:var(--bs-alert-link-color)}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{--bs-alert-color:var(--bs-primary-text);--bs-alert-bg:var(--bs-primary-bg-subtle);--bs-alert-border-color:var(--bs-primary-border-subtle);--bs-alert-link-color:var(--bs-primary-text)}.alert-secondary{--bs-alert-color:var(--bs-secondary-text);--bs-alert-bg:var(--bs-secondary-bg-subtle);--bs-alert-border-color:var(--bs-secondary-border-subtle);--bs-alert-link-color:var(--bs-secondary-text)}.alert-success{--bs-alert-color:var(--bs-success-text);--bs-alert-bg:var(--bs-success-bg-subtle);--bs-alert-border-color:var(--bs-success-border-subtle);--bs-alert-link-color:var(--bs-success-text)}.alert-info{--bs-alert-color:var(--bs-info-text);--bs-alert-bg:var(--bs-info-bg-subtle);--bs-alert-border-color:var(--bs-info-border-subtle);--bs-alert-link-color:var(--bs-info-text)}.alert-warning{--bs-alert-color:var(--bs-warning-text);--bs-alert-bg:var(--bs-warning-bg-subtle);--bs-alert-border-color:var(--bs-warning-border-subtle);--bs-alert-link-color:var(--bs-warning-text)}.alert-danger{--bs-alert-color:var(--bs-danger-text);--bs-alert-bg:var(--bs-danger-bg-subtle);--bs-alert-border-color:var(--bs-danger-border-subtle);--bs-alert-link-color:var(--bs-danger-text)}.alert-light{--bs-alert-color:var(--bs-light-text);--bs-alert-bg:var(--bs-light-bg-subtle);--bs-alert-border-color:var(--bs-light-border-subtle);--bs-alert-link-color:var(--bs-light-text)}.alert-dark{--bs-alert-color:var(--bs-dark-text);--bs-alert-bg:var(--bs-dark-bg-subtle);--bs-alert-border-color:var(--bs-dark-border-subtle);--bs-alert-link-color:var(--bs-dark-text)}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress,.progress-stacked{--bs-progress-height:1rem;--bs-progress-font-size:0.75rem;--bs-progress-bg:var(--bs-secondary-bg);--bs-progress-border-radius:var(--bs-border-radius);--bs-progress-box-shadow:var(--bs-box-shadow-inset);--bs-progress-bar-color:#fff;--bs-progress-bar-bg:#0d6efd;--bs-progress-bar-transition:width 0.6s ease;display:flex;height:var(--bs-progress-height);overflow:hidden;font-size:var(--bs-progress-font-size);background-color:var(--bs-progress-bg);border-radius:var(--bs-progress-border-radius)}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:var(--bs-progress-bar-color);text-align:center;white-space:nowrap;background-color:var(--bs-progress-bar-bg);transition:var(--bs-progress-bar-transition)}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:var(--bs-progress-height) var(--bs-progress-height)}.progress-stacked>.progress{overflow:visible}.progress-stacked>.progress>.progress-bar{width:100%}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{animation:none}}.list-group{--bs-list-group-color:var(--bs-body-color);--bs-list-group-bg:var(--bs-body-bg);--bs-list-group-border-color:var(--bs-border-color);--bs-list-group-border-width:var(--bs-border-width);--bs-list-group-border-radius:var(--bs-border-radius);--bs-list-group-item-padding-x:1rem;--bs-list-group-item-padding-y:0.5rem;--bs-list-group-action-color:var(--bs-secondary-color);--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-tertiary-bg);--bs-list-group-action-active-color:var(--bs-body-color);--bs-list-group-action-active-bg:var(--bs-secondary-bg);--bs-list-group-disabled-color:var(--bs-secondary-color);--bs-list-group-disabled-bg:var(--bs-body-bg);--bs-list-group-active-color:#fff;--bs-list-group-active-bg:#0d6efd;--bs-list-group-active-border-color:#0d6efd;display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:var(--bs-list-group-border-radius)}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>.list-group-item::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:var(--bs-list-group-action-color);text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:var(--bs-list-group-action-hover-color);text-decoration:none;background-color:var(--bs-list-group-action-hover-bg)}.list-group-item-action:active{color:var(--bs-list-group-action-active-color);background-color:var(--bs-list-group-action-active-bg)}.list-group-item{position:relative;display:block;padding:var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);color:var(--bs-list-group-color);text-decoration:none;background-color:var(--bs-list-group-bg);border:var(--bs-list-group-border-width) solid var(--bs-list-group-border-color)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:var(--bs-list-group-disabled-color);pointer-events:none;background-color:var(--bs-list-group-disabled-bg)}.list-group-item.active{z-index:2;color:var(--bs-list-group-active-color);background-color:var(--bs-list-group-active-bg);border-color:var(--bs-list-group-active-border-color)}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:calc(-1 * var(--bs-list-group-border-width));border-top-width:var(--bs-list-group-border-width)}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child:not(:last-child){border-bottom-left-radius:var(--bs-list-group-border-radius);border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child:not(:first-child){border-top-right-radius:var(--bs-list-group-border-radius);border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:var(--bs-list-group-border-width);border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:calc(-1 * var(--bs-list-group-border-width));border-left-width:var(--bs-list-group-border-width)}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 var(--bs-list-group-border-width)}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{--bs-list-group-color:var(--bs-primary-text);--bs-list-group-bg:var(--bs-primary-bg-subtle);--bs-list-group-border-color:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-primary-border-subtle)}.list-group-item-primary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-primary-text);--bs-list-group-active-border-color:var(--bs-primary-text)}.list-group-item-secondary{--bs-list-group-color:var(--bs-secondary-text);--bs-list-group-bg:var(--bs-secondary-bg-subtle);--bs-list-group-border-color:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-secondary-border-subtle)}.list-group-item-secondary.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-secondary-text);--bs-list-group-active-border-color:var(--bs-secondary-text)}.list-group-item-success{--bs-list-group-color:var(--bs-success-text);--bs-list-group-bg:var(--bs-success-bg-subtle);--bs-list-group-border-color:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-success-border-subtle)}.list-group-item-success.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-success-text);--bs-list-group-active-border-color:var(--bs-success-text)}.list-group-item-info{--bs-list-group-color:var(--bs-info-text);--bs-list-group-bg:var(--bs-info-bg-subtle);--bs-list-group-border-color:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-info-border-subtle)}.list-group-item-info.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-info-text);--bs-list-group-active-border-color:var(--bs-info-text)}.list-group-item-warning{--bs-list-group-color:var(--bs-warning-text);--bs-list-group-bg:var(--bs-warning-bg-subtle);--bs-list-group-border-color:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-warning-border-subtle)}.list-group-item-warning.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-warning-text);--bs-list-group-active-border-color:var(--bs-warning-text)}.list-group-item-danger{--bs-list-group-color:var(--bs-danger-text);--bs-list-group-bg:var(--bs-danger-bg-subtle);--bs-list-group-border-color:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-danger-border-subtle)}.list-group-item-danger.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-danger-text);--bs-list-group-active-border-color:var(--bs-danger-text)}.list-group-item-light{--bs-list-group-color:var(--bs-light-text);--bs-list-group-bg:var(--bs-light-bg-subtle);--bs-list-group-border-color:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-light-border-subtle)}.list-group-item-light.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-light-text);--bs-list-group-active-border-color:var(--bs-light-text)}.list-group-item-dark{--bs-list-group-color:var(--bs-dark-text);--bs-list-group-bg:var(--bs-dark-bg-subtle);--bs-list-group-border-color:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{--bs-list-group-action-hover-color:var(--bs-emphasis-color);--bs-list-group-action-hover-bg:var(--bs-dark-border-subtle)}.list-group-item-dark.list-group-item-action:active{--bs-list-group-active-color:var(--bs-emphasis-color);--bs-list-group-active-bg:var(--bs-dark-text);--bs-list-group-active-border-color:var(--bs-dark-text)}.btn-close{--bs-btn-close-color:#000;--bs-btn-close-bg:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e");--bs-btn-close-opacity:0.5;--bs-btn-close-hover-opacity:0.75;--bs-btn-close-focus-shadow:0 0 0 0.25rem rgba(13, 110, 253, 0.25);--bs-btn-close-focus-opacity:1;--bs-btn-close-disabled-opacity:0.25;--bs-btn-close-white-filter:invert(1) grayscale(100%) brightness(200%);box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:var(--bs-btn-close-color);background:transparent var(--bs-btn-close-bg) center/1em auto no-repeat;border:0;border-radius:.375rem;opacity:var(--bs-btn-close-opacity)}.btn-close:hover{color:var(--bs-btn-close-color);text-decoration:none;opacity:var(--bs-btn-close-hover-opacity)}.btn-close:focus{outline:0;box-shadow:var(--bs-btn-close-focus-shadow);opacity:var(--bs-btn-close-focus-opacity)}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:var(--bs-btn-close-disabled-opacity)}.btn-close-white{filter:var(--bs-btn-close-white-filter)}[data-bs-theme=dark] .btn-close{filter:var(--bs-btn-close-white-filter)}.toast{--bs-toast-zindex:1090;--bs-toast-padding-x:0.75rem;--bs-toast-padding-y:0.5rem;--bs-toast-spacing:1.5rem;--bs-toast-max-width:350px;--bs-toast-font-size:0.875rem;--bs-toast-color: ;--bs-toast-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-border-width:var(--bs-border-width);--bs-toast-border-color:var(--bs-border-color-translucent);--bs-toast-border-radius:var(--bs-border-radius);--bs-toast-box-shadow:var(--bs-box-shadow);--bs-toast-header-color:var(--bs-secondary-color);--bs-toast-header-bg:rgba(var(--bs-body-bg-rgb), 0.85);--bs-toast-header-border-color:var(--bs-border-color-translucent);width:var(--bs-toast-max-width);max-width:100%;font-size:var(--bs-toast-font-size);color:var(--bs-toast-color);pointer-events:auto;background-color:var(--bs-toast-bg);background-clip:padding-box;border:var(--bs-toast-border-width) solid var(--bs-toast-border-color);box-shadow:var(--bs-toast-box-shadow);border-radius:var(--bs-toast-border-radius)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{--bs-toast-zindex:1090;position:absolute;z-index:var(--bs-toast-zindex);width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:var(--bs-toast-spacing)}.toast-header{display:flex;align-items:center;padding:var(--bs-toast-padding-y) var(--bs-toast-padding-x);color:var(--bs-toast-header-color);background-color:var(--bs-toast-header-bg);background-clip:padding-box;border-bottom:var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);border-top-left-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));border-top-right-radius:calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width))}.toast-header .btn-close{margin-right:calc(-.5 * var(--bs-toast-padding-x));margin-left:var(--bs-toast-padding-x)}.toast-body{padding:var(--bs-toast-padding-x);word-wrap:break-word}.modal{--bs-modal-zindex:1055;--bs-modal-width:500px;--bs-modal-padding:1rem;--bs-modal-margin:0.5rem;--bs-modal-color: ;--bs-modal-bg:var(--bs-body-bg);--bs-modal-border-color:var(--bs-border-color-translucent);--bs-modal-border-width:var(--bs-border-width);--bs-modal-border-radius:var(--bs-border-radius-lg);--bs-modal-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-modal-inner-border-radius:calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));--bs-modal-header-padding-x:1rem;--bs-modal-header-padding-y:1rem;--bs-modal-header-padding:1rem 1rem;--bs-modal-header-border-color:var(--bs-border-color);--bs-modal-header-border-width:var(--bs-border-width);--bs-modal-title-line-height:1.5;--bs-modal-footer-gap:0.5rem;--bs-modal-footer-bg: ;--bs-modal-footer-border-color:var(--bs-border-color);--bs-modal-footer-border-width:var(--bs-border-width);position:fixed;top:0;left:0;z-index:var(--bs-modal-zindex);display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:var(--bs-modal-margin);pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - var(--bs-modal-margin) * 2)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - var(--bs-modal-margin) * 2)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;color:var(--bs-modal-color);pointer-events:auto;background-color:var(--bs-modal-bg);background-clip:padding-box;border:var(--bs-modal-border-width) solid var(--bs-modal-border-color);border-radius:var(--bs-modal-border-radius);outline:0}.modal-backdrop{--bs-backdrop-zindex:1050;--bs-backdrop-bg:#000;--bs-backdrop-opacity:0.5;position:fixed;top:0;left:0;z-index:var(--bs-backdrop-zindex);width:100vw;height:100vh;background-color:var(--bs-backdrop-bg)}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:var(--bs-backdrop-opacity)}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:var(--bs-modal-header-padding);border-bottom:var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);border-top-left-radius:var(--bs-modal-inner-border-radius);border-top-right-radius:var(--bs-modal-inner-border-radius)}.modal-header .btn-close{padding:calc(var(--bs-modal-header-padding-y) * .5) calc(var(--bs-modal-header-padding-x) * .5);margin:calc(-.5 * var(--bs-modal-header-padding-y)) calc(-.5 * var(--bs-modal-header-padding-x)) calc(-.5 * var(--bs-modal-header-padding-y)) auto}.modal-title{margin-bottom:0;line-height:var(--bs-modal-title-line-height)}.modal-body{position:relative;flex:1 1 auto;padding:var(--bs-modal-padding)}.modal-footer{display:flex;flex-shrink:0;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * .5);background-color:var(--bs-modal-footer-bg);border-top:var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);border-bottom-right-radius:var(--bs-modal-inner-border-radius);border-bottom-left-radius:var(--bs-modal-inner-border-radius)}.modal-footer>*{margin:calc(var(--bs-modal-footer-gap) * .5)}@media (min-width:576px){.modal{--bs-modal-margin:1.75rem;--bs-modal-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15)}.modal-dialog{max-width:var(--bs-modal-width);margin-right:auto;margin-left:auto}.modal-sm{--bs-modal-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{--bs-modal-width:800px}}@media (min-width:1200px){.modal-xl{--bs-modal-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-footer,.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-footer,.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-footer,.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-footer,.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-footer,.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-footer,.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{--bs-tooltip-zindex:1080;--bs-tooltip-max-width:200px;--bs-tooltip-padding-x:0.5rem;--bs-tooltip-padding-y:0.25rem;--bs-tooltip-margin: ;--bs-tooltip-font-size:0.875rem;--bs-tooltip-color:var(--bs-body-bg);--bs-tooltip-bg:var(--bs-emphasis-color);--bs-tooltip-border-radius:var(--bs-border-radius);--bs-tooltip-opacity:0.9;--bs-tooltip-arrow-width:0.8rem;--bs-tooltip-arrow-height:0.4rem;z-index:var(--bs-tooltip-zindex);display:block;padding:var(--bs-tooltip-arrow-height);margin:var(--bs-tooltip-margin);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-tooltip-font-size);word-wrap:break-word;opacity:0}.tooltip.show{opacity:var(--bs-tooltip-opacity)}.tooltip .tooltip-arrow{display:block;width:var(--bs-tooltip-arrow-width);height:var(--bs-tooltip-arrow-height)}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-top-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * .5) 0;border-right-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-bottom-color:var(--bs-tooltip-bg)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:var(--bs-tooltip-arrow-height);height:var(--bs-tooltip-arrow-width)}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:calc(var(--bs-tooltip-arrow-width) * .5) 0 calc(var(--bs-tooltip-arrow-width) * .5) var(--bs-tooltip-arrow-height);border-left-color:var(--bs-tooltip-bg)}.tooltip-inner{max-width:var(--bs-tooltip-max-width);padding:var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);color:var(--bs-tooltip-color);text-align:center;background-color:var(--bs-tooltip-bg);border-radius:var(--bs-tooltip-border-radius)}.popover{--bs-popover-zindex:1070;--bs-popover-max-width:276px;--bs-popover-font-size:0.875rem;--bs-popover-bg:var(--bs-body-bg);--bs-popover-border-width:var(--bs-border-width);--bs-popover-border-color:var(--bs-border-color-translucent);--bs-popover-border-radius:var(--bs-border-radius-lg);--bs-popover-inner-border-radius:calc(var(--bs-border-radius-lg) - var(--bs-border-width));--bs-popover-box-shadow:0 0.5rem 1rem rgba(var(--bs-body-color-rgb), 0.15);--bs-popover-header-padding-x:1rem;--bs-popover-header-padding-y:0.5rem;--bs-popover-header-font-size:1rem;--bs-popover-header-color: ;--bs-popover-header-bg:var(--bs-secondary-bg);--bs-popover-body-padding-x:1rem;--bs-popover-body-padding-y:1rem;--bs-popover-body-color:var(--bs-body-color);--bs-popover-arrow-width:1rem;--bs-popover-arrow-height:0.5rem;--bs-popover-arrow-border:var(--bs-popover-border-color);z-index:var(--bs-popover-zindex);display:block;max-width:var(--bs-popover-max-width);font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;white-space:normal;word-spacing:normal;line-break:auto;font-size:var(--bs-popover-font-size);word-wrap:break-word;background-color:var(--bs-popover-bg);background-clip:padding-box;border:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-radius:var(--bs-popover-border-radius)}.popover .popover-arrow{display:block;width:var(--bs-popover-arrow-width);height:var(--bs-popover-arrow-height)}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid;border-width:0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::after,.bs-popover-top>.popover-arrow::before{border-width:var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-top-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:var(--bs-popover-border-width);border-top-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::after,.bs-popover-end>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * .5) 0}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-right-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:var(--bs-popover-border-width);border-right-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width))}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::before{border-width:0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-bottom-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:var(--bs-popover-border-width);border-bottom-color:var(--bs-popover-bg)}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:var(--bs-popover-arrow-width);margin-left:calc(-.5 * var(--bs-popover-arrow-width));content:"";border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-header-bg)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));width:var(--bs-popover-arrow-height);height:var(--bs-popover-arrow-width)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::after,.bs-popover-start>.popover-arrow::before{border-width:calc(var(--bs-popover-arrow-width) * .5) 0 calc(var(--bs-popover-arrow-width) * .5) var(--bs-popover-arrow-height)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-left-color:var(--bs-popover-arrow-border)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:var(--bs-popover-border-width);border-left-color:var(--bs-popover-bg)}.popover-header{padding:var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);margin-bottom:0;font-size:var(--bs-popover-header-font-size);color:var(--bs-popover-header-color);background-color:var(--bs-popover-header-bg);border-bottom:var(--bs-popover-border-width) solid var(--bs-popover-border-color);border-top-left-radius:var(--bs-popover-inner-border-radius);border-top-right-radius:var(--bs-popover-inner-border-radius)}.popover-header:empty{display:none}.popover-body{padding:var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);color:var(--bs-popover-body-color)}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}[data-bs-theme=dark] .carousel .carousel-control-next-icon,[data-bs-theme=dark] .carousel .carousel-control-prev-icon{filter:invert(1) grayscale(100)}[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target]{background-color:#000}[data-bs-theme=dark] .carousel .carousel-caption{color:#000}.spinner-border,.spinner-grow{display:inline-block;width:var(--bs-spinner-width);height:var(--bs-spinner-height);vertical-align:var(--bs-spinner-vertical-align);border-radius:50%;animation:var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name)}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-border-width:0.25em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-border;border:var(--bs-spinner-border-width) solid currentcolor;border-right-color:transparent}.spinner-border-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem;--bs-spinner-border-width:0.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{--bs-spinner-width:2rem;--bs-spinner-height:2rem;--bs-spinner-vertical-align:-0.125em;--bs-spinner-animation-speed:0.75s;--bs-spinner-animation-name:spinner-grow;background-color:currentcolor;opacity:0}.spinner-grow-sm{--bs-spinner-width:1rem;--bs-spinner-height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{--bs-spinner-animation-speed:1.5s}}.offcanvas,.offcanvas-lg,.offcanvas-md,.offcanvas-sm,.offcanvas-xl,.offcanvas-xxl{--bs-offcanvas-zindex:1045;--bs-offcanvas-width:400px;--bs-offcanvas-height:30vh;--bs-offcanvas-padding-x:1rem;--bs-offcanvas-padding-y:1rem;--bs-offcanvas-color:var(--bs-body-color);--bs-offcanvas-bg:var(--bs-body-bg);--bs-offcanvas-border-width:var(--bs-border-width);--bs-offcanvas-border-color:var(--bs-border-color-translucent);--bs-offcanvas-box-shadow:0 0.125rem 0.25rem rgba(var(--bs-body-color-rgb), 0.075);--bs-offcanvas-transition:transform 0.3s ease-in-out;--bs-offcanvas-title-line-height:1.5}@media (max-width:575.98px){.offcanvas-sm{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:575.98px) and (prefers-reduced-motion:reduce){.offcanvas-sm{transition:none}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:575.98px){.offcanvas-sm.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:575.98px){.offcanvas-sm.show:not(.hiding),.offcanvas-sm.showing{transform:none}}@media (max-width:575.98px){.offcanvas-sm.hiding,.offcanvas-sm.show,.offcanvas-sm.showing{visibility:visible}}@media (min-width:576px){.offcanvas-sm{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-sm .offcanvas-header{display:none}.offcanvas-sm .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:767.98px){.offcanvas-md{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:767.98px) and (prefers-reduced-motion:reduce){.offcanvas-md{transition:none}}@media (max-width:767.98px){.offcanvas-md.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:767.98px){.offcanvas-md.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:767.98px){.offcanvas-md.show:not(.hiding),.offcanvas-md.showing{transform:none}}@media (max-width:767.98px){.offcanvas-md.hiding,.offcanvas-md.show,.offcanvas-md.showing{visibility:visible}}@media (min-width:768px){.offcanvas-md{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-md .offcanvas-header{display:none}.offcanvas-md .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:991.98px){.offcanvas-lg{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:991.98px) and (prefers-reduced-motion:reduce){.offcanvas-lg{transition:none}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:991.98px){.offcanvas-lg.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:991.98px){.offcanvas-lg.show:not(.hiding),.offcanvas-lg.showing{transform:none}}@media (max-width:991.98px){.offcanvas-lg.hiding,.offcanvas-lg.show,.offcanvas-lg.showing{visibility:visible}}@media (min-width:992px){.offcanvas-lg{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-lg .offcanvas-header{display:none}.offcanvas-lg .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1199.98px){.offcanvas-xl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1199.98px) and (prefers-reduced-motion:reduce){.offcanvas-xl{transition:none}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1199.98px){.offcanvas-xl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1199.98px){.offcanvas-xl.show:not(.hiding),.offcanvas-xl.showing{transform:none}}@media (max-width:1199.98px){.offcanvas-xl.hiding,.offcanvas-xl.show,.offcanvas-xl.showing{visibility:visible}}@media (min-width:1200px){.offcanvas-xl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xl .offcanvas-header{display:none}.offcanvas-xl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}@media (max-width:1399.98px){.offcanvas-xxl{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}}@media (max-width:1399.98px) and (prefers-reduced-motion:reduce){.offcanvas-xxl{transition:none}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}}@media (max-width:1399.98px){.offcanvas-xxl.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}}@media (max-width:1399.98px){.offcanvas-xxl.show:not(.hiding),.offcanvas-xxl.showing{transform:none}}@media (max-width:1399.98px){.offcanvas-xxl.hiding,.offcanvas-xxl.show,.offcanvas-xxl.showing{visibility:visible}}@media (min-width:1400px){.offcanvas-xxl{--bs-offcanvas-height:auto;--bs-offcanvas-border-width:0;background-color:transparent!important}.offcanvas-xxl .offcanvas-header{display:none}.offcanvas-xxl .offcanvas-body{display:flex;flex-grow:0;padding:0;overflow-y:visible;background-color:transparent!important}}.offcanvas{position:fixed;bottom:0;z-index:var(--bs-offcanvas-zindex);display:flex;flex-direction:column;max-width:100%;color:var(--bs-offcanvas-color);visibility:hidden;background-color:var(--bs-offcanvas-bg);background-clip:padding-box;outline:0;transition:var(--bs-offcanvas-transition)}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas.offcanvas-start{top:0;left:0;width:var(--bs-offcanvas-width);border-right:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(-100%)}.offcanvas.offcanvas-end{top:0;right:0;width:var(--bs-offcanvas-width);border-left:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateX(100%)}.offcanvas.offcanvas-top{top:0;right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-bottom:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(-100%)}.offcanvas.offcanvas-bottom{right:0;left:0;height:var(--bs-offcanvas-height);max-height:100%;border-top:var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);transform:translateY(100%)}.offcanvas.show:not(.hiding),.offcanvas.showing{transform:none}.offcanvas.hiding,.offcanvas.show,.offcanvas.showing{visibility:visible}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x)}.offcanvas-header .btn-close{padding:calc(var(--bs-offcanvas-padding-y) * .5) calc(var(--bs-offcanvas-padding-x) * .5);margin-top:calc(-.5 * var(--bs-offcanvas-padding-y));margin-right:calc(-.5 * var(--bs-offcanvas-padding-x));margin-bottom:calc(-.5 * var(--bs-offcanvas-padding-y))}.offcanvas-title{margin-bottom:0;line-height:var(--bs-offcanvas-title-line-height)}.offcanvas-body{flex-grow:1;padding:var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);overflow-y:auto}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentcolor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{-webkit-mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);mask-image:linear-gradient(130deg,#000 55%,rgba(0,0,0,0.8) 75%,#000 95%);-webkit-mask-size:200% 100%;mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{-webkit-mask-position:-200% 0%;mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.text-bg-primary{color:#fff!important;background-color:RGBA(13,110,253,var(--bs-bg-opacity,1))!important}.text-bg-secondary{color:#fff!important;background-color:RGBA(108,117,125,var(--bs-bg-opacity,1))!important}.text-bg-success{color:#fff!important;background-color:RGBA(25,135,84,var(--bs-bg-opacity,1))!important}.text-bg-info{color:#000!important;background-color:RGBA(13,202,240,var(--bs-bg-opacity,1))!important}.text-bg-warning{color:#000!important;background-color:RGBA(255,193,7,var(--bs-bg-opacity,1))!important}.text-bg-danger{color:#fff!important;background-color:RGBA(220,53,69,var(--bs-bg-opacity,1))!important}.text-bg-light{color:#000!important;background-color:RGBA(248,249,250,var(--bs-bg-opacity,1))!important}.text-bg-dark{color:#fff!important;background-color:RGBA(33,37,41,var(--bs-bg-opacity,1))!important}.link-primary{color:#0d6efd!important}.link-primary:focus,.link-primary:hover{color:#0a58ca!important}.link-secondary{color:#6c757d!important}.link-secondary:focus,.link-secondary:hover{color:#565e64!important}.link-success{color:#198754!important}.link-success:focus,.link-success:hover{color:#146c43!important}.link-info{color:#0dcaf0!important}.link-info:focus,.link-info:hover{color:#3dd5f3!important}.link-warning{color:#ffc107!important}.link-warning:focus,.link-warning:hover{color:#ffcd39!important}.link-danger{color:#dc3545!important}.link-danger:focus,.link-danger:hover{color:#b02a37!important}.link-light{color:#f8f9fa!important}.link-light:focus,.link-light:hover{color:#f9fafb!important}.link-dark{color:#212529!important}.link-dark:focus,.link-dark:hover{color:#1a1e21!important}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:75%}.ratio-16x9{--bs-aspect-ratio:56.25%}.ratio-21x9{--bs-aspect-ratio:42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-sm-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-md-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-lg-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}.sticky-xxl-bottom{position:-webkit-sticky;position:sticky;bottom:0;z-index:1020}}.hstack{display:flex;flex-direction:row;align-items:center;align-self:stretch}.vstack{display:flex;flex:1 1 auto;flex-direction:column;align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;width:1px;min-height:1em;background-color:currentcolor;opacity:.25}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.object-fit-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-none{-o-object-fit:none!important;object-fit:none!important}.opacity-0{opacity:0!important}.opacity-25{opacity:.25!important}.opacity-50{opacity:.5!important}.opacity-75{opacity:.75!important}.opacity-100{opacity:1!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.overflow-x-auto{overflow-x:auto!important}.overflow-x-hidden{overflow-x:hidden!important}.overflow-x-visible{overflow-x:visible!important}.overflow-x-scroll{overflow-x:scroll!important}.overflow-y-auto{overflow-y:auto!important}.overflow-y-hidden{overflow-y:hidden!important}.overflow-y-visible{overflow-y:visible!important}.overflow-y-scroll{overflow-y:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(var(--bs-body-color-rgb),.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(var(--bs-body-color-rgb),.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(var(--bs-body-color-rgb),.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-0{border:0!important}.border-top{border-top:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-top-0{border-top:0!important}.border-end{border-right:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:var(--bs-border-width) var(--bs-border-style) var(--bs-border-color)!important}.border-start-0{border-left:0!important}.border-primary{--bs-border-opacity:1;border-color:rgba(var(--bs-primary-rgb),var(--bs-border-opacity))!important}.border-secondary{--bs-border-opacity:1;border-color:rgba(var(--bs-secondary-rgb),var(--bs-border-opacity))!important}.border-success{--bs-border-opacity:1;border-color:rgba(var(--bs-success-rgb),var(--bs-border-opacity))!important}.border-info{--bs-border-opacity:1;border-color:rgba(var(--bs-info-rgb),var(--bs-border-opacity))!important}.border-warning{--bs-border-opacity:1;border-color:rgba(var(--bs-warning-rgb),var(--bs-border-opacity))!important}.border-danger{--bs-border-opacity:1;border-color:rgba(var(--bs-danger-rgb),var(--bs-border-opacity))!important}.border-light{--bs-border-opacity:1;border-color:rgba(var(--bs-light-rgb),var(--bs-border-opacity))!important}.border-dark{--bs-border-opacity:1;border-color:rgba(var(--bs-dark-rgb),var(--bs-border-opacity))!important}.border-white{--bs-border-opacity:1;border-color:rgba(var(--bs-white-rgb),var(--bs-border-opacity))!important}.border-primary-subtle{border-color:var(--bs-primary-border-subtle)!important}.border-secondary-subtle{border-color:var(--bs-secondary-border-subtle)!important}.border-success-subtle{border-color:var(--bs-success-border-subtle)!important}.border-info-subtle{border-color:var(--bs-info-border-subtle)!important}.border-warning-subtle{border-color:var(--bs-warning-border-subtle)!important}.border-danger-subtle{border-color:var(--bs-danger-border-subtle)!important}.border-light-subtle{border-color:var(--bs-light-border-subtle)!important}.border-dark-subtle{border-color:var(--bs-dark-border-subtle)!important}.border-1{--bs-border-width:1px}.border-2{--bs-border-width:2px}.border-3{--bs-border-width:3px}.border-4{--bs-border-width:4px}.border-5{--bs-border-width:5px}.border-opacity-10{--bs-border-opacity:0.1}.border-opacity-25{--bs-border-opacity:0.25}.border-opacity-50{--bs-border-opacity:0.5}.border-opacity-75{--bs-border-opacity:0.75}.border-opacity-100{--bs-border-opacity:1}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.row-gap-0{row-gap:0!important}.row-gap-1{row-gap:.25rem!important}.row-gap-2{row-gap:.5rem!important}.row-gap-3{row-gap:1rem!important}.row-gap-4{row-gap:1.5rem!important}.row-gap-5{row-gap:3rem!important}.column-gap-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-lighter{font-weight:lighter!important}.fw-light{font-weight:300!important}.fw-normal{font-weight:400!important}.fw-medium{font-weight:500!important}.fw-semibold{font-weight:600!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{--bs-text-opacity:1;color:rgba(var(--bs-primary-rgb),var(--bs-text-opacity))!important}.text-secondary{--bs-text-opacity:1;color:rgba(var(--bs-secondary-rgb),var(--bs-text-opacity))!important}.text-success{--bs-text-opacity:1;color:rgba(var(--bs-success-rgb),var(--bs-text-opacity))!important}.text-info{--bs-text-opacity:1;color:rgba(var(--bs-info-rgb),var(--bs-text-opacity))!important}.text-warning{--bs-text-opacity:1;color:rgba(var(--bs-warning-rgb),var(--bs-text-opacity))!important}.text-danger{--bs-text-opacity:1;color:rgba(var(--bs-danger-rgb),var(--bs-text-opacity))!important}.text-light{--bs-text-opacity:1;color:rgba(var(--bs-light-rgb),var(--bs-text-opacity))!important}.text-dark{--bs-text-opacity:1;color:rgba(var(--bs-dark-rgb),var(--bs-text-opacity))!important}.text-black{--bs-text-opacity:1;color:rgba(var(--bs-black-rgb),var(--bs-text-opacity))!important}.text-white{--bs-text-opacity:1;color:rgba(var(--bs-white-rgb),var(--bs-text-opacity))!important}.text-body{--bs-text-opacity:1;color:rgba(var(--bs-body-color-rgb),var(--bs-text-opacity))!important}.text-muted{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-black-50{--bs-text-opacity:1;color:rgba(0,0,0,.5)!important}.text-white-50{--bs-text-opacity:1;color:rgba(255,255,255,.5)!important}.text-body-secondary{--bs-text-opacity:1;color:var(--bs-secondary-color)!important}.text-body-tertiary{--bs-text-opacity:1;color:var(--bs-tertiary-color)!important}.text-body-emphasis{--bs-text-opacity:1;color:var(--bs-emphasis-color)!important}.text-reset{--bs-text-opacity:1;color:inherit!important}.text-opacity-25{--bs-text-opacity:0.25}.text-opacity-50{--bs-text-opacity:0.5}.text-opacity-75{--bs-text-opacity:0.75}.text-opacity-100{--bs-text-opacity:1}.text-primary-emphasis{color:var(--bs-primary-text)!important}.text-secondary-emphasis{color:var(--bs-secondary-text)!important}.text-success-emphasis{color:var(--bs-success-text)!important}.text-info-emphasis{color:var(--bs-info-text)!important}.text-warning-emphasis{color:var(--bs-warning-text)!important}.text-danger-emphasis{color:var(--bs-danger-text)!important}.text-light-emphasis{color:var(--bs-light-text)!important}.text-dark-emphasis{color:var(--bs-dark-text)!important}.bg-primary{--bs-bg-opacity:1;background-color:rgba(var(--bs-primary-rgb),var(--bs-bg-opacity))!important}.bg-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-rgb),var(--bs-bg-opacity))!important}.bg-success{--bs-bg-opacity:1;background-color:rgba(var(--bs-success-rgb),var(--bs-bg-opacity))!important}.bg-info{--bs-bg-opacity:1;background-color:rgba(var(--bs-info-rgb),var(--bs-bg-opacity))!important}.bg-warning{--bs-bg-opacity:1;background-color:rgba(var(--bs-warning-rgb),var(--bs-bg-opacity))!important}.bg-danger{--bs-bg-opacity:1;background-color:rgba(var(--bs-danger-rgb),var(--bs-bg-opacity))!important}.bg-light{--bs-bg-opacity:1;background-color:rgba(var(--bs-light-rgb),var(--bs-bg-opacity))!important}.bg-dark{--bs-bg-opacity:1;background-color:rgba(var(--bs-dark-rgb),var(--bs-bg-opacity))!important}.bg-black{--bs-bg-opacity:1;background-color:rgba(var(--bs-black-rgb),var(--bs-bg-opacity))!important}.bg-white{--bs-bg-opacity:1;background-color:rgba(var(--bs-white-rgb),var(--bs-bg-opacity))!important}.bg-body{--bs-bg-opacity:1;background-color:rgba(var(--bs-body-bg-rgb),var(--bs-bg-opacity))!important}.bg-transparent{--bs-bg-opacity:1;background-color:transparent!important}.bg-body-secondary{--bs-bg-opacity:1;background-color:rgba(var(--bs-secondary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-tertiary{--bs-bg-opacity:1;background-color:rgba(var(--bs-tertiary-bg-rgb),var(--bs-bg-opacity))!important}.bg-body-emphasis{--bs-bg-opacity:1;background-color:rgba(var(--bs-emphasis-bg-rgb),var(--bs-bg-opacity))!important}.bg-opacity-10{--bs-bg-opacity:0.1}.bg-opacity-25{--bs-bg-opacity:0.25}.bg-opacity-50{--bs-bg-opacity:0.5}.bg-opacity-75{--bs-bg-opacity:0.75}.bg-opacity-100{--bs-bg-opacity:1}.bg-primary-subtle{background-color:var(--bs-primary-bg-subtle)!important}.bg-secondary-subtle{background-color:var(--bs-secondary-bg-subtle)!important}.bg-success-subtle{background-color:var(--bs-success-bg-subtle)!important}.bg-info-subtle{background-color:var(--bs-info-bg-subtle)!important}.bg-warning-subtle{background-color:var(--bs-warning-bg-subtle)!important}.bg-danger-subtle{background-color:var(--bs-danger-bg-subtle)!important}.bg-light-subtle{background-color:var(--bs-light-bg-subtle)!important}.bg-dark-subtle{background-color:var(--bs-dark-bg-subtle)!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:var(--bs-border-radius)!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:var(--bs-border-radius-sm)!important}.rounded-2{border-radius:var(--bs-border-radius)!important}.rounded-3{border-radius:var(--bs-border-radius-lg)!important}.rounded-4{border-radius:var(--bs-border-radius-xl)!important}.rounded-5{border-radius:var(--bs-border-radius-2xl)!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:var(--bs-border-radius-pill)!important}.rounded-top{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-0{border-top-left-radius:0!important;border-top-right-radius:0!important}.rounded-top-1{border-top-left-radius:var(--bs-border-radius-sm)!important;border-top-right-radius:var(--bs-border-radius-sm)!important}.rounded-top-2{border-top-left-radius:var(--bs-border-radius)!important;border-top-right-radius:var(--bs-border-radius)!important}.rounded-top-3{border-top-left-radius:var(--bs-border-radius-lg)!important;border-top-right-radius:var(--bs-border-radius-lg)!important}.rounded-top-4{border-top-left-radius:var(--bs-border-radius-xl)!important;border-top-right-radius:var(--bs-border-radius-xl)!important}.rounded-top-5{border-top-left-radius:var(--bs-border-radius-2xl)!important;border-top-right-radius:var(--bs-border-radius-2xl)!important}.rounded-top-circle{border-top-left-radius:50%!important;border-top-right-radius:50%!important}.rounded-top-pill{border-top-left-radius:var(--bs-border-radius-pill)!important;border-top-right-radius:var(--bs-border-radius-pill)!important}.rounded-end{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-0{border-top-right-radius:0!important;border-bottom-right-radius:0!important}.rounded-end-1{border-top-right-radius:var(--bs-border-radius-sm)!important;border-bottom-right-radius:var(--bs-border-radius-sm)!important}.rounded-end-2{border-top-right-radius:var(--bs-border-radius)!important;border-bottom-right-radius:var(--bs-border-radius)!important}.rounded-end-3{border-top-right-radius:var(--bs-border-radius-lg)!important;border-bottom-right-radius:var(--bs-border-radius-lg)!important}.rounded-end-4{border-top-right-radius:var(--bs-border-radius-xl)!important;border-bottom-right-radius:var(--bs-border-radius-xl)!important}.rounded-end-5{border-top-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-right-radius:var(--bs-border-radius-2xl)!important}.rounded-end-circle{border-top-right-radius:50%!important;border-bottom-right-radius:50%!important}.rounded-end-pill{border-top-right-radius:var(--bs-border-radius-pill)!important;border-bottom-right-radius:var(--bs-border-radius-pill)!important}.rounded-bottom{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-0{border-bottom-right-radius:0!important;border-bottom-left-radius:0!important}.rounded-bottom-1{border-bottom-right-radius:var(--bs-border-radius-sm)!important;border-bottom-left-radius:var(--bs-border-radius-sm)!important}.rounded-bottom-2{border-bottom-right-radius:var(--bs-border-radius)!important;border-bottom-left-radius:var(--bs-border-radius)!important}.rounded-bottom-3{border-bottom-right-radius:var(--bs-border-radius-lg)!important;border-bottom-left-radius:var(--bs-border-radius-lg)!important}.rounded-bottom-4{border-bottom-right-radius:var(--bs-border-radius-xl)!important;border-bottom-left-radius:var(--bs-border-radius-xl)!important}.rounded-bottom-5{border-bottom-right-radius:var(--bs-border-radius-2xl)!important;border-bottom-left-radius:var(--bs-border-radius-2xl)!important}.rounded-bottom-circle{border-bottom-right-radius:50%!important;border-bottom-left-radius:50%!important}.rounded-bottom-pill{border-bottom-right-radius:var(--bs-border-radius-pill)!important;border-bottom-left-radius:var(--bs-border-radius-pill)!important}.rounded-start{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-0{border-bottom-left-radius:0!important;border-top-left-radius:0!important}.rounded-start-1{border-bottom-left-radius:var(--bs-border-radius-sm)!important;border-top-left-radius:var(--bs-border-radius-sm)!important}.rounded-start-2{border-bottom-left-radius:var(--bs-border-radius)!important;border-top-left-radius:var(--bs-border-radius)!important}.rounded-start-3{border-bottom-left-radius:var(--bs-border-radius-lg)!important;border-top-left-radius:var(--bs-border-radius-lg)!important}.rounded-start-4{border-bottom-left-radius:var(--bs-border-radius-xl)!important;border-top-left-radius:var(--bs-border-radius-xl)!important}.rounded-start-5{border-bottom-left-radius:var(--bs-border-radius-2xl)!important;border-top-left-radius:var(--bs-border-radius-2xl)!important}.rounded-start-circle{border-bottom-left-radius:50%!important;border-top-left-radius:50%!important}.rounded-start-pill{border-bottom-left-radius:var(--bs-border-radius-pill)!important;border-top-left-radius:var(--bs-border-radius-pill)!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.z-n1{z-index:-1!important}.z-0{z-index:0!important}.z-1{z-index:1!important}.z-2{z-index:2!important}.z-3{z-index:3!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.object-fit-sm-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-sm-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-sm-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-sm-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-sm-none{-o-object-fit:none!important;object-fit:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.row-gap-sm-0{row-gap:0!important}.row-gap-sm-1{row-gap:.25rem!important}.row-gap-sm-2{row-gap:.5rem!important}.row-gap-sm-3{row-gap:1rem!important}.row-gap-sm-4{row-gap:1.5rem!important}.row-gap-sm-5{row-gap:3rem!important}.column-gap-sm-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-sm-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-sm-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-sm-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-sm-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-sm-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.object-fit-md-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-md-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-md-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-md-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-md-none{-o-object-fit:none!important;object-fit:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.row-gap-md-0{row-gap:0!important}.row-gap-md-1{row-gap:.25rem!important}.row-gap-md-2{row-gap:.5rem!important}.row-gap-md-3{row-gap:1rem!important}.row-gap-md-4{row-gap:1.5rem!important}.row-gap-md-5{row-gap:3rem!important}.column-gap-md-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-md-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-md-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-md-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-md-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-md-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.object-fit-lg-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-lg-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-lg-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-lg-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-lg-none{-o-object-fit:none!important;object-fit:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.row-gap-lg-0{row-gap:0!important}.row-gap-lg-1{row-gap:.25rem!important}.row-gap-lg-2{row-gap:.5rem!important}.row-gap-lg-3{row-gap:1rem!important}.row-gap-lg-4{row-gap:1.5rem!important}.row-gap-lg-5{row-gap:3rem!important}.column-gap-lg-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-lg-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-lg-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-lg-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-lg-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-lg-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.object-fit-xl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xl-none{-o-object-fit:none!important;object-fit:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.row-gap-xl-0{row-gap:0!important}.row-gap-xl-1{row-gap:.25rem!important}.row-gap-xl-2{row-gap:.5rem!important}.row-gap-xl-3{row-gap:1rem!important}.row-gap-xl-4{row-gap:1.5rem!important}.row-gap-xl-5{row-gap:3rem!important}.column-gap-xl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.object-fit-xxl-contain{-o-object-fit:contain!important;object-fit:contain!important}.object-fit-xxl-cover{-o-object-fit:cover!important;object-fit:cover!important}.object-fit-xxl-fill{-o-object-fit:fill!important;object-fit:fill!important}.object-fit-xxl-scale{-o-object-fit:scale-down!important;object-fit:scale-down!important}.object-fit-xxl-none{-o-object-fit:none!important;object-fit:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.row-gap-xxl-0{row-gap:0!important}.row-gap-xxl-1{row-gap:.25rem!important}.row-gap-xxl-2{row-gap:.5rem!important}.row-gap-xxl-3{row-gap:1rem!important}.row-gap-xxl-4{row-gap:1.5rem!important}.row-gap-xxl-5{row-gap:3rem!important}.column-gap-xxl-0{-moz-column-gap:0!important;column-gap:0!important}.column-gap-xxl-1{-moz-column-gap:0.25rem!important;column-gap:.25rem!important}.column-gap-xxl-2{-moz-column-gap:0.5rem!important;column-gap:.5rem!important}.column-gap-xxl-3{-moz-column-gap:1rem!important;column-gap:1rem!important}.column-gap-xxl-4{-moz-column-gap:1.5rem!important;column-gap:1.5rem!important}.column-gap-xxl-5{-moz-column-gap:3rem!important;column-gap:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css.map b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css.map new file mode 100644 index 0000000..39a8606 --- /dev/null +++ b/user_config/usr/share/newton/context_path/resources/css/libs/bootstrap5/bootstrap.min.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["../../scss/mixins/_banner.scss","../../scss/_root.scss","dist/css/bootstrap.css","../../scss/vendor/_rfs.scss","../../scss/mixins/_color-mode.scss","../../scss/_reboot.scss","../../scss/mixins/_border-radius.scss","../../scss/_type.scss","../../scss/mixins/_lists.scss","../../scss/_images.scss","../../scss/mixins/_image.scss","../../scss/_containers.scss","../../scss/mixins/_container.scss","../../scss/mixins/_breakpoints.scss","../../scss/_grid.scss","../../scss/mixins/_grid.scss","../../scss/_tables.scss","../../scss/mixins/_table-variants.scss","../../scss/forms/_labels.scss","../../scss/forms/_form-text.scss","../../scss/forms/_form-control.scss","../../scss/mixins/_transition.scss","../../scss/mixins/_gradients.scss","../../scss/forms/_form-select.scss","../../scss/forms/_form-check.scss","../../scss/forms/_form-range.scss","../../scss/forms/_floating-labels.scss","../../scss/forms/_input-group.scss","../../scss/mixins/_forms.scss","../../scss/_buttons.scss","../../scss/mixins/_buttons.scss","../../scss/_transitions.scss","../../scss/_dropdown.scss","../../scss/mixins/_caret.scss","../../scss/_button-group.scss","../../scss/_nav.scss","../../scss/_navbar.scss","../../scss/_card.scss","../../scss/_accordion.scss","../../scss/_breadcrumb.scss","../../scss/_pagination.scss","../../scss/mixins/_pagination.scss","../../scss/_badge.scss","../../scss/_alert.scss","../../scss/_progress.scss","../../scss/_list-group.scss","../../scss/_close.scss","../../scss/_toasts.scss","../../scss/_modal.scss","../../scss/mixins/_backdrop.scss","../../scss/_tooltip.scss","../../scss/mixins/_reset-text.scss","../../scss/_popover.scss","../../scss/_carousel.scss","../../scss/mixins/_clearfix.scss","../../scss/_spinners.scss","../../scss/_offcanvas.scss","../../scss/_placeholders.scss","../../scss/helpers/_color-bg.scss","../../scss/helpers/_colored-links.scss","../../scss/helpers/_focus-ring.scss","../../scss/helpers/_icon-link.scss","../../scss/helpers/_ratio.scss","../../scss/helpers/_position.scss","../../scss/helpers/_stacks.scss","../../scss/helpers/_visually-hidden.scss","../../scss/mixins/_visually-hidden.scss","../../scss/helpers/_stretched-link.scss","../../scss/helpers/_text-truncation.scss","../../scss/mixins/_text-truncate.scss","../../scss/helpers/_vr.scss","../../scss/mixins/_utilities.scss","../../scss/utilities/_api.scss"],"names":[],"mappings":"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","sourcesContent":["@mixin bsBanner($file) {\n /*!\n * Bootstrap #{$file} v5.3.0 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n}\n",":root,\n[data-bs-theme=\"light\"] {\n // Note: Custom variable values only support SassScript inside `#{}`.\n\n // Colors\n //\n // Generate palettes for full colors, grays, and theme colors.\n\n @each $color, $value in $colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $grays {\n --#{$prefix}gray-#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors {\n --#{$prefix}#{$color}: #{$value};\n }\n\n @each $color, $value in $theme-colors-rgb {\n --#{$prefix}#{$color}-rgb: #{$value};\n }\n\n @each $color, $value in $theme-colors-text {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n --#{$prefix}white-rgb: #{to-rgb($white)};\n --#{$prefix}black-rgb: #{to-rgb($black)};\n\n // Fonts\n\n // Note: Use `inspect` for lists so that quoted items keep the quotes.\n // See https://github.com/sass/sass/issues/2383#issuecomment-336349172\n --#{$prefix}font-sans-serif: #{inspect($font-family-sans-serif)};\n --#{$prefix}font-monospace: #{inspect($font-family-monospace)};\n --#{$prefix}gradient: #{$gradient};\n\n // Root and body\n // scss-docs-start root-body-variables\n @if $font-size-root != null {\n --#{$prefix}root-font-size: #{$font-size-root};\n }\n --#{$prefix}body-font-family: #{inspect($font-family-base)};\n @include rfs($font-size-base, --#{$prefix}body-font-size);\n --#{$prefix}body-font-weight: #{$font-weight-base};\n --#{$prefix}body-line-height: #{$line-height-base};\n @if $body-text-align != null {\n --#{$prefix}body-text-align: #{$body-text-align};\n }\n\n --#{$prefix}body-color: #{$body-color};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color)};\n --#{$prefix}body-bg: #{$body-bg};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg)};\n // scss-docs-end root-body-variables\n\n --#{$prefix}heading-color: #{$headings-color};\n\n --#{$prefix}link-color: #{$link-color};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color)};\n --#{$prefix}link-decoration: #{$link-decoration};\n\n --#{$prefix}link-hover-color: #{$link-hover-color};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color)};\n\n @if $link-hover-decoration != null {\n --#{$prefix}link-hover-decoration: #{$link-hover-decoration};\n }\n\n --#{$prefix}code-color: #{$code-color};\n --#{$prefix}highlight-bg: #{$mark-bg};\n\n // scss-docs-start root-border-var\n --#{$prefix}border-width: #{$border-width};\n --#{$prefix}border-style: #{$border-style};\n --#{$prefix}border-color: #{$border-color};\n --#{$prefix}border-color-translucent: #{$border-color-translucent};\n\n --#{$prefix}border-radius: #{$border-radius};\n --#{$prefix}border-radius-sm: #{$border-radius-sm};\n --#{$prefix}border-radius-lg: #{$border-radius-lg};\n --#{$prefix}border-radius-xl: #{$border-radius-xl};\n --#{$prefix}border-radius-xxl: #{$border-radius-xxl};\n --#{$prefix}border-radius-2xl: var(--#{$prefix}border-radius-xxl); // Deprecated in v5.3.0 for consistency\n --#{$prefix}border-radius-pill: #{$border-radius-pill};\n // scss-docs-end root-border-var\n\n --#{$prefix}box-shadow: #{$box-shadow};\n --#{$prefix}box-shadow-sm: #{$box-shadow-sm};\n --#{$prefix}box-shadow-lg: #{$box-shadow-lg};\n --#{$prefix}box-shadow-inset: #{$box-shadow-inset};\n\n // Focus styles\n // scss-docs-start root-focus-variables\n --#{$prefix}focus-ring-width: #{$focus-ring-width};\n --#{$prefix}focus-ring-opacity: #{$focus-ring-opacity};\n --#{$prefix}focus-ring-color: #{$focus-ring-color};\n // scss-docs-end root-focus-variables\n\n // scss-docs-start root-form-validation-variables\n --#{$prefix}form-valid-color: #{$form-valid-color};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color};\n --#{$prefix}form-invalid-color: #{$form-invalid-color};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color};\n // scss-docs-end root-form-validation-variables\n}\n\n@if $enable-dark-mode {\n @include color-mode(dark, true) {\n color-scheme: dark;\n\n // scss-docs-start root-dark-mode-vars\n --#{$prefix}body-color: #{$body-color-dark};\n --#{$prefix}body-color-rgb: #{to-rgb($body-color-dark)};\n --#{$prefix}body-bg: #{$body-bg-dark};\n --#{$prefix}body-bg-rgb: #{to-rgb($body-bg-dark)};\n\n --#{$prefix}emphasis-color: #{$body-emphasis-color-dark};\n --#{$prefix}emphasis-color-rgb: #{to-rgb($body-emphasis-color-dark)};\n\n --#{$prefix}secondary-color: #{$body-secondary-color-dark};\n --#{$prefix}secondary-color-rgb: #{to-rgb($body-secondary-color-dark)};\n --#{$prefix}secondary-bg: #{$body-secondary-bg-dark};\n --#{$prefix}secondary-bg-rgb: #{to-rgb($body-secondary-bg-dark)};\n\n --#{$prefix}tertiary-color: #{$body-tertiary-color-dark};\n --#{$prefix}tertiary-color-rgb: #{to-rgb($body-tertiary-color-dark)};\n --#{$prefix}tertiary-bg: #{$body-tertiary-bg-dark};\n --#{$prefix}tertiary-bg-rgb: #{to-rgb($body-tertiary-bg-dark)};\n\n @each $color, $value in $theme-colors-text-dark {\n --#{$prefix}#{$color}-text-emphasis: #{$value};\n }\n\n @each $color, $value in $theme-colors-bg-subtle-dark {\n --#{$prefix}#{$color}-bg-subtle: #{$value};\n }\n\n @each $color, $value in $theme-colors-border-subtle-dark {\n --#{$prefix}#{$color}-border-subtle: #{$value};\n }\n\n --#{$prefix}heading-color: #{$headings-color-dark};\n\n --#{$prefix}link-color: #{$link-color-dark};\n --#{$prefix}link-hover-color: #{$link-hover-color-dark};\n --#{$prefix}link-color-rgb: #{to-rgb($link-color-dark)};\n --#{$prefix}link-hover-color-rgb: #{to-rgb($link-hover-color-dark)};\n\n --#{$prefix}code-color: #{$code-color-dark};\n\n --#{$prefix}border-color: #{$border-color-dark};\n --#{$prefix}border-color-translucent: #{$border-color-translucent-dark};\n\n --#{$prefix}form-valid-color: #{$form-valid-color-dark};\n --#{$prefix}form-valid-border-color: #{$form-valid-border-color-dark};\n --#{$prefix}form-invalid-color: #{$form-invalid-color-dark};\n --#{$prefix}form-invalid-border-color: #{$form-invalid-border-color-dark};\n // scss-docs-end root-dark-mode-vars\n }\n}\n","@charset \"UTF-8\";\n/*!\n * Bootstrap v5.3.0 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n:root,\n[data-bs-theme=light] {\n --bs-blue: #0d6efd;\n --bs-indigo: #6610f2;\n --bs-purple: #6f42c1;\n --bs-pink: #d63384;\n --bs-red: #dc3545;\n --bs-orange: #fd7e14;\n --bs-yellow: #ffc107;\n --bs-green: #198754;\n --bs-teal: #20c997;\n --bs-cyan: #0dcaf0;\n --bs-black: #000;\n --bs-white: #fff;\n --bs-gray: #6c757d;\n --bs-gray-dark: #343a40;\n --bs-gray-100: #f8f9fa;\n --bs-gray-200: #e9ecef;\n --bs-gray-300: #dee2e6;\n --bs-gray-400: #ced4da;\n --bs-gray-500: #adb5bd;\n --bs-gray-600: #6c757d;\n --bs-gray-700: #495057;\n --bs-gray-800: #343a40;\n --bs-gray-900: #212529;\n --bs-primary: #0d6efd;\n --bs-secondary: #6c757d;\n --bs-success: #198754;\n --bs-info: #0dcaf0;\n --bs-warning: #ffc107;\n --bs-danger: #dc3545;\n --bs-light: #f8f9fa;\n --bs-dark: #212529;\n --bs-primary-rgb: 13, 110, 253;\n --bs-secondary-rgb: 108, 117, 125;\n --bs-success-rgb: 25, 135, 84;\n --bs-info-rgb: 13, 202, 240;\n --bs-warning-rgb: 255, 193, 7;\n --bs-danger-rgb: 220, 53, 69;\n --bs-light-rgb: 248, 249, 250;\n --bs-dark-rgb: 33, 37, 41;\n --bs-primary-text-emphasis: #052c65;\n --bs-secondary-text-emphasis: #2b2f32;\n --bs-success-text-emphasis: #0a3622;\n --bs-info-text-emphasis: #055160;\n --bs-warning-text-emphasis: #664d03;\n --bs-danger-text-emphasis: #58151c;\n --bs-light-text-emphasis: #495057;\n --bs-dark-text-emphasis: #495057;\n --bs-primary-bg-subtle: #cfe2ff;\n --bs-secondary-bg-subtle: #e2e3e5;\n --bs-success-bg-subtle: #d1e7dd;\n --bs-info-bg-subtle: #cff4fc;\n --bs-warning-bg-subtle: #fff3cd;\n --bs-danger-bg-subtle: #f8d7da;\n --bs-light-bg-subtle: #fcfcfd;\n --bs-dark-bg-subtle: #ced4da;\n --bs-primary-border-subtle: #9ec5fe;\n --bs-secondary-border-subtle: #c4c8cb;\n --bs-success-border-subtle: #a3cfbb;\n --bs-info-border-subtle: #9eeaf9;\n --bs-warning-border-subtle: #ffe69c;\n --bs-danger-border-subtle: #f1aeb5;\n --bs-light-border-subtle: #e9ecef;\n --bs-dark-border-subtle: #adb5bd;\n --bs-white-rgb: 255, 255, 255;\n --bs-black-rgb: 0, 0, 0;\n --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Noto Sans\", \"Liberation Sans\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));\n --bs-body-font-family: var(--bs-font-sans-serif);\n --bs-body-font-size: 1rem;\n --bs-body-font-weight: 400;\n --bs-body-line-height: 1.5;\n --bs-body-color: #212529;\n --bs-body-color-rgb: 33, 37, 41;\n --bs-body-bg: #fff;\n --bs-body-bg-rgb: 255, 255, 255;\n --bs-emphasis-color: #000;\n --bs-emphasis-color-rgb: 0, 0, 0;\n --bs-secondary-color: rgba(33, 37, 41, 0.75);\n --bs-secondary-color-rgb: 33, 37, 41;\n --bs-secondary-bg: #e9ecef;\n --bs-secondary-bg-rgb: 233, 236, 239;\n --bs-tertiary-color: rgba(33, 37, 41, 0.5);\n --bs-tertiary-color-rgb: 33, 37, 41;\n --bs-tertiary-bg: #f8f9fa;\n --bs-tertiary-bg-rgb: 248, 249, 250;\n --bs-heading-color: inherit;\n --bs-link-color: #0d6efd;\n --bs-link-color-rgb: 13, 110, 253;\n --bs-link-decoration: underline;\n --bs-link-hover-color: #0a58ca;\n --bs-link-hover-color-rgb: 10, 88, 202;\n --bs-code-color: #d63384;\n --bs-highlight-bg: #fff3cd;\n --bs-border-width: 1px;\n --bs-border-style: solid;\n --bs-border-color: #dee2e6;\n --bs-border-color-translucent: rgba(0, 0, 0, 0.175);\n --bs-border-radius: 0.375rem;\n --bs-border-radius-sm: 0.25rem;\n --bs-border-radius-lg: 0.5rem;\n --bs-border-radius-xl: 1rem;\n --bs-border-radius-xxl: 2rem;\n --bs-border-radius-2xl: var(--bs-border-radius-xxl);\n --bs-border-radius-pill: 50rem;\n --bs-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n --bs-box-shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n --bs-box-shadow-lg: 0 1rem 3rem rgba(0, 0, 0, 0.175);\n --bs-box-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.075);\n --bs-focus-ring-width: 0.25rem;\n --bs-focus-ring-opacity: 0.25;\n --bs-focus-ring-color: rgba(13, 110, 253, 0.25);\n --bs-form-valid-color: #198754;\n --bs-form-valid-border-color: #198754;\n --bs-form-invalid-color: #dc3545;\n --bs-form-invalid-border-color: #dc3545;\n}\n\n[data-bs-theme=dark] {\n color-scheme: dark;\n --bs-body-color: #adb5bd;\n --bs-body-color-rgb: 173, 181, 189;\n --bs-body-bg: #212529;\n --bs-body-bg-rgb: 33, 37, 41;\n --bs-emphasis-color: #fff;\n --bs-emphasis-color-rgb: 255, 255, 255;\n --bs-secondary-color: rgba(173, 181, 189, 0.75);\n --bs-secondary-color-rgb: 173, 181, 189;\n --bs-secondary-bg: #343a40;\n --bs-secondary-bg-rgb: 52, 58, 64;\n --bs-tertiary-color: rgba(173, 181, 189, 0.5);\n --bs-tertiary-color-rgb: 173, 181, 189;\n --bs-tertiary-bg: #2b3035;\n --bs-tertiary-bg-rgb: 43, 48, 53;\n --bs-primary-text-emphasis: #6ea8fe;\n --bs-secondary-text-emphasis: #a7acb1;\n --bs-success-text-emphasis: #75b798;\n --bs-info-text-emphasis: #6edff6;\n --bs-warning-text-emphasis: #ffda6a;\n --bs-danger-text-emphasis: #ea868f;\n --bs-light-text-emphasis: #f8f9fa;\n --bs-dark-text-emphasis: #dee2e6;\n --bs-primary-bg-subtle: #031633;\n --bs-secondary-bg-subtle: #161719;\n --bs-success-bg-subtle: #051b11;\n --bs-info-bg-subtle: #032830;\n --bs-warning-bg-subtle: #332701;\n --bs-danger-bg-subtle: #2c0b0e;\n --bs-light-bg-subtle: #343a40;\n --bs-dark-bg-subtle: #1a1d20;\n --bs-primary-border-subtle: #084298;\n --bs-secondary-border-subtle: #41464b;\n --bs-success-border-subtle: #0f5132;\n --bs-info-border-subtle: #087990;\n --bs-warning-border-subtle: #997404;\n --bs-danger-border-subtle: #842029;\n --bs-light-border-subtle: #495057;\n --bs-dark-border-subtle: #343a40;\n --bs-heading-color: inherit;\n --bs-link-color: #6ea8fe;\n --bs-link-hover-color: #8bb9fe;\n --bs-link-color-rgb: 110, 168, 254;\n --bs-link-hover-color-rgb: 139, 185, 254;\n --bs-code-color: #e685b5;\n --bs-border-color: #495057;\n --bs-border-color-translucent: rgba(255, 255, 255, 0.15);\n --bs-form-valid-color: #75b798;\n --bs-form-valid-border-color: #75b798;\n --bs-form-invalid-color: #ea868f;\n --bs-form-invalid-border-color: #ea868f;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n :root {\n scroll-behavior: smooth;\n }\n}\n\nbody {\n margin: 0;\n font-family: var(--bs-body-font-family);\n font-size: var(--bs-body-font-size);\n font-weight: var(--bs-body-font-weight);\n line-height: var(--bs-body-line-height);\n color: var(--bs-body-color);\n text-align: var(--bs-body-text-align);\n background-color: var(--bs-body-bg);\n -webkit-text-size-adjust: 100%;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nhr {\n margin: 1rem 0;\n color: inherit;\n border: 0;\n border-top: var(--bs-border-width) solid;\n opacity: 0.25;\n}\n\nh6, .h6, h5, .h5, h4, .h4, h3, .h3, h2, .h2, h1, .h1 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n font-weight: 500;\n line-height: 1.2;\n color: var(--bs-heading-color);\n}\n\nh1, .h1 {\n font-size: calc(1.375rem + 1.5vw);\n}\n@media (min-width: 1200px) {\n h1, .h1 {\n font-size: 2.5rem;\n }\n}\n\nh2, .h2 {\n font-size: calc(1.325rem + 0.9vw);\n}\n@media (min-width: 1200px) {\n h2, .h2 {\n font-size: 2rem;\n }\n}\n\nh3, .h3 {\n font-size: calc(1.3rem + 0.6vw);\n}\n@media (min-width: 1200px) {\n h3, .h3 {\n font-size: 1.75rem;\n }\n}\n\nh4, .h4 {\n font-size: calc(1.275rem + 0.3vw);\n}\n@media (min-width: 1200px) {\n h4, .h4 {\n font-size: 1.5rem;\n }\n}\n\nh5, .h5 {\n font-size: 1.25rem;\n}\n\nh6, .h6 {\n font-size: 1rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title] {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n -webkit-text-decoration-skip-ink: none;\n text-decoration-skip-ink: none;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: 0.5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall, .small {\n font-size: 0.875em;\n}\n\nmark, .mark {\n padding: 0.1875em;\n background-color: var(--bs-highlight-bg);\n}\n\nsub,\nsup {\n position: relative;\n font-size: 0.75em;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\na {\n color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 1));\n text-decoration: underline;\n}\na:hover {\n --bs-link-color-rgb: var(--bs-link-hover-color-rgb);\n}\n\na:not([href]):not([class]), a:not([href]):not([class]):hover {\n color: inherit;\n text-decoration: none;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: var(--bs-font-monospace);\n font-size: 1em;\n}\n\npre {\n display: block;\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n font-size: 0.875em;\n}\npre code {\n font-size: inherit;\n color: inherit;\n word-break: normal;\n}\n\ncode {\n font-size: 0.875em;\n color: var(--bs-code-color);\n word-wrap: break-word;\n}\na > code {\n color: inherit;\n}\n\nkbd {\n padding: 0.1875rem 0.375rem;\n font-size: 0.875em;\n color: var(--bs-body-bg);\n background-color: var(--bs-body-color);\n border-radius: 0.25rem;\n}\nkbd kbd {\n padding: 0;\n font-size: 1em;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n color: var(--bs-secondary-color);\n text-align: left;\n}\n\nth {\n text-align: inherit;\n text-align: -webkit-match-parent;\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\nlabel {\n display: inline-block;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\n[role=button] {\n cursor: pointer;\n}\n\nselect {\n word-wrap: normal;\n}\nselect:disabled {\n opacity: 1;\n}\n\n[list]:not([type=date]):not([type=datetime-local]):not([type=month]):not([type=week]):not([type=time])::-webkit-calendar-picker-indicator {\n display: none !important;\n}\n\nbutton,\n[type=button],\n[type=reset],\n[type=submit] {\n -webkit-appearance: button;\n}\nbutton:not(:disabled),\n[type=button]:not(:disabled),\n[type=reset]:not(:disabled),\n[type=submit]:not(:disabled) {\n cursor: pointer;\n}\n\n::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ntextarea {\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n float: left;\n width: 100%;\n padding: 0;\n margin-bottom: 0.5rem;\n font-size: calc(1.275rem + 0.3vw);\n line-height: inherit;\n}\n@media (min-width: 1200px) {\n legend {\n font-size: 1.5rem;\n }\n}\nlegend + * {\n clear: left;\n}\n\n::-webkit-datetime-edit-fields-wrapper,\n::-webkit-datetime-edit-text,\n::-webkit-datetime-edit-minute,\n::-webkit-datetime-edit-hour-field,\n::-webkit-datetime-edit-day-field,\n::-webkit-datetime-edit-month-field,\n::-webkit-datetime-edit-year-field {\n padding: 0;\n}\n\n::-webkit-inner-spin-button {\n height: auto;\n}\n\n[type=search] {\n outline-offset: -2px;\n -webkit-appearance: textfield;\n}\n\n/* rtl:raw:\n[type=\"tel\"],\n[type=\"url\"],\n[type=\"email\"],\n[type=\"number\"] {\n direction: ltr;\n}\n*/\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-color-swatch-wrapper {\n padding: 0;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\n::file-selector-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\niframe {\n border: 0;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.lead {\n font-size: 1.25rem;\n font-weight: 300;\n}\n\n.display-1 {\n font-size: calc(1.625rem + 4.5vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-1 {\n font-size: 5rem;\n }\n}\n\n.display-2 {\n font-size: calc(1.575rem + 3.9vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-2 {\n font-size: 4.5rem;\n }\n}\n\n.display-3 {\n font-size: calc(1.525rem + 3.3vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-3 {\n font-size: 4rem;\n }\n}\n\n.display-4 {\n font-size: calc(1.475rem + 2.7vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-4 {\n font-size: 3.5rem;\n }\n}\n\n.display-5 {\n font-size: calc(1.425rem + 2.1vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-5 {\n font-size: 3rem;\n }\n}\n\n.display-6 {\n font-size: calc(1.375rem + 1.5vw);\n font-weight: 300;\n line-height: 1.2;\n}\n@media (min-width: 1200px) {\n .display-6 {\n font-size: 2.5rem;\n }\n}\n\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline {\n padding-left: 0;\n list-style: none;\n}\n\n.list-inline-item {\n display: inline-block;\n}\n.list-inline-item:not(:last-child) {\n margin-right: 0.5rem;\n}\n\n.initialism {\n font-size: 0.875em;\n text-transform: uppercase;\n}\n\n.blockquote {\n margin-bottom: 1rem;\n font-size: 1.25rem;\n}\n.blockquote > :last-child {\n margin-bottom: 0;\n}\n\n.blockquote-footer {\n margin-top: -1rem;\n margin-bottom: 1rem;\n font-size: 0.875em;\n color: #6c757d;\n}\n.blockquote-footer::before {\n content: \"— \";\n}\n\n.img-fluid {\n max-width: 100%;\n height: auto;\n}\n\n.img-thumbnail {\n padding: 0.25rem;\n background-color: var(--bs-body-bg);\n border: var(--bs-border-width) solid var(--bs-border-color);\n border-radius: var(--bs-border-radius);\n max-width: 100%;\n height: auto;\n}\n\n.figure {\n display: inline-block;\n}\n\n.figure-img {\n margin-bottom: 0.5rem;\n line-height: 1;\n}\n\n.figure-caption {\n font-size: 0.875em;\n color: var(--bs-secondary-color);\n}\n\n.container,\n.container-fluid,\n.container-xxl,\n.container-xl,\n.container-lg,\n.container-md,\n.container-sm {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-right: auto;\n margin-left: auto;\n}\n\n@media (min-width: 576px) {\n .container-sm, .container {\n max-width: 540px;\n }\n}\n@media (min-width: 768px) {\n .container-md, .container-sm, .container {\n max-width: 720px;\n }\n}\n@media (min-width: 992px) {\n .container-lg, .container-md, .container-sm, .container {\n max-width: 960px;\n }\n}\n@media (min-width: 1200px) {\n .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1140px;\n }\n}\n@media (min-width: 1400px) {\n .container-xxl, .container-xl, .container-lg, .container-md, .container-sm, .container {\n max-width: 1320px;\n }\n}\n:root {\n --bs-breakpoint-xs: 0;\n --bs-breakpoint-sm: 576px;\n --bs-breakpoint-md: 768px;\n --bs-breakpoint-lg: 992px;\n --bs-breakpoint-xl: 1200px;\n --bs-breakpoint-xxl: 1400px;\n}\n\n.row {\n --bs-gutter-x: 1.5rem;\n --bs-gutter-y: 0;\n display: flex;\n flex-wrap: wrap;\n margin-top: calc(-1 * var(--bs-gutter-y));\n margin-right: calc(-0.5 * var(--bs-gutter-x));\n margin-left: calc(-0.5 * var(--bs-gutter-x));\n}\n.row > * {\n flex-shrink: 0;\n width: 100%;\n max-width: 100%;\n padding-right: calc(var(--bs-gutter-x) * 0.5);\n padding-left: calc(var(--bs-gutter-x) * 0.5);\n margin-top: var(--bs-gutter-y);\n}\n\n.col {\n flex: 1 0 0%;\n}\n\n.row-cols-auto > * {\n flex: 0 0 auto;\n width: auto;\n}\n\n.row-cols-1 > * {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.row-cols-2 > * {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.row-cols-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n}\n\n.row-cols-4 > * {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.row-cols-5 > * {\n flex: 0 0 auto;\n width: 20%;\n}\n\n.row-cols-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n}\n\n.col-auto {\n flex: 0 0 auto;\n width: auto;\n}\n\n.col-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n}\n\n.col-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n}\n\n.col-3 {\n flex: 0 0 auto;\n width: 25%;\n}\n\n.col-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n}\n\n.col-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n}\n\n.col-6 {\n flex: 0 0 auto;\n width: 50%;\n}\n\n.col-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n}\n\n.col-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n}\n\n.col-9 {\n flex: 0 0 auto;\n width: 75%;\n}\n\n.col-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n}\n\n.col-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n}\n\n.col-12 {\n flex: 0 0 auto;\n width: 100%;\n}\n\n.offset-1 {\n margin-left: 8.33333333%;\n}\n\n.offset-2 {\n margin-left: 16.66666667%;\n}\n\n.offset-3 {\n margin-left: 25%;\n}\n\n.offset-4 {\n margin-left: 33.33333333%;\n}\n\n.offset-5 {\n margin-left: 41.66666667%;\n}\n\n.offset-6 {\n margin-left: 50%;\n}\n\n.offset-7 {\n margin-left: 58.33333333%;\n}\n\n.offset-8 {\n margin-left: 66.66666667%;\n}\n\n.offset-9 {\n margin-left: 75%;\n}\n\n.offset-10 {\n margin-left: 83.33333333%;\n}\n\n.offset-11 {\n margin-left: 91.66666667%;\n}\n\n.g-0,\n.gx-0 {\n --bs-gutter-x: 0;\n}\n\n.g-0,\n.gy-0 {\n --bs-gutter-y: 0;\n}\n\n.g-1,\n.gx-1 {\n --bs-gutter-x: 0.25rem;\n}\n\n.g-1,\n.gy-1 {\n --bs-gutter-y: 0.25rem;\n}\n\n.g-2,\n.gx-2 {\n --bs-gutter-x: 0.5rem;\n}\n\n.g-2,\n.gy-2 {\n --bs-gutter-y: 0.5rem;\n}\n\n.g-3,\n.gx-3 {\n --bs-gutter-x: 1rem;\n}\n\n.g-3,\n.gy-3 {\n --bs-gutter-y: 1rem;\n}\n\n.g-4,\n.gx-4 {\n --bs-gutter-x: 1.5rem;\n}\n\n.g-4,\n.gy-4 {\n --bs-gutter-y: 1.5rem;\n}\n\n.g-5,\n.gx-5 {\n --bs-gutter-x: 3rem;\n}\n\n.g-5,\n.gy-5 {\n --bs-gutter-y: 3rem;\n}\n\n@media (min-width: 576px) {\n .col-sm {\n flex: 1 0 0%;\n }\n .row-cols-sm-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-sm-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-sm-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-sm-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n }\n .row-cols-sm-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-sm-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-sm-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n }\n .col-sm-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-sm-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-sm-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-sm-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-sm-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-sm-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-sm-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-sm-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-sm-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-sm-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-sm-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-sm-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-sm-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-sm-0 {\n margin-left: 0;\n }\n .offset-sm-1 {\n margin-left: 8.33333333%;\n }\n .offset-sm-2 {\n margin-left: 16.66666667%;\n }\n .offset-sm-3 {\n margin-left: 25%;\n }\n .offset-sm-4 {\n margin-left: 33.33333333%;\n }\n .offset-sm-5 {\n margin-left: 41.66666667%;\n }\n .offset-sm-6 {\n margin-left: 50%;\n }\n .offset-sm-7 {\n margin-left: 58.33333333%;\n }\n .offset-sm-8 {\n margin-left: 66.66666667%;\n }\n .offset-sm-9 {\n margin-left: 75%;\n }\n .offset-sm-10 {\n margin-left: 83.33333333%;\n }\n .offset-sm-11 {\n margin-left: 91.66666667%;\n }\n .g-sm-0,\n .gx-sm-0 {\n --bs-gutter-x: 0;\n }\n .g-sm-0,\n .gy-sm-0 {\n --bs-gutter-y: 0;\n }\n .g-sm-1,\n .gx-sm-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-sm-1,\n .gy-sm-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-sm-2,\n .gx-sm-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-sm-2,\n .gy-sm-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-sm-3,\n .gx-sm-3 {\n --bs-gutter-x: 1rem;\n }\n .g-sm-3,\n .gy-sm-3 {\n --bs-gutter-y: 1rem;\n }\n .g-sm-4,\n .gx-sm-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-sm-4,\n .gy-sm-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-sm-5,\n .gx-sm-5 {\n --bs-gutter-x: 3rem;\n }\n .g-sm-5,\n .gy-sm-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 768px) {\n .col-md {\n flex: 1 0 0%;\n }\n .row-cols-md-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-md-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-md-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-md-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n }\n .row-cols-md-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-md-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-md-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n }\n .col-md-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-md-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-md-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-md-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-md-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-md-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-md-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-md-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-md-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-md-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-md-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-md-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-md-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-md-0 {\n margin-left: 0;\n }\n .offset-md-1 {\n margin-left: 8.33333333%;\n }\n .offset-md-2 {\n margin-left: 16.66666667%;\n }\n .offset-md-3 {\n margin-left: 25%;\n }\n .offset-md-4 {\n margin-left: 33.33333333%;\n }\n .offset-md-5 {\n margin-left: 41.66666667%;\n }\n .offset-md-6 {\n margin-left: 50%;\n }\n .offset-md-7 {\n margin-left: 58.33333333%;\n }\n .offset-md-8 {\n margin-left: 66.66666667%;\n }\n .offset-md-9 {\n margin-left: 75%;\n }\n .offset-md-10 {\n margin-left: 83.33333333%;\n }\n .offset-md-11 {\n margin-left: 91.66666667%;\n }\n .g-md-0,\n .gx-md-0 {\n --bs-gutter-x: 0;\n }\n .g-md-0,\n .gy-md-0 {\n --bs-gutter-y: 0;\n }\n .g-md-1,\n .gx-md-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-md-1,\n .gy-md-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-md-2,\n .gx-md-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-md-2,\n .gy-md-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-md-3,\n .gx-md-3 {\n --bs-gutter-x: 1rem;\n }\n .g-md-3,\n .gy-md-3 {\n --bs-gutter-y: 1rem;\n }\n .g-md-4,\n .gx-md-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-md-4,\n .gy-md-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-md-5,\n .gx-md-5 {\n --bs-gutter-x: 3rem;\n }\n .g-md-5,\n .gy-md-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 992px) {\n .col-lg {\n flex: 1 0 0%;\n }\n .row-cols-lg-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-lg-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-lg-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-lg-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n }\n .row-cols-lg-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-lg-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-lg-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n }\n .col-lg-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-lg-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-lg-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-lg-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-lg-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-lg-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-lg-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-lg-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-lg-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-lg-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-lg-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-lg-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-lg-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-lg-0 {\n margin-left: 0;\n }\n .offset-lg-1 {\n margin-left: 8.33333333%;\n }\n .offset-lg-2 {\n margin-left: 16.66666667%;\n }\n .offset-lg-3 {\n margin-left: 25%;\n }\n .offset-lg-4 {\n margin-left: 33.33333333%;\n }\n .offset-lg-5 {\n margin-left: 41.66666667%;\n }\n .offset-lg-6 {\n margin-left: 50%;\n }\n .offset-lg-7 {\n margin-left: 58.33333333%;\n }\n .offset-lg-8 {\n margin-left: 66.66666667%;\n }\n .offset-lg-9 {\n margin-left: 75%;\n }\n .offset-lg-10 {\n margin-left: 83.33333333%;\n }\n .offset-lg-11 {\n margin-left: 91.66666667%;\n }\n .g-lg-0,\n .gx-lg-0 {\n --bs-gutter-x: 0;\n }\n .g-lg-0,\n .gy-lg-0 {\n --bs-gutter-y: 0;\n }\n .g-lg-1,\n .gx-lg-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-lg-1,\n .gy-lg-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-lg-2,\n .gx-lg-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-lg-2,\n .gy-lg-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-lg-3,\n .gx-lg-3 {\n --bs-gutter-x: 1rem;\n }\n .g-lg-3,\n .gy-lg-3 {\n --bs-gutter-y: 1rem;\n }\n .g-lg-4,\n .gx-lg-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-lg-4,\n .gy-lg-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-lg-5,\n .gx-lg-5 {\n --bs-gutter-x: 3rem;\n }\n .g-lg-5,\n .gy-lg-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1200px) {\n .col-xl {\n flex: 1 0 0%;\n }\n .row-cols-xl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xl-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n }\n .row-cols-xl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xl-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n }\n .col-xl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xl-0 {\n margin-left: 0;\n }\n .offset-xl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xl-3 {\n margin-left: 25%;\n }\n .offset-xl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xl-6 {\n margin-left: 50%;\n }\n .offset-xl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xl-9 {\n margin-left: 75%;\n }\n .offset-xl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xl-11 {\n margin-left: 91.66666667%;\n }\n .g-xl-0,\n .gx-xl-0 {\n --bs-gutter-x: 0;\n }\n .g-xl-0,\n .gy-xl-0 {\n --bs-gutter-y: 0;\n }\n .g-xl-1,\n .gx-xl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xl-1,\n .gy-xl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xl-2,\n .gx-xl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xl-2,\n .gy-xl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xl-3,\n .gx-xl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xl-3,\n .gy-xl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xl-4,\n .gx-xl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xl-4,\n .gy-xl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xl-5,\n .gx-xl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xl-5,\n .gy-xl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n@media (min-width: 1400px) {\n .col-xxl {\n flex: 1 0 0%;\n }\n .row-cols-xxl-auto > * {\n flex: 0 0 auto;\n width: auto;\n }\n .row-cols-xxl-1 > * {\n flex: 0 0 auto;\n width: 100%;\n }\n .row-cols-xxl-2 > * {\n flex: 0 0 auto;\n width: 50%;\n }\n .row-cols-xxl-3 > * {\n flex: 0 0 auto;\n width: 33.3333333333%;\n }\n .row-cols-xxl-4 > * {\n flex: 0 0 auto;\n width: 25%;\n }\n .row-cols-xxl-5 > * {\n flex: 0 0 auto;\n width: 20%;\n }\n .row-cols-xxl-6 > * {\n flex: 0 0 auto;\n width: 16.6666666667%;\n }\n .col-xxl-auto {\n flex: 0 0 auto;\n width: auto;\n }\n .col-xxl-1 {\n flex: 0 0 auto;\n width: 8.33333333%;\n }\n .col-xxl-2 {\n flex: 0 0 auto;\n width: 16.66666667%;\n }\n .col-xxl-3 {\n flex: 0 0 auto;\n width: 25%;\n }\n .col-xxl-4 {\n flex: 0 0 auto;\n width: 33.33333333%;\n }\n .col-xxl-5 {\n flex: 0 0 auto;\n width: 41.66666667%;\n }\n .col-xxl-6 {\n flex: 0 0 auto;\n width: 50%;\n }\n .col-xxl-7 {\n flex: 0 0 auto;\n width: 58.33333333%;\n }\n .col-xxl-8 {\n flex: 0 0 auto;\n width: 66.66666667%;\n }\n .col-xxl-9 {\n flex: 0 0 auto;\n width: 75%;\n }\n .col-xxl-10 {\n flex: 0 0 auto;\n width: 83.33333333%;\n }\n .col-xxl-11 {\n flex: 0 0 auto;\n width: 91.66666667%;\n }\n .col-xxl-12 {\n flex: 0 0 auto;\n width: 100%;\n }\n .offset-xxl-0 {\n margin-left: 0;\n }\n .offset-xxl-1 {\n margin-left: 8.33333333%;\n }\n .offset-xxl-2 {\n margin-left: 16.66666667%;\n }\n .offset-xxl-3 {\n margin-left: 25%;\n }\n .offset-xxl-4 {\n margin-left: 33.33333333%;\n }\n .offset-xxl-5 {\n margin-left: 41.66666667%;\n }\n .offset-xxl-6 {\n margin-left: 50%;\n }\n .offset-xxl-7 {\n margin-left: 58.33333333%;\n }\n .offset-xxl-8 {\n margin-left: 66.66666667%;\n }\n .offset-xxl-9 {\n margin-left: 75%;\n }\n .offset-xxl-10 {\n margin-left: 83.33333333%;\n }\n .offset-xxl-11 {\n margin-left: 91.66666667%;\n }\n .g-xxl-0,\n .gx-xxl-0 {\n --bs-gutter-x: 0;\n }\n .g-xxl-0,\n .gy-xxl-0 {\n --bs-gutter-y: 0;\n }\n .g-xxl-1,\n .gx-xxl-1 {\n --bs-gutter-x: 0.25rem;\n }\n .g-xxl-1,\n .gy-xxl-1 {\n --bs-gutter-y: 0.25rem;\n }\n .g-xxl-2,\n .gx-xxl-2 {\n --bs-gutter-x: 0.5rem;\n }\n .g-xxl-2,\n .gy-xxl-2 {\n --bs-gutter-y: 0.5rem;\n }\n .g-xxl-3,\n .gx-xxl-3 {\n --bs-gutter-x: 1rem;\n }\n .g-xxl-3,\n .gy-xxl-3 {\n --bs-gutter-y: 1rem;\n }\n .g-xxl-4,\n .gx-xxl-4 {\n --bs-gutter-x: 1.5rem;\n }\n .g-xxl-4,\n .gy-xxl-4 {\n --bs-gutter-y: 1.5rem;\n }\n .g-xxl-5,\n .gx-xxl-5 {\n --bs-gutter-x: 3rem;\n }\n .g-xxl-5,\n .gy-xxl-5 {\n --bs-gutter-y: 3rem;\n }\n}\n.table {\n --bs-table-color-type: initial;\n --bs-table-bg-type: initial;\n --bs-table-color-state: initial;\n --bs-table-bg-state: initial;\n --bs-table-color: var(--bs-body-color);\n --bs-table-bg: var(--bs-body-bg);\n --bs-table-border-color: var(--bs-border-color);\n --bs-table-accent-bg: transparent;\n --bs-table-striped-color: var(--bs-body-color);\n --bs-table-striped-bg: rgba(0, 0, 0, 0.05);\n --bs-table-active-color: var(--bs-body-color);\n --bs-table-active-bg: rgba(0, 0, 0, 0.1);\n --bs-table-hover-color: var(--bs-body-color);\n --bs-table-hover-bg: rgba(0, 0, 0, 0.075);\n width: 100%;\n margin-bottom: 1rem;\n vertical-align: top;\n border-color: var(--bs-table-border-color);\n}\n.table > :not(caption) > * > * {\n padding: 0.5rem 0.5rem;\n color: var(--bs-table-color-state, var(--bs-table-color-type, var(--bs-table-color)));\n background-color: var(--bs-table-bg);\n border-bottom-width: var(--bs-border-width);\n box-shadow: inset 0 0 0 9999px var(--bs-table-bg-state, var(--bs-table-bg-type, var(--bs-table-accent-bg)));\n}\n.table > tbody {\n vertical-align: inherit;\n}\n.table > thead {\n vertical-align: bottom;\n}\n\n.table-group-divider {\n border-top: calc(var(--bs-border-width) * 2) solid currentcolor;\n}\n\n.caption-top {\n caption-side: top;\n}\n\n.table-sm > :not(caption) > * > * {\n padding: 0.25rem 0.25rem;\n}\n\n.table-bordered > :not(caption) > * {\n border-width: var(--bs-border-width) 0;\n}\n.table-bordered > :not(caption) > * > * {\n border-width: 0 var(--bs-border-width);\n}\n\n.table-borderless > :not(caption) > * > * {\n border-bottom-width: 0;\n}\n.table-borderless > :not(:first-child) {\n border-top-width: 0;\n}\n\n.table-striped > tbody > tr:nth-of-type(odd) > * {\n --bs-table-color-type: var(--bs-table-striped-color);\n --bs-table-bg-type: var(--bs-table-striped-bg);\n}\n\n.table-striped-columns > :not(caption) > tr > :nth-child(even) {\n --bs-table-color-type: var(--bs-table-striped-color);\n --bs-table-bg-type: var(--bs-table-striped-bg);\n}\n\n.table-active {\n --bs-table-color-state: var(--bs-table-active-color);\n --bs-table-bg-state: var(--bs-table-active-bg);\n}\n\n.table-hover > tbody > tr:hover > * {\n --bs-table-color-state: var(--bs-table-hover-color);\n --bs-table-bg-state: var(--bs-table-hover-bg);\n}\n\n.table-primary {\n --bs-table-color: #000;\n --bs-table-bg: #cfe2ff;\n --bs-table-border-color: #bacbe6;\n --bs-table-striped-bg: #c5d7f2;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #bacbe6;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #bfd1ec;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-secondary {\n --bs-table-color: #000;\n --bs-table-bg: #e2e3e5;\n --bs-table-border-color: #cbccce;\n --bs-table-striped-bg: #d7d8da;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #cbccce;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #d1d2d4;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-success {\n --bs-table-color: #000;\n --bs-table-bg: #d1e7dd;\n --bs-table-border-color: #bcd0c7;\n --bs-table-striped-bg: #c7dbd2;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #bcd0c7;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #c1d6cc;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-info {\n --bs-table-color: #000;\n --bs-table-bg: #cff4fc;\n --bs-table-border-color: #badce3;\n --bs-table-striped-bg: #c5e8ef;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #badce3;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #bfe2e9;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-warning {\n --bs-table-color: #000;\n --bs-table-bg: #fff3cd;\n --bs-table-border-color: #e6dbb9;\n --bs-table-striped-bg: #f2e7c3;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #e6dbb9;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #ece1be;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-danger {\n --bs-table-color: #000;\n --bs-table-bg: #f8d7da;\n --bs-table-border-color: #dfc2c4;\n --bs-table-striped-bg: #eccccf;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #dfc2c4;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #e5c7ca;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-light {\n --bs-table-color: #000;\n --bs-table-bg: #f8f9fa;\n --bs-table-border-color: #dfe0e1;\n --bs-table-striped-bg: #ecedee;\n --bs-table-striped-color: #000;\n --bs-table-active-bg: #dfe0e1;\n --bs-table-active-color: #000;\n --bs-table-hover-bg: #e5e6e7;\n --bs-table-hover-color: #000;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-dark {\n --bs-table-color: #fff;\n --bs-table-bg: #212529;\n --bs-table-border-color: #373b3e;\n --bs-table-striped-bg: #2c3034;\n --bs-table-striped-color: #fff;\n --bs-table-active-bg: #373b3e;\n --bs-table-active-color: #fff;\n --bs-table-hover-bg: #323539;\n --bs-table-hover-color: #fff;\n color: var(--bs-table-color);\n border-color: var(--bs-table-border-color);\n}\n\n.table-responsive {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n}\n\n@media (max-width: 575.98px) {\n .table-responsive-sm {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n}\n@media (max-width: 767.98px) {\n .table-responsive-md {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n}\n@media (max-width: 991.98px) {\n .table-responsive-lg {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n}\n@media (max-width: 1199.98px) {\n .table-responsive-xl {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n}\n@media (max-width: 1399.98px) {\n .table-responsive-xxl {\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n }\n}\n.form-label {\n margin-bottom: 0.5rem;\n}\n\n.col-form-label {\n padding-top: calc(0.375rem + var(--bs-border-width));\n padding-bottom: calc(0.375rem + var(--bs-border-width));\n margin-bottom: 0;\n font-size: inherit;\n line-height: 1.5;\n}\n\n.col-form-label-lg {\n padding-top: calc(0.5rem + var(--bs-border-width));\n padding-bottom: calc(0.5rem + var(--bs-border-width));\n font-size: 1.25rem;\n}\n\n.col-form-label-sm {\n padding-top: calc(0.25rem + var(--bs-border-width));\n padding-bottom: calc(0.25rem + var(--bs-border-width));\n font-size: 0.875rem;\n}\n\n.form-text {\n margin-top: 0.25rem;\n font-size: 0.875em;\n color: var(--bs-secondary-color);\n}\n\n.form-control {\n display: block;\n width: 100%;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: var(--bs-body-color);\n background-color: var(--bs-body-bg);\n background-clip: padding-box;\n border: var(--bs-border-width) solid var(--bs-border-color);\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n border-radius: var(--bs-border-radius);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-control {\n transition: none;\n }\n}\n.form-control[type=file] {\n overflow: hidden;\n}\n.form-control[type=file]:not(:disabled):not([readonly]) {\n cursor: pointer;\n}\n.form-control:focus {\n color: var(--bs-body-color);\n background-color: var(--bs-body-bg);\n border-color: #86b7fe;\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-control::-webkit-date-and-time-value {\n min-width: 85px;\n height: 1.5em;\n margin: 0;\n}\n.form-control::-webkit-datetime-edit {\n display: block;\n padding: 0;\n}\n.form-control::-moz-placeholder {\n color: var(--bs-secondary-color);\n opacity: 1;\n}\n.form-control::placeholder {\n color: var(--bs-secondary-color);\n opacity: 1;\n}\n.form-control:disabled {\n background-color: var(--bs-secondary-bg);\n opacity: 1;\n}\n.form-control::-webkit-file-upload-button {\n padding: 0.375rem 0.75rem;\n margin: -0.375rem -0.75rem;\n -webkit-margin-end: 0.75rem;\n margin-inline-end: 0.75rem;\n color: var(--bs-body-color);\n background-color: var(--bs-tertiary-bg);\n pointer-events: none;\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n border-inline-end-width: var(--bs-border-width);\n border-radius: 0;\n -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n.form-control::file-selector-button {\n padding: 0.375rem 0.75rem;\n margin: -0.375rem -0.75rem;\n -webkit-margin-end: 0.75rem;\n margin-inline-end: 0.75rem;\n color: var(--bs-body-color);\n background-color: var(--bs-tertiary-bg);\n pointer-events: none;\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n border-inline-end-width: var(--bs-border-width);\n border-radius: 0;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-control::-webkit-file-upload-button {\n -webkit-transition: none;\n transition: none;\n }\n .form-control::file-selector-button {\n transition: none;\n }\n}\n.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {\n background-color: var(--bs-secondary-bg);\n}\n.form-control:hover:not(:disabled):not([readonly])::file-selector-button {\n background-color: var(--bs-secondary-bg);\n}\n\n.form-control-plaintext {\n display: block;\n width: 100%;\n padding: 0.375rem 0;\n margin-bottom: 0;\n line-height: 1.5;\n color: var(--bs-body-color);\n background-color: transparent;\n border: solid transparent;\n border-width: var(--bs-border-width) 0;\n}\n.form-control-plaintext:focus {\n outline: 0;\n}\n.form-control-plaintext.form-control-sm, .form-control-plaintext.form-control-lg {\n padding-right: 0;\n padding-left: 0;\n}\n\n.form-control-sm {\n min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n border-radius: var(--bs-border-radius-sm);\n}\n.form-control-sm::-webkit-file-upload-button {\n padding: 0.25rem 0.5rem;\n margin: -0.25rem -0.5rem;\n -webkit-margin-end: 0.5rem;\n margin-inline-end: 0.5rem;\n}\n.form-control-sm::file-selector-button {\n padding: 0.25rem 0.5rem;\n margin: -0.25rem -0.5rem;\n -webkit-margin-end: 0.5rem;\n margin-inline-end: 0.5rem;\n}\n\n.form-control-lg {\n min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n border-radius: var(--bs-border-radius-lg);\n}\n.form-control-lg::-webkit-file-upload-button {\n padding: 0.5rem 1rem;\n margin: -0.5rem -1rem;\n -webkit-margin-end: 1rem;\n margin-inline-end: 1rem;\n}\n.form-control-lg::file-selector-button {\n padding: 0.5rem 1rem;\n margin: -0.5rem -1rem;\n -webkit-margin-end: 1rem;\n margin-inline-end: 1rem;\n}\n\ntextarea.form-control {\n min-height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));\n}\ntextarea.form-control-sm {\n min-height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));\n}\ntextarea.form-control-lg {\n min-height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));\n}\n\n.form-control-color {\n width: 3rem;\n height: calc(1.5em + 0.75rem + calc(var(--bs-border-width) * 2));\n padding: 0.375rem;\n}\n.form-control-color:not(:disabled):not([readonly]) {\n cursor: pointer;\n}\n.form-control-color::-moz-color-swatch {\n border: 0 !important;\n border-radius: var(--bs-border-radius);\n}\n.form-control-color::-webkit-color-swatch {\n border: 0 !important;\n border-radius: var(--bs-border-radius);\n}\n.form-control-color.form-control-sm {\n height: calc(1.5em + 0.5rem + calc(var(--bs-border-width) * 2));\n}\n.form-control-color.form-control-lg {\n height: calc(1.5em + 1rem + calc(var(--bs-border-width) * 2));\n}\n\n.form-select {\n --bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");\n display: block;\n width: 100%;\n padding: 0.375rem 2.25rem 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: var(--bs-body-color);\n background-color: var(--bs-body-bg);\n background-image: var(--bs-form-select-bg-img), var(--bs-form-select-bg-icon, none);\n background-repeat: no-repeat;\n background-position: right 0.75rem center;\n background-size: 16px 12px;\n border: var(--bs-border-width) solid var(--bs-border-color);\n border-radius: var(--bs-border-radius);\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-select {\n transition: none;\n }\n}\n.form-select:focus {\n border-color: #86b7fe;\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-select[multiple], .form-select[size]:not([size=\"1\"]) {\n padding-right: 0.75rem;\n background-image: none;\n}\n.form-select:disabled {\n background-color: var(--bs-secondary-bg);\n}\n.form-select:-moz-focusring {\n color: transparent;\n text-shadow: 0 0 0 var(--bs-body-color);\n}\n\n.form-select-sm {\n padding-top: 0.25rem;\n padding-bottom: 0.25rem;\n padding-left: 0.5rem;\n font-size: 0.875rem;\n border-radius: var(--bs-border-radius-sm);\n}\n\n.form-select-lg {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n padding-left: 1rem;\n font-size: 1.25rem;\n border-radius: var(--bs-border-radius-lg);\n}\n\n[data-bs-theme=dark] .form-select {\n --bs-form-select-bg-img: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23adb5bd' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e\");\n}\n\n.form-check {\n display: block;\n min-height: 1.5rem;\n padding-left: 1.5em;\n margin-bottom: 0.125rem;\n}\n.form-check .form-check-input {\n float: left;\n margin-left: -1.5em;\n}\n\n.form-check-reverse {\n padding-right: 1.5em;\n padding-left: 0;\n text-align: right;\n}\n.form-check-reverse .form-check-input {\n float: right;\n margin-right: -1.5em;\n margin-left: 0;\n}\n\n.form-check-input {\n --bs-form-check-bg: var(--bs-body-bg);\n width: 1em;\n height: 1em;\n margin-top: 0.25em;\n vertical-align: top;\n background-color: var(--bs-form-check-bg);\n background-image: var(--bs-form-check-bg-image);\n background-repeat: no-repeat;\n background-position: center;\n background-size: contain;\n border: var(--bs-border-width) solid var(--bs-border-color);\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n -webkit-print-color-adjust: exact;\n color-adjust: exact;\n print-color-adjust: exact;\n}\n.form-check-input[type=checkbox] {\n border-radius: 0.25em;\n}\n.form-check-input[type=radio] {\n border-radius: 50%;\n}\n.form-check-input:active {\n filter: brightness(90%);\n}\n.form-check-input:focus {\n border-color: #86b7fe;\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-check-input:checked {\n background-color: #0d6efd;\n border-color: #0d6efd;\n}\n.form-check-input:checked[type=checkbox] {\n --bs-form-check-bg-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='m6 10 3 3 6-6'/%3e%3c/svg%3e\");\n}\n.form-check-input:checked[type=radio] {\n --bs-form-check-bg-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-check-input[type=checkbox]:indeterminate {\n background-color: #0d6efd;\n border-color: #0d6efd;\n --bs-form-check-bg-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e\");\n}\n.form-check-input:disabled {\n pointer-events: none;\n filter: none;\n opacity: 0.5;\n}\n.form-check-input[disabled] ~ .form-check-label, .form-check-input:disabled ~ .form-check-label {\n cursor: default;\n opacity: 0.5;\n}\n\n.form-switch {\n padding-left: 2.5em;\n}\n.form-switch .form-check-input {\n --bs-form-switch-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e\");\n width: 2em;\n margin-left: -2.5em;\n background-image: var(--bs-form-switch-bg);\n background-position: left center;\n border-radius: 2em;\n transition: background-position 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-switch .form-check-input {\n transition: none;\n }\n}\n.form-switch .form-check-input:focus {\n --bs-form-switch-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e\");\n}\n.form-switch .form-check-input:checked {\n background-position: right center;\n --bs-form-switch-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e\");\n}\n.form-switch.form-check-reverse {\n padding-right: 2.5em;\n padding-left: 0;\n}\n.form-switch.form-check-reverse .form-check-input {\n margin-right: -2.5em;\n margin-left: 0;\n}\n\n.form-check-inline {\n display: inline-block;\n margin-right: 1rem;\n}\n\n.btn-check {\n position: absolute;\n clip: rect(0, 0, 0, 0);\n pointer-events: none;\n}\n.btn-check[disabled] + .btn, .btn-check:disabled + .btn {\n pointer-events: none;\n filter: none;\n opacity: 0.65;\n}\n\n[data-bs-theme=dark] .form-switch .form-check-input:not(:checked):not(:focus) {\n --bs-form-switch-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%28255, 255, 255, 0.25%29'/%3e%3c/svg%3e\");\n}\n\n.form-range {\n width: 100%;\n height: 1.5rem;\n padding: 0;\n background-color: transparent;\n -webkit-appearance: none;\n -moz-appearance: none;\n appearance: none;\n}\n.form-range:focus {\n outline: 0;\n}\n.form-range:focus::-webkit-slider-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range:focus::-moz-range-thumb {\n box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.form-range::-moz-focus-outer {\n border: 0;\n}\n.form-range::-webkit-slider-thumb {\n width: 1rem;\n height: 1rem;\n margin-top: -0.25rem;\n background-color: #0d6efd;\n border: 0;\n border-radius: 1rem;\n -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -webkit-appearance: none;\n appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-range::-webkit-slider-thumb {\n -webkit-transition: none;\n transition: none;\n }\n}\n.form-range::-webkit-slider-thumb:active {\n background-color: #b6d4fe;\n}\n.form-range::-webkit-slider-runnable-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: var(--bs-tertiary-bg);\n border-color: transparent;\n border-radius: 1rem;\n}\n.form-range::-moz-range-thumb {\n width: 1rem;\n height: 1rem;\n background-color: #0d6efd;\n border: 0;\n border-radius: 1rem;\n -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n -moz-appearance: none;\n appearance: none;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-range::-moz-range-thumb {\n -moz-transition: none;\n transition: none;\n }\n}\n.form-range::-moz-range-thumb:active {\n background-color: #b6d4fe;\n}\n.form-range::-moz-range-track {\n width: 100%;\n height: 0.5rem;\n color: transparent;\n cursor: pointer;\n background-color: var(--bs-tertiary-bg);\n border-color: transparent;\n border-radius: 1rem;\n}\n.form-range:disabled {\n pointer-events: none;\n}\n.form-range:disabled::-webkit-slider-thumb {\n background-color: var(--bs-secondary-color);\n}\n.form-range:disabled::-moz-range-thumb {\n background-color: var(--bs-secondary-color);\n}\n\n.form-floating {\n position: relative;\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext,\n.form-floating > .form-select {\n height: calc(3.5rem + calc(var(--bs-border-width) * 2));\n min-height: calc(3.5rem + calc(var(--bs-border-width) * 2));\n line-height: 1.25;\n}\n.form-floating > label {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2;\n height: 100%;\n padding: 1rem 0.75rem;\n overflow: hidden;\n text-align: start;\n text-overflow: ellipsis;\n white-space: nowrap;\n pointer-events: none;\n border: var(--bs-border-width) solid transparent;\n transform-origin: 0 0;\n transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .form-floating > label {\n transition: none;\n }\n}\n.form-floating > .form-control,\n.form-floating > .form-control-plaintext {\n padding: 1rem 0.75rem;\n}\n.form-floating > .form-control::-moz-placeholder, .form-floating > .form-control-plaintext::-moz-placeholder {\n color: transparent;\n}\n.form-floating > .form-control::placeholder,\n.form-floating > .form-control-plaintext::placeholder {\n color: transparent;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown), .form-floating > .form-control-plaintext:not(:-moz-placeholder-shown) {\n padding-top: 1.625rem;\n padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:focus, .form-floating > .form-control:not(:placeholder-shown),\n.form-floating > .form-control-plaintext:focus,\n.form-floating > .form-control-plaintext:not(:placeholder-shown) {\n padding-top: 1.625rem;\n padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:-webkit-autofill,\n.form-floating > .form-control-plaintext:-webkit-autofill {\n padding-top: 1.625rem;\n padding-bottom: 0.625rem;\n}\n.form-floating > .form-select {\n padding-top: 1.625rem;\n padding-bottom: 0.625rem;\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {\n color: rgba(var(--bs-body-color-rgb), 0.65);\n transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:focus ~ label,\n.form-floating > .form-control:not(:placeholder-shown) ~ label,\n.form-floating > .form-control-plaintext ~ label,\n.form-floating > .form-select ~ label {\n color: rgba(var(--bs-body-color-rgb), 0.65);\n transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label::after {\n position: absolute;\n inset: 1rem 0.375rem;\n z-index: -1;\n height: 1.5em;\n content: \"\";\n background-color: var(--bs-body-bg);\n border-radius: var(--bs-border-radius);\n}\n.form-floating > .form-control:focus ~ label::after,\n.form-floating > .form-control:not(:placeholder-shown) ~ label::after,\n.form-floating > .form-control-plaintext ~ label::after,\n.form-floating > .form-select ~ label::after {\n position: absolute;\n inset: 1rem 0.375rem;\n z-index: -1;\n height: 1.5em;\n content: \"\";\n background-color: var(--bs-body-bg);\n border-radius: var(--bs-border-radius);\n}\n.form-floating > .form-control:-webkit-autofill ~ label {\n color: rgba(var(--bs-body-color-rgb), 0.65);\n transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);\n}\n.form-floating > .form-control-plaintext ~ label {\n border-width: var(--bs-border-width) 0;\n}\n.form-floating > :disabled ~ label {\n color: #6c757d;\n}\n.form-floating > :disabled ~ label::after {\n background-color: var(--bs-secondary-bg);\n}\n\n.input-group {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n width: 100%;\n}\n.input-group > .form-control,\n.input-group > .form-select,\n.input-group > .form-floating {\n position: relative;\n flex: 1 1 auto;\n width: 1%;\n min-width: 0;\n}\n.input-group > .form-control:focus,\n.input-group > .form-select:focus,\n.input-group > .form-floating:focus-within {\n z-index: 5;\n}\n.input-group .btn {\n position: relative;\n z-index: 2;\n}\n.input-group .btn:focus {\n z-index: 5;\n}\n\n.input-group-text {\n display: flex;\n align-items: center;\n padding: 0.375rem 0.75rem;\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: var(--bs-body-color);\n text-align: center;\n white-space: nowrap;\n background-color: var(--bs-tertiary-bg);\n border: var(--bs-border-width) solid var(--bs-border-color);\n border-radius: var(--bs-border-radius);\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .form-select,\n.input-group-lg > .input-group-text,\n.input-group-lg > .btn {\n padding: 0.5rem 1rem;\n font-size: 1.25rem;\n border-radius: var(--bs-border-radius-lg);\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .form-select,\n.input-group-sm > .input-group-text,\n.input-group-sm > .btn {\n padding: 0.25rem 0.5rem;\n font-size: 0.875rem;\n border-radius: var(--bs-border-radius-sm);\n}\n\n.input-group-lg > .form-select,\n.input-group-sm > .form-select {\n padding-right: 3rem;\n}\n\n.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3),\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control,\n.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group.has-validation > :nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating),\n.input-group.has-validation > .dropdown-toggle:nth-last-child(n+4),\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-control,\n.input-group.has-validation > .form-floating:nth-last-child(n+3) > .form-select {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {\n margin-left: calc(var(--bs-border-width) * -1);\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n.input-group > .form-floating:not(:first-child) > .form-control,\n.input-group > .form-floating:not(:first-child) > .form-select {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.valid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 0.875em;\n color: var(--bs-form-valid-color);\n}\n\n.valid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: 0.1rem;\n font-size: 0.875rem;\n color: #fff;\n background-color: var(--bs-success);\n border-radius: var(--bs-border-radius);\n}\n\n.was-validated :valid ~ .valid-feedback,\n.was-validated :valid ~ .valid-tooltip,\n.is-valid ~ .valid-feedback,\n.is-valid ~ .valid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:valid, .form-control.is-valid {\n border-color: var(--bs-form-valid-border-color);\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:valid:focus, .form-control.is-valid:focus {\n border-color: var(--bs-form-valid-border-color);\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);\n}\n\n.was-validated textarea.form-control:valid, textarea.form-control.is-valid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:valid, .form-select.is-valid {\n border-color: var(--bs-form-valid-border-color);\n}\n.was-validated .form-select:valid:not([multiple]):not([size]), .was-validated .form-select:valid:not([multiple])[size=\"1\"], .form-select.is-valid:not([multiple]):not([size]), .form-select.is-valid:not([multiple])[size=\"1\"] {\n --bs-form-select-bg-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e\");\n padding-right: 4.125rem;\n background-position: right 0.75rem center, center right 2.25rem;\n background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:valid:focus, .form-select.is-valid:focus {\n border-color: var(--bs-form-valid-border-color);\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);\n}\n\n.was-validated .form-control-color:valid, .form-control-color.is-valid {\n width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:valid, .form-check-input.is-valid {\n border-color: var(--bs-form-valid-border-color);\n}\n.was-validated .form-check-input:valid:checked, .form-check-input.is-valid:checked {\n background-color: var(--bs-form-valid-color);\n}\n.was-validated .form-check-input:valid:focus, .form-check-input.is-valid:focus {\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-success-rgb), 0.25);\n}\n.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label {\n color: var(--bs-form-valid-color);\n}\n\n.form-check-inline .form-check-input ~ .valid-feedback {\n margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):valid, .input-group > .form-control:not(:focus).is-valid,\n.was-validated .input-group > .form-select:not(:focus):valid,\n.input-group > .form-select:not(:focus).is-valid,\n.was-validated .input-group > .form-floating:not(:focus-within):valid,\n.input-group > .form-floating:not(:focus-within).is-valid {\n z-index: 3;\n}\n\n.invalid-feedback {\n display: none;\n width: 100%;\n margin-top: 0.25rem;\n font-size: 0.875em;\n color: var(--bs-form-invalid-color);\n}\n\n.invalid-tooltip {\n position: absolute;\n top: 100%;\n z-index: 5;\n display: none;\n max-width: 100%;\n padding: 0.25rem 0.5rem;\n margin-top: 0.1rem;\n font-size: 0.875rem;\n color: #fff;\n background-color: var(--bs-danger);\n border-radius: var(--bs-border-radius);\n}\n\n.was-validated :invalid ~ .invalid-feedback,\n.was-validated :invalid ~ .invalid-tooltip,\n.is-invalid ~ .invalid-feedback,\n.is-invalid ~ .invalid-tooltip {\n display: block;\n}\n\n.was-validated .form-control:invalid, .form-control.is-invalid {\n border-color: var(--bs-form-invalid-border-color);\n padding-right: calc(1.5em + 0.75rem);\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n background-repeat: no-repeat;\n background-position: right calc(0.375em + 0.1875rem) center;\n background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus {\n border-color: var(--bs-form-invalid-border-color);\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);\n}\n\n.was-validated textarea.form-control:invalid, textarea.form-control.is-invalid {\n padding-right: calc(1.5em + 0.75rem);\n background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);\n}\n\n.was-validated .form-select:invalid, .form-select.is-invalid {\n border-color: var(--bs-form-invalid-border-color);\n}\n.was-validated .form-select:invalid:not([multiple]):not([size]), .was-validated .form-select:invalid:not([multiple])[size=\"1\"], .form-select.is-invalid:not([multiple]):not([size]), .form-select.is-invalid:not([multiple])[size=\"1\"] {\n --bs-form-select-bg-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e\");\n padding-right: 4.125rem;\n background-position: right 0.75rem center, center right 2.25rem;\n background-size: 16px 12px, calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);\n}\n.was-validated .form-select:invalid:focus, .form-select.is-invalid:focus {\n border-color: var(--bs-form-invalid-border-color);\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);\n}\n\n.was-validated .form-control-color:invalid, .form-control-color.is-invalid {\n width: calc(3rem + calc(1.5em + 0.75rem));\n}\n\n.was-validated .form-check-input:invalid, .form-check-input.is-invalid {\n border-color: var(--bs-form-invalid-border-color);\n}\n.was-validated .form-check-input:invalid:checked, .form-check-input.is-invalid:checked {\n background-color: var(--bs-form-invalid-color);\n}\n.was-validated .form-check-input:invalid:focus, .form-check-input.is-invalid:focus {\n box-shadow: 0 0 0 0.25rem rgba(var(--bs-danger-rgb), 0.25);\n}\n.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label {\n color: var(--bs-form-invalid-color);\n}\n\n.form-check-inline .form-check-input ~ .invalid-feedback {\n margin-left: 0.5em;\n}\n\n.was-validated .input-group > .form-control:not(:focus):invalid, .input-group > .form-control:not(:focus).is-invalid,\n.was-validated .input-group > .form-select:not(:focus):invalid,\n.input-group > .form-select:not(:focus).is-invalid,\n.was-validated .input-group > .form-floating:not(:focus-within):invalid,\n.input-group > .form-floating:not(:focus-within).is-invalid {\n z-index: 4;\n}\n\n.btn {\n --bs-btn-padding-x: 0.75rem;\n --bs-btn-padding-y: 0.375rem;\n --bs-btn-font-family: ;\n --bs-btn-font-size: 1rem;\n --bs-btn-font-weight: 400;\n --bs-btn-line-height: 1.5;\n --bs-btn-color: var(--bs-body-color);\n --bs-btn-bg: transparent;\n --bs-btn-border-width: var(--bs-border-width);\n --bs-btn-border-color: transparent;\n --bs-btn-border-radius: var(--bs-border-radius);\n --bs-btn-hover-border-color: transparent;\n --bs-btn-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n --bs-btn-disabled-opacity: 0.65;\n --bs-btn-focus-box-shadow: 0 0 0 0.25rem rgba(var(--bs-btn-focus-shadow-rgb), .5);\n display: inline-block;\n padding: var(--bs-btn-padding-y) var(--bs-btn-padding-x);\n font-family: var(--bs-btn-font-family);\n font-size: var(--bs-btn-font-size);\n font-weight: var(--bs-btn-font-weight);\n line-height: var(--bs-btn-line-height);\n color: var(--bs-btn-color);\n text-align: center;\n text-decoration: none;\n vertical-align: middle;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n border: var(--bs-btn-border-width) solid var(--bs-btn-border-color);\n border-radius: var(--bs-btn-border-radius);\n background-color: var(--bs-btn-bg);\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .btn {\n transition: none;\n }\n}\n.btn:hover {\n color: var(--bs-btn-hover-color);\n background-color: var(--bs-btn-hover-bg);\n border-color: var(--bs-btn-hover-border-color);\n}\n.btn-check + .btn:hover {\n color: var(--bs-btn-color);\n background-color: var(--bs-btn-bg);\n border-color: var(--bs-btn-border-color);\n}\n.btn:focus-visible {\n color: var(--bs-btn-hover-color);\n background-color: var(--bs-btn-hover-bg);\n border-color: var(--bs-btn-hover-border-color);\n outline: 0;\n box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:focus-visible + .btn {\n border-color: var(--bs-btn-hover-border-color);\n outline: 0;\n box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn-check:checked + .btn, :not(.btn-check) + .btn:active, .btn:first-child:active, .btn.active, .btn.show {\n color: var(--bs-btn-active-color);\n background-color: var(--bs-btn-active-bg);\n border-color: var(--bs-btn-active-border-color);\n}\n.btn-check:checked + .btn:focus-visible, :not(.btn-check) + .btn:active:focus-visible, .btn:first-child:active:focus-visible, .btn.active:focus-visible, .btn.show:focus-visible {\n box-shadow: var(--bs-btn-focus-box-shadow);\n}\n.btn:disabled, .btn.disabled, fieldset:disabled .btn {\n color: var(--bs-btn-disabled-color);\n pointer-events: none;\n background-color: var(--bs-btn-disabled-bg);\n border-color: var(--bs-btn-disabled-border-color);\n opacity: var(--bs-btn-disabled-opacity);\n}\n\n.btn-primary {\n --bs-btn-color: #fff;\n --bs-btn-bg: #0d6efd;\n --bs-btn-border-color: #0d6efd;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #0b5ed7;\n --bs-btn-hover-border-color: #0a58ca;\n --bs-btn-focus-shadow-rgb: 49, 132, 253;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #0a58ca;\n --bs-btn-active-border-color: #0a53be;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #fff;\n --bs-btn-disabled-bg: #0d6efd;\n --bs-btn-disabled-border-color: #0d6efd;\n}\n\n.btn-secondary {\n --bs-btn-color: #fff;\n --bs-btn-bg: #6c757d;\n --bs-btn-border-color: #6c757d;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #5c636a;\n --bs-btn-hover-border-color: #565e64;\n --bs-btn-focus-shadow-rgb: 130, 138, 145;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #565e64;\n --bs-btn-active-border-color: #51585e;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #fff;\n --bs-btn-disabled-bg: #6c757d;\n --bs-btn-disabled-border-color: #6c757d;\n}\n\n.btn-success {\n --bs-btn-color: #fff;\n --bs-btn-bg: #198754;\n --bs-btn-border-color: #198754;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #157347;\n --bs-btn-hover-border-color: #146c43;\n --bs-btn-focus-shadow-rgb: 60, 153, 110;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #146c43;\n --bs-btn-active-border-color: #13653f;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #fff;\n --bs-btn-disabled-bg: #198754;\n --bs-btn-disabled-border-color: #198754;\n}\n\n.btn-info {\n --bs-btn-color: #000;\n --bs-btn-bg: #0dcaf0;\n --bs-btn-border-color: #0dcaf0;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #31d2f2;\n --bs-btn-hover-border-color: #25cff2;\n --bs-btn-focus-shadow-rgb: 11, 172, 204;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #3dd5f3;\n --bs-btn-active-border-color: #25cff2;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #000;\n --bs-btn-disabled-bg: #0dcaf0;\n --bs-btn-disabled-border-color: #0dcaf0;\n}\n\n.btn-warning {\n --bs-btn-color: #000;\n --bs-btn-bg: #ffc107;\n --bs-btn-border-color: #ffc107;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #ffca2c;\n --bs-btn-hover-border-color: #ffc720;\n --bs-btn-focus-shadow-rgb: 217, 164, 6;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #ffcd39;\n --bs-btn-active-border-color: #ffc720;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #000;\n --bs-btn-disabled-bg: #ffc107;\n --bs-btn-disabled-border-color: #ffc107;\n}\n\n.btn-danger {\n --bs-btn-color: #fff;\n --bs-btn-bg: #dc3545;\n --bs-btn-border-color: #dc3545;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #bb2d3b;\n --bs-btn-hover-border-color: #b02a37;\n --bs-btn-focus-shadow-rgb: 225, 83, 97;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #b02a37;\n --bs-btn-active-border-color: #a52834;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #fff;\n --bs-btn-disabled-bg: #dc3545;\n --bs-btn-disabled-border-color: #dc3545;\n}\n\n.btn-light {\n --bs-btn-color: #000;\n --bs-btn-bg: #f8f9fa;\n --bs-btn-border-color: #f8f9fa;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #d3d4d5;\n --bs-btn-hover-border-color: #c6c7c8;\n --bs-btn-focus-shadow-rgb: 211, 212, 213;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #c6c7c8;\n --bs-btn-active-border-color: #babbbc;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #000;\n --bs-btn-disabled-bg: #f8f9fa;\n --bs-btn-disabled-border-color: #f8f9fa;\n}\n\n.btn-dark {\n --bs-btn-color: #fff;\n --bs-btn-bg: #212529;\n --bs-btn-border-color: #212529;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #424649;\n --bs-btn-hover-border-color: #373b3e;\n --bs-btn-focus-shadow-rgb: 66, 70, 73;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #4d5154;\n --bs-btn-active-border-color: #373b3e;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #fff;\n --bs-btn-disabled-bg: #212529;\n --bs-btn-disabled-border-color: #212529;\n}\n\n.btn-outline-primary {\n --bs-btn-color: #0d6efd;\n --bs-btn-border-color: #0d6efd;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #0d6efd;\n --bs-btn-hover-border-color: #0d6efd;\n --bs-btn-focus-shadow-rgb: 13, 110, 253;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #0d6efd;\n --bs-btn-active-border-color: #0d6efd;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #0d6efd;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #0d6efd;\n --bs-gradient: none;\n}\n\n.btn-outline-secondary {\n --bs-btn-color: #6c757d;\n --bs-btn-border-color: #6c757d;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #6c757d;\n --bs-btn-hover-border-color: #6c757d;\n --bs-btn-focus-shadow-rgb: 108, 117, 125;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #6c757d;\n --bs-btn-active-border-color: #6c757d;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #6c757d;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #6c757d;\n --bs-gradient: none;\n}\n\n.btn-outline-success {\n --bs-btn-color: #198754;\n --bs-btn-border-color: #198754;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #198754;\n --bs-btn-hover-border-color: #198754;\n --bs-btn-focus-shadow-rgb: 25, 135, 84;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #198754;\n --bs-btn-active-border-color: #198754;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #198754;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #198754;\n --bs-gradient: none;\n}\n\n.btn-outline-info {\n --bs-btn-color: #0dcaf0;\n --bs-btn-border-color: #0dcaf0;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #0dcaf0;\n --bs-btn-hover-border-color: #0dcaf0;\n --bs-btn-focus-shadow-rgb: 13, 202, 240;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #0dcaf0;\n --bs-btn-active-border-color: #0dcaf0;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #0dcaf0;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #0dcaf0;\n --bs-gradient: none;\n}\n\n.btn-outline-warning {\n --bs-btn-color: #ffc107;\n --bs-btn-border-color: #ffc107;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #ffc107;\n --bs-btn-hover-border-color: #ffc107;\n --bs-btn-focus-shadow-rgb: 255, 193, 7;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #ffc107;\n --bs-btn-active-border-color: #ffc107;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #ffc107;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #ffc107;\n --bs-gradient: none;\n}\n\n.btn-outline-danger {\n --bs-btn-color: #dc3545;\n --bs-btn-border-color: #dc3545;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #dc3545;\n --bs-btn-hover-border-color: #dc3545;\n --bs-btn-focus-shadow-rgb: 220, 53, 69;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #dc3545;\n --bs-btn-active-border-color: #dc3545;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #dc3545;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #dc3545;\n --bs-gradient: none;\n}\n\n.btn-outline-light {\n --bs-btn-color: #f8f9fa;\n --bs-btn-border-color: #f8f9fa;\n --bs-btn-hover-color: #000;\n --bs-btn-hover-bg: #f8f9fa;\n --bs-btn-hover-border-color: #f8f9fa;\n --bs-btn-focus-shadow-rgb: 248, 249, 250;\n --bs-btn-active-color: #000;\n --bs-btn-active-bg: #f8f9fa;\n --bs-btn-active-border-color: #f8f9fa;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #f8f9fa;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #f8f9fa;\n --bs-gradient: none;\n}\n\n.btn-outline-dark {\n --bs-btn-color: #212529;\n --bs-btn-border-color: #212529;\n --bs-btn-hover-color: #fff;\n --bs-btn-hover-bg: #212529;\n --bs-btn-hover-border-color: #212529;\n --bs-btn-focus-shadow-rgb: 33, 37, 41;\n --bs-btn-active-color: #fff;\n --bs-btn-active-bg: #212529;\n --bs-btn-active-border-color: #212529;\n --bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n --bs-btn-disabled-color: #212529;\n --bs-btn-disabled-bg: transparent;\n --bs-btn-disabled-border-color: #212529;\n --bs-gradient: none;\n}\n\n.btn-link {\n --bs-btn-font-weight: 400;\n --bs-btn-color: var(--bs-link-color);\n --bs-btn-bg: transparent;\n --bs-btn-border-color: transparent;\n --bs-btn-hover-color: var(--bs-link-hover-color);\n --bs-btn-hover-border-color: transparent;\n --bs-btn-active-color: var(--bs-link-hover-color);\n --bs-btn-active-border-color: transparent;\n --bs-btn-disabled-color: #6c757d;\n --bs-btn-disabled-border-color: transparent;\n --bs-btn-box-shadow: 0 0 0 #000;\n --bs-btn-focus-shadow-rgb: 49, 132, 253;\n text-decoration: underline;\n}\n.btn-link:focus-visible {\n color: var(--bs-btn-color);\n}\n.btn-link:hover {\n color: var(--bs-btn-hover-color);\n}\n\n.btn-lg, .btn-group-lg > .btn {\n --bs-btn-padding-y: 0.5rem;\n --bs-btn-padding-x: 1rem;\n --bs-btn-font-size: 1.25rem;\n --bs-btn-border-radius: var(--bs-border-radius-lg);\n}\n\n.btn-sm, .btn-group-sm > .btn {\n --bs-btn-padding-y: 0.25rem;\n --bs-btn-padding-x: 0.5rem;\n --bs-btn-font-size: 0.875rem;\n --bs-btn-border-radius: var(--bs-border-radius-sm);\n}\n\n.fade {\n transition: opacity 0.15s linear;\n}\n@media (prefers-reduced-motion: reduce) {\n .fade {\n transition: none;\n }\n}\n.fade:not(.show) {\n opacity: 0;\n}\n\n.collapse:not(.show) {\n display: none;\n}\n\n.collapsing {\n height: 0;\n overflow: hidden;\n transition: height 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n .collapsing {\n transition: none;\n }\n}\n.collapsing.collapse-horizontal {\n width: 0;\n height: auto;\n transition: width 0.35s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n .collapsing.collapse-horizontal {\n transition: none;\n }\n}\n\n.dropup,\n.dropend,\n.dropdown,\n.dropstart,\n.dropup-center,\n.dropdown-center {\n position: relative;\n}\n\n.dropdown-toggle {\n white-space: nowrap;\n}\n.dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid;\n border-right: 0.3em solid transparent;\n border-bottom: 0;\n border-left: 0.3em solid transparent;\n}\n.dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropdown-menu {\n --bs-dropdown-zindex: 1000;\n --bs-dropdown-min-width: 10rem;\n --bs-dropdown-padding-x: 0;\n --bs-dropdown-padding-y: 0.5rem;\n --bs-dropdown-spacer: 0.125rem;\n --bs-dropdown-font-size: 1rem;\n --bs-dropdown-color: var(--bs-body-color);\n --bs-dropdown-bg: var(--bs-body-bg);\n --bs-dropdown-border-color: var(--bs-border-color-translucent);\n --bs-dropdown-border-radius: var(--bs-border-radius);\n --bs-dropdown-border-width: var(--bs-border-width);\n --bs-dropdown-inner-border-radius: calc(var(--bs-border-radius) - var(--bs-border-width));\n --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n --bs-dropdown-divider-margin-y: 0.5rem;\n --bs-dropdown-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n --bs-dropdown-link-color: var(--bs-body-color);\n --bs-dropdown-link-hover-color: var(--bs-body-color);\n --bs-dropdown-link-hover-bg: var(--bs-tertiary-bg);\n --bs-dropdown-link-active-color: #fff;\n --bs-dropdown-link-active-bg: #0d6efd;\n --bs-dropdown-link-disabled-color: var(--bs-tertiary-color);\n --bs-dropdown-item-padding-x: 1rem;\n --bs-dropdown-item-padding-y: 0.25rem;\n --bs-dropdown-header-color: #6c757d;\n --bs-dropdown-header-padding-x: 1rem;\n --bs-dropdown-header-padding-y: 0.5rem;\n position: absolute;\n z-index: var(--bs-dropdown-zindex);\n display: none;\n min-width: var(--bs-dropdown-min-width);\n padding: var(--bs-dropdown-padding-y) var(--bs-dropdown-padding-x);\n margin: 0;\n font-size: var(--bs-dropdown-font-size);\n color: var(--bs-dropdown-color);\n text-align: left;\n list-style: none;\n background-color: var(--bs-dropdown-bg);\n background-clip: padding-box;\n border: var(--bs-dropdown-border-width) solid var(--bs-dropdown-border-color);\n border-radius: var(--bs-dropdown-border-radius);\n}\n.dropdown-menu[data-bs-popper] {\n top: 100%;\n left: 0;\n margin-top: var(--bs-dropdown-spacer);\n}\n\n.dropdown-menu-start {\n --bs-position: start;\n}\n.dropdown-menu-start[data-bs-popper] {\n right: auto;\n left: 0;\n}\n\n.dropdown-menu-end {\n --bs-position: end;\n}\n.dropdown-menu-end[data-bs-popper] {\n right: 0;\n left: auto;\n}\n\n@media (min-width: 576px) {\n .dropdown-menu-sm-start {\n --bs-position: start;\n }\n .dropdown-menu-sm-start[data-bs-popper] {\n right: auto;\n left: 0;\n }\n .dropdown-menu-sm-end {\n --bs-position: end;\n }\n .dropdown-menu-sm-end[data-bs-popper] {\n right: 0;\n left: auto;\n }\n}\n@media (min-width: 768px) {\n .dropdown-menu-md-start {\n --bs-position: start;\n }\n .dropdown-menu-md-start[data-bs-popper] {\n right: auto;\n left: 0;\n }\n .dropdown-menu-md-end {\n --bs-position: end;\n }\n .dropdown-menu-md-end[data-bs-popper] {\n right: 0;\n left: auto;\n }\n}\n@media (min-width: 992px) {\n .dropdown-menu-lg-start {\n --bs-position: start;\n }\n .dropdown-menu-lg-start[data-bs-popper] {\n right: auto;\n left: 0;\n }\n .dropdown-menu-lg-end {\n --bs-position: end;\n }\n .dropdown-menu-lg-end[data-bs-popper] {\n right: 0;\n left: auto;\n }\n}\n@media (min-width: 1200px) {\n .dropdown-menu-xl-start {\n --bs-position: start;\n }\n .dropdown-menu-xl-start[data-bs-popper] {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xl-end {\n --bs-position: end;\n }\n .dropdown-menu-xl-end[data-bs-popper] {\n right: 0;\n left: auto;\n }\n}\n@media (min-width: 1400px) {\n .dropdown-menu-xxl-start {\n --bs-position: start;\n }\n .dropdown-menu-xxl-start[data-bs-popper] {\n right: auto;\n left: 0;\n }\n .dropdown-menu-xxl-end {\n --bs-position: end;\n }\n .dropdown-menu-xxl-end[data-bs-popper] {\n right: 0;\n left: auto;\n }\n}\n.dropup .dropdown-menu[data-bs-popper] {\n top: auto;\n bottom: 100%;\n margin-top: 0;\n margin-bottom: var(--bs-dropdown-spacer);\n}\n.dropup .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0;\n border-right: 0.3em solid transparent;\n border-bottom: 0.3em solid;\n border-left: 0.3em solid transparent;\n}\n.dropup .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n\n.dropend .dropdown-menu[data-bs-popper] {\n top: 0;\n right: auto;\n left: 100%;\n margin-top: 0;\n margin-left: var(--bs-dropdown-spacer);\n}\n.dropend .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0;\n border-bottom: 0.3em solid transparent;\n border-left: 0.3em solid;\n}\n.dropend .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n.dropend .dropdown-toggle::after {\n vertical-align: 0;\n}\n\n.dropstart .dropdown-menu[data-bs-popper] {\n top: 0;\n right: 100%;\n left: auto;\n margin-top: 0;\n margin-right: var(--bs-dropdown-spacer);\n}\n.dropstart .dropdown-toggle::after {\n display: inline-block;\n margin-left: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n}\n.dropstart .dropdown-toggle::after {\n display: none;\n}\n.dropstart .dropdown-toggle::before {\n display: inline-block;\n margin-right: 0.255em;\n vertical-align: 0.255em;\n content: \"\";\n border-top: 0.3em solid transparent;\n border-right: 0.3em solid;\n border-bottom: 0.3em solid transparent;\n}\n.dropstart .dropdown-toggle:empty::after {\n margin-left: 0;\n}\n.dropstart .dropdown-toggle::before {\n vertical-align: 0;\n}\n\n.dropdown-divider {\n height: 0;\n margin: var(--bs-dropdown-divider-margin-y) 0;\n overflow: hidden;\n border-top: 1px solid var(--bs-dropdown-divider-bg);\n opacity: 1;\n}\n\n.dropdown-item {\n display: block;\n width: 100%;\n padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n clear: both;\n font-weight: 400;\n color: var(--bs-dropdown-link-color);\n text-align: inherit;\n text-decoration: none;\n white-space: nowrap;\n background-color: transparent;\n border: 0;\n border-radius: var(--bs-dropdown-item-border-radius, 0);\n}\n.dropdown-item:hover, .dropdown-item:focus {\n color: var(--bs-dropdown-link-hover-color);\n background-color: var(--bs-dropdown-link-hover-bg);\n}\n.dropdown-item.active, .dropdown-item:active {\n color: var(--bs-dropdown-link-active-color);\n text-decoration: none;\n background-color: var(--bs-dropdown-link-active-bg);\n}\n.dropdown-item.disabled, .dropdown-item:disabled {\n color: var(--bs-dropdown-link-disabled-color);\n pointer-events: none;\n background-color: transparent;\n}\n\n.dropdown-menu.show {\n display: block;\n}\n\n.dropdown-header {\n display: block;\n padding: var(--bs-dropdown-header-padding-y) var(--bs-dropdown-header-padding-x);\n margin-bottom: 0;\n font-size: 0.875rem;\n color: var(--bs-dropdown-header-color);\n white-space: nowrap;\n}\n\n.dropdown-item-text {\n display: block;\n padding: var(--bs-dropdown-item-padding-y) var(--bs-dropdown-item-padding-x);\n color: var(--bs-dropdown-link-color);\n}\n\n.dropdown-menu-dark {\n --bs-dropdown-color: #dee2e6;\n --bs-dropdown-bg: #343a40;\n --bs-dropdown-border-color: var(--bs-border-color-translucent);\n --bs-dropdown-box-shadow: ;\n --bs-dropdown-link-color: #dee2e6;\n --bs-dropdown-link-hover-color: #fff;\n --bs-dropdown-divider-bg: var(--bs-border-color-translucent);\n --bs-dropdown-link-hover-bg: rgba(255, 255, 255, 0.15);\n --bs-dropdown-link-active-color: #fff;\n --bs-dropdown-link-active-bg: #0d6efd;\n --bs-dropdown-link-disabled-color: #adb5bd;\n --bs-dropdown-header-color: #adb5bd;\n}\n\n.btn-group,\n.btn-group-vertical {\n position: relative;\n display: inline-flex;\n vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n position: relative;\n flex: 1 1 auto;\n}\n.btn-group > .btn-check:checked + .btn,\n.btn-group > .btn-check:focus + .btn,\n.btn-group > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn-check:checked + .btn,\n.btn-group-vertical > .btn-check:focus + .btn,\n.btn-group-vertical > .btn:hover,\n.btn-group-vertical > .btn:focus,\n.btn-group-vertical > .btn:active,\n.btn-group-vertical > .btn.active {\n z-index: 1;\n}\n\n.btn-toolbar {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-start;\n}\n.btn-toolbar .input-group {\n width: auto;\n}\n\n.btn-group {\n border-radius: var(--bs-border-radius);\n}\n.btn-group > :not(.btn-check:first-child) + .btn,\n.btn-group > .btn-group:not(:first-child) {\n margin-left: calc(var(--bs-border-width) * -1);\n}\n.btn-group > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group > .btn.dropdown-toggle-split:first-child,\n.btn-group > .btn-group:not(:last-child) > .btn {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.btn-group > .btn:nth-child(n+3),\n.btn-group > :not(.btn-check) + .btn,\n.btn-group > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n}\n\n.dropdown-toggle-split {\n padding-right: 0.5625rem;\n padding-left: 0.5625rem;\n}\n.dropdown-toggle-split::after, .dropup .dropdown-toggle-split::after, .dropend .dropdown-toggle-split::after {\n margin-left: 0;\n}\n.dropstart .dropdown-toggle-split::before {\n margin-right: 0;\n}\n\n.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {\n padding-right: 0.375rem;\n padding-left: 0.375rem;\n}\n\n.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {\n padding-right: 0.75rem;\n padding-left: 0.75rem;\n}\n\n.btn-group-vertical {\n flex-direction: column;\n align-items: flex-start;\n justify-content: center;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group {\n width: 100%;\n}\n.btn-group-vertical > .btn:not(:first-child),\n.btn-group-vertical > .btn-group:not(:first-child) {\n margin-top: calc(var(--bs-border-width) * -1);\n}\n.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),\n.btn-group-vertical > .btn-group:not(:last-child) > .btn {\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn ~ .btn,\n.btn-group-vertical > .btn-group:not(:first-child) > .btn {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav {\n --bs-nav-link-padding-x: 1rem;\n --bs-nav-link-padding-y: 0.5rem;\n --bs-nav-link-font-weight: ;\n --bs-nav-link-color: var(--bs-link-color);\n --bs-nav-link-hover-color: var(--bs-link-hover-color);\n --bs-nav-link-disabled-color: var(--bs-secondary-color);\n display: flex;\n flex-wrap: wrap;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n\n.nav-link {\n display: block;\n padding: var(--bs-nav-link-padding-y) var(--bs-nav-link-padding-x);\n font-size: var(--bs-nav-link-font-size);\n font-weight: var(--bs-nav-link-font-weight);\n color: var(--bs-nav-link-color);\n text-decoration: none;\n background: none;\n border: 0;\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .nav-link {\n transition: none;\n }\n}\n.nav-link:hover, .nav-link:focus {\n color: var(--bs-nav-link-hover-color);\n}\n.nav-link:focus-visible {\n outline: 0;\n box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n}\n.nav-link.disabled {\n color: var(--bs-nav-link-disabled-color);\n pointer-events: none;\n cursor: default;\n}\n\n.nav-tabs {\n --bs-nav-tabs-border-width: var(--bs-border-width);\n --bs-nav-tabs-border-color: var(--bs-border-color);\n --bs-nav-tabs-border-radius: var(--bs-border-radius);\n --bs-nav-tabs-link-hover-border-color: var(--bs-secondary-bg) var(--bs-secondary-bg) var(--bs-border-color);\n --bs-nav-tabs-link-active-color: var(--bs-emphasis-color);\n --bs-nav-tabs-link-active-bg: var(--bs-body-bg);\n --bs-nav-tabs-link-active-border-color: var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);\n border-bottom: var(--bs-nav-tabs-border-width) solid var(--bs-nav-tabs-border-color);\n}\n.nav-tabs .nav-link {\n margin-bottom: calc(-1 * var(--bs-nav-tabs-border-width));\n border: var(--bs-nav-tabs-border-width) solid transparent;\n border-top-left-radius: var(--bs-nav-tabs-border-radius);\n border-top-right-radius: var(--bs-nav-tabs-border-radius);\n}\n.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus {\n isolation: isolate;\n border-color: var(--bs-nav-tabs-link-hover-border-color);\n}\n.nav-tabs .nav-link.disabled, .nav-tabs .nav-link:disabled {\n color: var(--bs-nav-link-disabled-color);\n background-color: transparent;\n border-color: transparent;\n}\n.nav-tabs .nav-link.active,\n.nav-tabs .nav-item.show .nav-link {\n color: var(--bs-nav-tabs-link-active-color);\n background-color: var(--bs-nav-tabs-link-active-bg);\n border-color: var(--bs-nav-tabs-link-active-border-color);\n}\n.nav-tabs .dropdown-menu {\n margin-top: calc(-1 * var(--bs-nav-tabs-border-width));\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n}\n\n.nav-pills {\n --bs-nav-pills-border-radius: var(--bs-border-radius);\n --bs-nav-pills-link-active-color: #fff;\n --bs-nav-pills-link-active-bg: #0d6efd;\n}\n.nav-pills .nav-link {\n border-radius: var(--bs-nav-pills-border-radius);\n}\n.nav-pills .nav-link:disabled {\n color: var(--bs-nav-link-disabled-color);\n background-color: transparent;\n border-color: transparent;\n}\n.nav-pills .nav-link.active,\n.nav-pills .show > .nav-link {\n color: var(--bs-nav-pills-link-active-color);\n background-color: var(--bs-nav-pills-link-active-bg);\n}\n\n.nav-underline {\n --bs-nav-underline-gap: 1rem;\n --bs-nav-underline-border-width: 0.125rem;\n --bs-nav-underline-link-active-color: var(--bs-emphasis-color);\n gap: var(--bs-nav-underline-gap);\n}\n.nav-underline .nav-link {\n padding-right: 0;\n padding-left: 0;\n border-bottom: var(--bs-nav-underline-border-width) solid transparent;\n}\n.nav-underline .nav-link:hover, .nav-underline .nav-link:focus {\n border-bottom-color: currentcolor;\n}\n.nav-underline .nav-link.active,\n.nav-underline .show > .nav-link {\n font-weight: 700;\n color: var(--bs-nav-underline-link-active-color);\n border-bottom-color: currentcolor;\n}\n\n.nav-fill > .nav-link,\n.nav-fill .nav-item {\n flex: 1 1 auto;\n text-align: center;\n}\n\n.nav-justified > .nav-link,\n.nav-justified .nav-item {\n flex-basis: 0;\n flex-grow: 1;\n text-align: center;\n}\n\n.nav-fill .nav-item .nav-link,\n.nav-justified .nav-item .nav-link {\n width: 100%;\n}\n\n.tab-content > .tab-pane {\n display: none;\n}\n.tab-content > .active {\n display: block;\n}\n\n.navbar {\n --bs-navbar-padding-x: 0;\n --bs-navbar-padding-y: 0.5rem;\n --bs-navbar-color: rgba(var(--bs-emphasis-color-rgb), 0.65);\n --bs-navbar-hover-color: rgba(var(--bs-emphasis-color-rgb), 0.8);\n --bs-navbar-disabled-color: rgba(var(--bs-emphasis-color-rgb), 0.3);\n --bs-navbar-active-color: rgba(var(--bs-emphasis-color-rgb), 1);\n --bs-navbar-brand-padding-y: 0.3125rem;\n --bs-navbar-brand-margin-end: 1rem;\n --bs-navbar-brand-font-size: 1.25rem;\n --bs-navbar-brand-color: rgba(var(--bs-emphasis-color-rgb), 1);\n --bs-navbar-brand-hover-color: rgba(var(--bs-emphasis-color-rgb), 1);\n --bs-navbar-nav-link-padding-x: 0.5rem;\n --bs-navbar-toggler-padding-y: 0.25rem;\n --bs-navbar-toggler-padding-x: 0.75rem;\n --bs-navbar-toggler-font-size: 1.25rem;\n --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2833, 37, 41, 0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n --bs-navbar-toggler-border-color: rgba(var(--bs-emphasis-color-rgb), 0.15);\n --bs-navbar-toggler-border-radius: var(--bs-border-radius);\n --bs-navbar-toggler-focus-width: 0.25rem;\n --bs-navbar-toggler-transition: box-shadow 0.15s ease-in-out;\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: var(--bs-navbar-padding-y) var(--bs-navbar-padding-x);\n}\n.navbar > .container,\n.navbar > .container-fluid,\n.navbar > .container-sm,\n.navbar > .container-md,\n.navbar > .container-lg,\n.navbar > .container-xl,\n.navbar > .container-xxl {\n display: flex;\n flex-wrap: inherit;\n align-items: center;\n justify-content: space-between;\n}\n.navbar-brand {\n padding-top: var(--bs-navbar-brand-padding-y);\n padding-bottom: var(--bs-navbar-brand-padding-y);\n margin-right: var(--bs-navbar-brand-margin-end);\n font-size: var(--bs-navbar-brand-font-size);\n color: var(--bs-navbar-brand-color);\n text-decoration: none;\n white-space: nowrap;\n}\n.navbar-brand:hover, .navbar-brand:focus {\n color: var(--bs-navbar-brand-hover-color);\n}\n\n.navbar-nav {\n --bs-nav-link-padding-x: 0;\n --bs-nav-link-padding-y: 0.5rem;\n --bs-nav-link-font-weight: ;\n --bs-nav-link-color: var(--bs-navbar-color);\n --bs-nav-link-hover-color: var(--bs-navbar-hover-color);\n --bs-nav-link-disabled-color: var(--bs-navbar-disabled-color);\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n list-style: none;\n}\n.navbar-nav .nav-link.active, .navbar-nav .nav-link.show {\n color: var(--bs-navbar-active-color);\n}\n.navbar-nav .dropdown-menu {\n position: static;\n}\n\n.navbar-text {\n padding-top: 0.5rem;\n padding-bottom: 0.5rem;\n color: var(--bs-navbar-color);\n}\n.navbar-text a,\n.navbar-text a:hover,\n.navbar-text a:focus {\n color: var(--bs-navbar-active-color);\n}\n\n.navbar-collapse {\n flex-basis: 100%;\n flex-grow: 1;\n align-items: center;\n}\n\n.navbar-toggler {\n padding: var(--bs-navbar-toggler-padding-y) var(--bs-navbar-toggler-padding-x);\n font-size: var(--bs-navbar-toggler-font-size);\n line-height: 1;\n color: var(--bs-navbar-color);\n background-color: transparent;\n border: var(--bs-border-width) solid var(--bs-navbar-toggler-border-color);\n border-radius: var(--bs-navbar-toggler-border-radius);\n transition: var(--bs-navbar-toggler-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n .navbar-toggler {\n transition: none;\n }\n}\n.navbar-toggler:hover {\n text-decoration: none;\n}\n.navbar-toggler:focus {\n text-decoration: none;\n outline: 0;\n box-shadow: 0 0 0 var(--bs-navbar-toggler-focus-width);\n}\n\n.navbar-toggler-icon {\n display: inline-block;\n width: 1.5em;\n height: 1.5em;\n vertical-align: middle;\n background-image: var(--bs-navbar-toggler-icon-bg);\n background-repeat: no-repeat;\n background-position: center;\n background-size: 100%;\n}\n\n.navbar-nav-scroll {\n max-height: var(--bs-scroll-height, 75vh);\n overflow-y: auto;\n}\n\n@media (min-width: 576px) {\n .navbar-expand-sm {\n flex-wrap: nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-sm .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-sm .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-sm .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n }\n .navbar-expand-sm .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-sm .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-sm .navbar-toggler {\n display: none;\n }\n .navbar-expand-sm .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n }\n .navbar-expand-sm .offcanvas .offcanvas-header {\n display: none;\n }\n .navbar-expand-sm .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n }\n}\n@media (min-width: 768px) {\n .navbar-expand-md {\n flex-wrap: nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-md .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-md .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-md .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n }\n .navbar-expand-md .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-md .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-md .navbar-toggler {\n display: none;\n }\n .navbar-expand-md .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n }\n .navbar-expand-md .offcanvas .offcanvas-header {\n display: none;\n }\n .navbar-expand-md .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n }\n}\n@media (min-width: 992px) {\n .navbar-expand-lg {\n flex-wrap: nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-lg .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-lg .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-lg .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n }\n .navbar-expand-lg .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-lg .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-lg .navbar-toggler {\n display: none;\n }\n .navbar-expand-lg .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n }\n .navbar-expand-lg .offcanvas .offcanvas-header {\n display: none;\n }\n .navbar-expand-lg .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n }\n}\n@media (min-width: 1200px) {\n .navbar-expand-xl {\n flex-wrap: nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xl .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n }\n .navbar-expand-xl .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-xl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xl .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n }\n .navbar-expand-xl .offcanvas .offcanvas-header {\n display: none;\n }\n .navbar-expand-xl .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n }\n}\n@media (min-width: 1400px) {\n .navbar-expand-xxl {\n flex-wrap: nowrap;\n justify-content: flex-start;\n }\n .navbar-expand-xxl .navbar-nav {\n flex-direction: row;\n }\n .navbar-expand-xxl .navbar-nav .dropdown-menu {\n position: absolute;\n }\n .navbar-expand-xxl .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n }\n .navbar-expand-xxl .navbar-nav-scroll {\n overflow: visible;\n }\n .navbar-expand-xxl .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n }\n .navbar-expand-xxl .navbar-toggler {\n display: none;\n }\n .navbar-expand-xxl .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n }\n .navbar-expand-xxl .offcanvas .offcanvas-header {\n display: none;\n }\n .navbar-expand-xxl .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n }\n}\n.navbar-expand {\n flex-wrap: nowrap;\n justify-content: flex-start;\n}\n.navbar-expand .navbar-nav {\n flex-direction: row;\n}\n.navbar-expand .navbar-nav .dropdown-menu {\n position: absolute;\n}\n.navbar-expand .navbar-nav .nav-link {\n padding-right: var(--bs-navbar-nav-link-padding-x);\n padding-left: var(--bs-navbar-nav-link-padding-x);\n}\n.navbar-expand .navbar-nav-scroll {\n overflow: visible;\n}\n.navbar-expand .navbar-collapse {\n display: flex !important;\n flex-basis: auto;\n}\n.navbar-expand .navbar-toggler {\n display: none;\n}\n.navbar-expand .offcanvas {\n position: static;\n z-index: auto;\n flex-grow: 1;\n width: auto !important;\n height: auto !important;\n visibility: visible !important;\n background-color: transparent !important;\n border: 0 !important;\n transform: none !important;\n transition: none;\n}\n.navbar-expand .offcanvas .offcanvas-header {\n display: none;\n}\n.navbar-expand .offcanvas .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n}\n\n.navbar-dark,\n.navbar[data-bs-theme=dark] {\n --bs-navbar-color: rgba(255, 255, 255, 0.55);\n --bs-navbar-hover-color: rgba(255, 255, 255, 0.75);\n --bs-navbar-disabled-color: rgba(255, 255, 255, 0.25);\n --bs-navbar-active-color: #fff;\n --bs-navbar-brand-color: #fff;\n --bs-navbar-brand-hover-color: #fff;\n --bs-navbar-toggler-border-color: rgba(255, 255, 255, 0.1);\n --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n[data-bs-theme=dark] .navbar-toggler-icon {\n --bs-navbar-toggler-icon-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e\");\n}\n\n.card {\n --bs-card-spacer-y: 1rem;\n --bs-card-spacer-x: 1rem;\n --bs-card-title-spacer-y: 0.5rem;\n --bs-card-title-color: ;\n --bs-card-subtitle-color: ;\n --bs-card-border-width: var(--bs-border-width);\n --bs-card-border-color: var(--bs-border-color-translucent);\n --bs-card-border-radius: var(--bs-border-radius);\n --bs-card-box-shadow: ;\n --bs-card-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));\n --bs-card-cap-padding-y: 0.5rem;\n --bs-card-cap-padding-x: 1rem;\n --bs-card-cap-bg: rgba(var(--bs-body-color-rgb), 0.03);\n --bs-card-cap-color: ;\n --bs-card-height: ;\n --bs-card-color: ;\n --bs-card-bg: var(--bs-body-bg);\n --bs-card-img-overlay-padding: 1rem;\n --bs-card-group-margin: 0.75rem;\n position: relative;\n display: flex;\n flex-direction: column;\n min-width: 0;\n height: var(--bs-card-height);\n color: var(--bs-body-color);\n word-wrap: break-word;\n background-color: var(--bs-card-bg);\n background-clip: border-box;\n border: var(--bs-card-border-width) solid var(--bs-card-border-color);\n border-radius: var(--bs-card-border-radius);\n}\n.card > hr {\n margin-right: 0;\n margin-left: 0;\n}\n.card > .list-group {\n border-top: inherit;\n border-bottom: inherit;\n}\n.card > .list-group:first-child {\n border-top-width: 0;\n border-top-left-radius: var(--bs-card-inner-border-radius);\n border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n.card > .list-group:last-child {\n border-bottom-width: 0;\n border-bottom-right-radius: var(--bs-card-inner-border-radius);\n border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n.card > .card-header + .list-group,\n.card > .list-group + .card-footer {\n border-top: 0;\n}\n\n.card-body {\n flex: 1 1 auto;\n padding: var(--bs-card-spacer-y) var(--bs-card-spacer-x);\n color: var(--bs-card-color);\n}\n\n.card-title {\n margin-bottom: var(--bs-card-title-spacer-y);\n color: var(--bs-card-title-color);\n}\n\n.card-subtitle {\n margin-top: calc(-0.5 * var(--bs-card-title-spacer-y));\n margin-bottom: 0;\n color: var(--bs-card-subtitle-color);\n}\n\n.card-text:last-child {\n margin-bottom: 0;\n}\n\n.card-link + .card-link {\n margin-left: var(--bs-card-spacer-x);\n}\n\n.card-header {\n padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n margin-bottom: 0;\n color: var(--bs-card-cap-color);\n background-color: var(--bs-card-cap-bg);\n border-bottom: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-header:first-child {\n border-radius: var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius) 0 0;\n}\n\n.card-footer {\n padding: var(--bs-card-cap-padding-y) var(--bs-card-cap-padding-x);\n color: var(--bs-card-cap-color);\n background-color: var(--bs-card-cap-bg);\n border-top: var(--bs-card-border-width) solid var(--bs-card-border-color);\n}\n.card-footer:last-child {\n border-radius: 0 0 var(--bs-card-inner-border-radius) var(--bs-card-inner-border-radius);\n}\n\n.card-header-tabs {\n margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n margin-bottom: calc(-1 * var(--bs-card-cap-padding-y));\n margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n border-bottom: 0;\n}\n.card-header-tabs .nav-link.active {\n background-color: var(--bs-card-bg);\n border-bottom-color: var(--bs-card-bg);\n}\n\n.card-header-pills {\n margin-right: calc(-0.5 * var(--bs-card-cap-padding-x));\n margin-left: calc(-0.5 * var(--bs-card-cap-padding-x));\n}\n\n.card-img-overlay {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n padding: var(--bs-card-img-overlay-padding);\n border-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-top,\n.card-img-bottom {\n width: 100%;\n}\n\n.card-img,\n.card-img-top {\n border-top-left-radius: var(--bs-card-inner-border-radius);\n border-top-right-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-img,\n.card-img-bottom {\n border-bottom-right-radius: var(--bs-card-inner-border-radius);\n border-bottom-left-radius: var(--bs-card-inner-border-radius);\n}\n\n.card-group > .card {\n margin-bottom: var(--bs-card-group-margin);\n}\n@media (min-width: 576px) {\n .card-group {\n display: flex;\n flex-flow: row wrap;\n }\n .card-group > .card {\n flex: 1 0 0%;\n margin-bottom: 0;\n }\n .card-group > .card + .card {\n margin-left: 0;\n border-left: 0;\n }\n .card-group > .card:not(:last-child) {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-top,\n .card-group > .card:not(:last-child) .card-header {\n border-top-right-radius: 0;\n }\n .card-group > .card:not(:last-child) .card-img-bottom,\n .card-group > .card:not(:last-child) .card-footer {\n border-bottom-right-radius: 0;\n }\n .card-group > .card:not(:first-child) {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-top,\n .card-group > .card:not(:first-child) .card-header {\n border-top-left-radius: 0;\n }\n .card-group > .card:not(:first-child) .card-img-bottom,\n .card-group > .card:not(:first-child) .card-footer {\n border-bottom-left-radius: 0;\n }\n}\n\n.accordion {\n --bs-accordion-color: var(--bs-body-color);\n --bs-accordion-bg: var(--bs-body-bg);\n --bs-accordion-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, border-radius 0.15s ease;\n --bs-accordion-border-color: var(--bs-border-color);\n --bs-accordion-border-width: var(--bs-border-width);\n --bs-accordion-border-radius: var(--bs-border-radius);\n --bs-accordion-inner-border-radius: calc(var(--bs-border-radius) - (var(--bs-border-width)));\n --bs-accordion-btn-padding-x: 1.25rem;\n --bs-accordion-btn-padding-y: 1rem;\n --bs-accordion-btn-color: var(--bs-body-color);\n --bs-accordion-btn-bg: var(--bs-accordion-bg);\n --bs-accordion-btn-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n --bs-accordion-btn-icon-width: 1.25rem;\n --bs-accordion-btn-icon-transform: rotate(-180deg);\n --bs-accordion-btn-icon-transition: transform 0.2s ease-in-out;\n --bs-accordion-btn-active-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23052c65'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n --bs-accordion-btn-focus-border-color: #86b7fe;\n --bs-accordion-btn-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n --bs-accordion-body-padding-x: 1.25rem;\n --bs-accordion-body-padding-y: 1rem;\n --bs-accordion-active-color: var(--bs-primary-text-emphasis);\n --bs-accordion-active-bg: var(--bs-primary-bg-subtle);\n}\n\n.accordion-button {\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n padding: var(--bs-accordion-btn-padding-y) var(--bs-accordion-btn-padding-x);\n font-size: 1rem;\n color: var(--bs-accordion-btn-color);\n text-align: left;\n background-color: var(--bs-accordion-btn-bg);\n border: 0;\n border-radius: 0;\n overflow-anchor: none;\n transition: var(--bs-accordion-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n .accordion-button {\n transition: none;\n }\n}\n.accordion-button:not(.collapsed) {\n color: var(--bs-accordion-active-color);\n background-color: var(--bs-accordion-active-bg);\n box-shadow: inset 0 calc(-1 * var(--bs-accordion-border-width)) 0 var(--bs-accordion-border-color);\n}\n.accordion-button:not(.collapsed)::after {\n background-image: var(--bs-accordion-btn-active-icon);\n transform: var(--bs-accordion-btn-icon-transform);\n}\n.accordion-button::after {\n flex-shrink: 0;\n width: var(--bs-accordion-btn-icon-width);\n height: var(--bs-accordion-btn-icon-width);\n margin-left: auto;\n content: \"\";\n background-image: var(--bs-accordion-btn-icon);\n background-repeat: no-repeat;\n background-size: var(--bs-accordion-btn-icon-width);\n transition: var(--bs-accordion-btn-icon-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n .accordion-button::after {\n transition: none;\n }\n}\n.accordion-button:hover {\n z-index: 2;\n}\n.accordion-button:focus {\n z-index: 3;\n border-color: var(--bs-accordion-btn-focus-border-color);\n outline: 0;\n box-shadow: var(--bs-accordion-btn-focus-box-shadow);\n}\n\n.accordion-header {\n margin-bottom: 0;\n}\n\n.accordion-item {\n color: var(--bs-accordion-color);\n background-color: var(--bs-accordion-bg);\n border: var(--bs-accordion-border-width) solid var(--bs-accordion-border-color);\n}\n.accordion-item:first-of-type {\n border-top-left-radius: var(--bs-accordion-border-radius);\n border-top-right-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:first-of-type .accordion-button {\n border-top-left-radius: var(--bs-accordion-inner-border-radius);\n border-top-right-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:not(:first-of-type) {\n border-top: 0;\n}\n.accordion-item:last-of-type {\n border-bottom-right-radius: var(--bs-accordion-border-radius);\n border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n.accordion-item:last-of-type .accordion-button.collapsed {\n border-bottom-right-radius: var(--bs-accordion-inner-border-radius);\n border-bottom-left-radius: var(--bs-accordion-inner-border-radius);\n}\n.accordion-item:last-of-type .accordion-collapse {\n border-bottom-right-radius: var(--bs-accordion-border-radius);\n border-bottom-left-radius: var(--bs-accordion-border-radius);\n}\n\n.accordion-body {\n padding: var(--bs-accordion-body-padding-y) var(--bs-accordion-body-padding-x);\n}\n\n.accordion-flush .accordion-collapse {\n border-width: 0;\n}\n.accordion-flush .accordion-item {\n border-right: 0;\n border-left: 0;\n border-radius: 0;\n}\n.accordion-flush .accordion-item:first-child {\n border-top: 0;\n}\n.accordion-flush .accordion-item:last-child {\n border-bottom: 0;\n}\n.accordion-flush .accordion-item .accordion-button, .accordion-flush .accordion-item .accordion-button.collapsed {\n border-radius: 0;\n}\n\n[data-bs-theme=dark] .accordion-button::after {\n --bs-accordion-btn-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n --bs-accordion-btn-active-icon: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236ea8fe'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n}\n\n.breadcrumb {\n --bs-breadcrumb-padding-x: 0;\n --bs-breadcrumb-padding-y: 0;\n --bs-breadcrumb-margin-bottom: 1rem;\n --bs-breadcrumb-bg: ;\n --bs-breadcrumb-border-radius: ;\n --bs-breadcrumb-divider-color: var(--bs-secondary-color);\n --bs-breadcrumb-item-padding-x: 0.5rem;\n --bs-breadcrumb-item-active-color: var(--bs-secondary-color);\n display: flex;\n flex-wrap: wrap;\n padding: var(--bs-breadcrumb-padding-y) var(--bs-breadcrumb-padding-x);\n margin-bottom: var(--bs-breadcrumb-margin-bottom);\n font-size: var(--bs-breadcrumb-font-size);\n list-style: none;\n background-color: var(--bs-breadcrumb-bg);\n border-radius: var(--bs-breadcrumb-border-radius);\n}\n\n.breadcrumb-item + .breadcrumb-item {\n padding-left: var(--bs-breadcrumb-item-padding-x);\n}\n.breadcrumb-item + .breadcrumb-item::before {\n float: left;\n padding-right: var(--bs-breadcrumb-item-padding-x);\n color: var(--bs-breadcrumb-divider-color);\n content: var(--bs-breadcrumb-divider, \"/\") /* rtl: var(--bs-breadcrumb-divider, \"/\") */;\n}\n.breadcrumb-item.active {\n color: var(--bs-breadcrumb-item-active-color);\n}\n\n.pagination {\n --bs-pagination-padding-x: 0.75rem;\n --bs-pagination-padding-y: 0.375rem;\n --bs-pagination-font-size: 1rem;\n --bs-pagination-color: var(--bs-link-color);\n --bs-pagination-bg: var(--bs-body-bg);\n --bs-pagination-border-width: var(--bs-border-width);\n --bs-pagination-border-color: var(--bs-border-color);\n --bs-pagination-border-radius: var(--bs-border-radius);\n --bs-pagination-hover-color: var(--bs-link-hover-color);\n --bs-pagination-hover-bg: var(--bs-tertiary-bg);\n --bs-pagination-hover-border-color: var(--bs-border-color);\n --bs-pagination-focus-color: var(--bs-link-hover-color);\n --bs-pagination-focus-bg: var(--bs-secondary-bg);\n --bs-pagination-focus-box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n --bs-pagination-active-color: #fff;\n --bs-pagination-active-bg: #0d6efd;\n --bs-pagination-active-border-color: #0d6efd;\n --bs-pagination-disabled-color: var(--bs-secondary-color);\n --bs-pagination-disabled-bg: var(--bs-secondary-bg);\n --bs-pagination-disabled-border-color: var(--bs-border-color);\n display: flex;\n padding-left: 0;\n list-style: none;\n}\n\n.page-link {\n position: relative;\n display: block;\n padding: var(--bs-pagination-padding-y) var(--bs-pagination-padding-x);\n font-size: var(--bs-pagination-font-size);\n color: var(--bs-pagination-color);\n text-decoration: none;\n background-color: var(--bs-pagination-bg);\n border: var(--bs-pagination-border-width) solid var(--bs-pagination-border-color);\n transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .page-link {\n transition: none;\n }\n}\n.page-link:hover {\n z-index: 2;\n color: var(--bs-pagination-hover-color);\n background-color: var(--bs-pagination-hover-bg);\n border-color: var(--bs-pagination-hover-border-color);\n}\n.page-link:focus {\n z-index: 3;\n color: var(--bs-pagination-focus-color);\n background-color: var(--bs-pagination-focus-bg);\n outline: 0;\n box-shadow: var(--bs-pagination-focus-box-shadow);\n}\n.page-link.active, .active > .page-link {\n z-index: 3;\n color: var(--bs-pagination-active-color);\n background-color: var(--bs-pagination-active-bg);\n border-color: var(--bs-pagination-active-border-color);\n}\n.page-link.disabled, .disabled > .page-link {\n color: var(--bs-pagination-disabled-color);\n pointer-events: none;\n background-color: var(--bs-pagination-disabled-bg);\n border-color: var(--bs-pagination-disabled-border-color);\n}\n\n.page-item:not(:first-child) .page-link {\n margin-left: calc(var(--bs-border-width) * -1);\n}\n.page-item:first-child .page-link {\n border-top-left-radius: var(--bs-pagination-border-radius);\n border-bottom-left-radius: var(--bs-pagination-border-radius);\n}\n.page-item:last-child .page-link {\n border-top-right-radius: var(--bs-pagination-border-radius);\n border-bottom-right-radius: var(--bs-pagination-border-radius);\n}\n\n.pagination-lg {\n --bs-pagination-padding-x: 1.5rem;\n --bs-pagination-padding-y: 0.75rem;\n --bs-pagination-font-size: 1.25rem;\n --bs-pagination-border-radius: var(--bs-border-radius-lg);\n}\n\n.pagination-sm {\n --bs-pagination-padding-x: 0.5rem;\n --bs-pagination-padding-y: 0.25rem;\n --bs-pagination-font-size: 0.875rem;\n --bs-pagination-border-radius: var(--bs-border-radius-sm);\n}\n\n.badge {\n --bs-badge-padding-x: 0.65em;\n --bs-badge-padding-y: 0.35em;\n --bs-badge-font-size: 0.75em;\n --bs-badge-font-weight: 700;\n --bs-badge-color: #fff;\n --bs-badge-border-radius: var(--bs-border-radius);\n display: inline-block;\n padding: var(--bs-badge-padding-y) var(--bs-badge-padding-x);\n font-size: var(--bs-badge-font-size);\n font-weight: var(--bs-badge-font-weight);\n line-height: 1;\n color: var(--bs-badge-color);\n text-align: center;\n white-space: nowrap;\n vertical-align: baseline;\n border-radius: var(--bs-badge-border-radius);\n}\n.badge:empty {\n display: none;\n}\n\n.btn .badge {\n position: relative;\n top: -1px;\n}\n\n.alert {\n --bs-alert-bg: transparent;\n --bs-alert-padding-x: 1rem;\n --bs-alert-padding-y: 1rem;\n --bs-alert-margin-bottom: 1rem;\n --bs-alert-color: inherit;\n --bs-alert-border-color: transparent;\n --bs-alert-border: var(--bs-border-width) solid var(--bs-alert-border-color);\n --bs-alert-border-radius: var(--bs-border-radius);\n --bs-alert-link-color: inherit;\n position: relative;\n padding: var(--bs-alert-padding-y) var(--bs-alert-padding-x);\n margin-bottom: var(--bs-alert-margin-bottom);\n color: var(--bs-alert-color);\n background-color: var(--bs-alert-bg);\n border: var(--bs-alert-border);\n border-radius: var(--bs-alert-border-radius);\n}\n\n.alert-heading {\n color: inherit;\n}\n\n.alert-link {\n font-weight: 700;\n color: var(--bs-alert-link-color);\n}\n\n.alert-dismissible {\n padding-right: 3rem;\n}\n.alert-dismissible .btn-close {\n position: absolute;\n top: 0;\n right: 0;\n z-index: 2;\n padding: 1.25rem 1rem;\n}\n\n.alert-primary {\n --bs-alert-color: var(--bs-primary-text-emphasis);\n --bs-alert-bg: var(--bs-primary-bg-subtle);\n --bs-alert-border-color: var(--bs-primary-border-subtle);\n --bs-alert-link-color: var(--bs-primary-text-emphasis);\n}\n\n.alert-secondary {\n --bs-alert-color: var(--bs-secondary-text-emphasis);\n --bs-alert-bg: var(--bs-secondary-bg-subtle);\n --bs-alert-border-color: var(--bs-secondary-border-subtle);\n --bs-alert-link-color: var(--bs-secondary-text-emphasis);\n}\n\n.alert-success {\n --bs-alert-color: var(--bs-success-text-emphasis);\n --bs-alert-bg: var(--bs-success-bg-subtle);\n --bs-alert-border-color: var(--bs-success-border-subtle);\n --bs-alert-link-color: var(--bs-success-text-emphasis);\n}\n\n.alert-info {\n --bs-alert-color: var(--bs-info-text-emphasis);\n --bs-alert-bg: var(--bs-info-bg-subtle);\n --bs-alert-border-color: var(--bs-info-border-subtle);\n --bs-alert-link-color: var(--bs-info-text-emphasis);\n}\n\n.alert-warning {\n --bs-alert-color: var(--bs-warning-text-emphasis);\n --bs-alert-bg: var(--bs-warning-bg-subtle);\n --bs-alert-border-color: var(--bs-warning-border-subtle);\n --bs-alert-link-color: var(--bs-warning-text-emphasis);\n}\n\n.alert-danger {\n --bs-alert-color: var(--bs-danger-text-emphasis);\n --bs-alert-bg: var(--bs-danger-bg-subtle);\n --bs-alert-border-color: var(--bs-danger-border-subtle);\n --bs-alert-link-color: var(--bs-danger-text-emphasis);\n}\n\n.alert-light {\n --bs-alert-color: var(--bs-light-text-emphasis);\n --bs-alert-bg: var(--bs-light-bg-subtle);\n --bs-alert-border-color: var(--bs-light-border-subtle);\n --bs-alert-link-color: var(--bs-light-text-emphasis);\n}\n\n.alert-dark {\n --bs-alert-color: var(--bs-dark-text-emphasis);\n --bs-alert-bg: var(--bs-dark-bg-subtle);\n --bs-alert-border-color: var(--bs-dark-border-subtle);\n --bs-alert-link-color: var(--bs-dark-text-emphasis);\n}\n\n@keyframes progress-bar-stripes {\n 0% {\n background-position-x: 1rem;\n }\n}\n.progress,\n.progress-stacked {\n --bs-progress-height: 1rem;\n --bs-progress-font-size: 0.75rem;\n --bs-progress-bg: var(--bs-secondary-bg);\n --bs-progress-border-radius: var(--bs-border-radius);\n --bs-progress-box-shadow: var(--bs-box-shadow-inset);\n --bs-progress-bar-color: #fff;\n --bs-progress-bar-bg: #0d6efd;\n --bs-progress-bar-transition: width 0.6s ease;\n display: flex;\n height: var(--bs-progress-height);\n overflow: hidden;\n font-size: var(--bs-progress-font-size);\n background-color: var(--bs-progress-bg);\n border-radius: var(--bs-progress-border-radius);\n}\n\n.progress-bar {\n display: flex;\n flex-direction: column;\n justify-content: center;\n overflow: hidden;\n color: var(--bs-progress-bar-color);\n text-align: center;\n white-space: nowrap;\n background-color: var(--bs-progress-bar-bg);\n transition: var(--bs-progress-bar-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n .progress-bar {\n transition: none;\n }\n}\n\n.progress-bar-striped {\n background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n background-size: var(--bs-progress-height) var(--bs-progress-height);\n}\n\n.progress-stacked > .progress {\n overflow: visible;\n}\n\n.progress-stacked > .progress > .progress-bar {\n width: 100%;\n}\n\n.progress-bar-animated {\n animation: 1s linear infinite progress-bar-stripes;\n}\n@media (prefers-reduced-motion: reduce) {\n .progress-bar-animated {\n animation: none;\n }\n}\n\n.list-group {\n --bs-list-group-color: var(--bs-body-color);\n --bs-list-group-bg: var(--bs-body-bg);\n --bs-list-group-border-color: var(--bs-border-color);\n --bs-list-group-border-width: var(--bs-border-width);\n --bs-list-group-border-radius: var(--bs-border-radius);\n --bs-list-group-item-padding-x: 1rem;\n --bs-list-group-item-padding-y: 0.5rem;\n --bs-list-group-action-color: var(--bs-secondary-color);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-tertiary-bg);\n --bs-list-group-action-active-color: var(--bs-body-color);\n --bs-list-group-action-active-bg: var(--bs-secondary-bg);\n --bs-list-group-disabled-color: var(--bs-secondary-color);\n --bs-list-group-disabled-bg: var(--bs-body-bg);\n --bs-list-group-active-color: #fff;\n --bs-list-group-active-bg: #0d6efd;\n --bs-list-group-active-border-color: #0d6efd;\n display: flex;\n flex-direction: column;\n padding-left: 0;\n margin-bottom: 0;\n border-radius: var(--bs-list-group-border-radius);\n}\n\n.list-group-numbered {\n list-style-type: none;\n counter-reset: section;\n}\n.list-group-numbered > .list-group-item::before {\n content: counters(section, \".\") \". \";\n counter-increment: section;\n}\n\n.list-group-item-action {\n width: 100%;\n color: var(--bs-list-group-action-color);\n text-align: inherit;\n}\n.list-group-item-action:hover, .list-group-item-action:focus {\n z-index: 1;\n color: var(--bs-list-group-action-hover-color);\n text-decoration: none;\n background-color: var(--bs-list-group-action-hover-bg);\n}\n.list-group-item-action:active {\n color: var(--bs-list-group-action-active-color);\n background-color: var(--bs-list-group-action-active-bg);\n}\n\n.list-group-item {\n position: relative;\n display: block;\n padding: var(--bs-list-group-item-padding-y) var(--bs-list-group-item-padding-x);\n color: var(--bs-list-group-color);\n text-decoration: none;\n background-color: var(--bs-list-group-bg);\n border: var(--bs-list-group-border-width) solid var(--bs-list-group-border-color);\n}\n.list-group-item:first-child {\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n}\n.list-group-item:last-child {\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n}\n.list-group-item.disabled, .list-group-item:disabled {\n color: var(--bs-list-group-disabled-color);\n pointer-events: none;\n background-color: var(--bs-list-group-disabled-bg);\n}\n.list-group-item.active {\n z-index: 2;\n color: var(--bs-list-group-active-color);\n background-color: var(--bs-list-group-active-bg);\n border-color: var(--bs-list-group-active-border-color);\n}\n.list-group-item + .list-group-item {\n border-top-width: 0;\n}\n.list-group-item + .list-group-item.active {\n margin-top: calc(-1 * var(--bs-list-group-border-width));\n border-top-width: var(--bs-list-group-border-width);\n}\n\n.list-group-horizontal {\n flex-direction: row;\n}\n.list-group-horizontal > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n}\n.list-group-horizontal > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n}\n.list-group-horizontal > .list-group-item.active {\n margin-top: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n}\n.list-group-horizontal > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n}\n\n@media (min-width: 576px) {\n .list-group-horizontal-sm {\n flex-direction: row;\n }\n .list-group-horizontal-sm > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-sm > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n }\n .list-group-horizontal-sm > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n }\n}\n@media (min-width: 768px) {\n .list-group-horizontal-md {\n flex-direction: row;\n }\n .list-group-horizontal-md > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-md > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n }\n .list-group-horizontal-md > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n }\n}\n@media (min-width: 992px) {\n .list-group-horizontal-lg {\n flex-direction: row;\n }\n .list-group-horizontal-lg > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-lg > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n }\n .list-group-horizontal-lg > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n }\n}\n@media (min-width: 1200px) {\n .list-group-horizontal-xl {\n flex-direction: row;\n }\n .list-group-horizontal-xl > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n }\n .list-group-horizontal-xl > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n }\n}\n@media (min-width: 1400px) {\n .list-group-horizontal-xxl {\n flex-direction: row;\n }\n .list-group-horizontal-xxl > .list-group-item:first-child:not(:last-child) {\n border-bottom-left-radius: var(--bs-list-group-border-radius);\n border-top-right-radius: 0;\n }\n .list-group-horizontal-xxl > .list-group-item:last-child:not(:first-child) {\n border-top-right-radius: var(--bs-list-group-border-radius);\n border-bottom-left-radius: 0;\n }\n .list-group-horizontal-xxl > .list-group-item.active {\n margin-top: 0;\n }\n .list-group-horizontal-xxl > .list-group-item + .list-group-item {\n border-top-width: var(--bs-list-group-border-width);\n border-left-width: 0;\n }\n .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {\n margin-left: calc(-1 * var(--bs-list-group-border-width));\n border-left-width: var(--bs-list-group-border-width);\n }\n}\n.list-group-flush {\n border-radius: 0;\n}\n.list-group-flush > .list-group-item {\n border-width: 0 0 var(--bs-list-group-border-width);\n}\n.list-group-flush > .list-group-item:last-child {\n border-bottom-width: 0;\n}\n\n.list-group-item-primary {\n --bs-list-group-color: var(--bs-primary-text-emphasis);\n --bs-list-group-bg: var(--bs-primary-bg-subtle);\n --bs-list-group-border-color: var(--bs-primary-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-primary-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-primary-border-subtle);\n --bs-list-group-active-color: var(--bs-primary-bg-subtle);\n --bs-list-group-active-bg: var(--bs-primary-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-primary-text-emphasis);\n}\n\n.list-group-item-secondary {\n --bs-list-group-color: var(--bs-secondary-text-emphasis);\n --bs-list-group-bg: var(--bs-secondary-bg-subtle);\n --bs-list-group-border-color: var(--bs-secondary-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-secondary-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-secondary-border-subtle);\n --bs-list-group-active-color: var(--bs-secondary-bg-subtle);\n --bs-list-group-active-bg: var(--bs-secondary-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-secondary-text-emphasis);\n}\n\n.list-group-item-success {\n --bs-list-group-color: var(--bs-success-text-emphasis);\n --bs-list-group-bg: var(--bs-success-bg-subtle);\n --bs-list-group-border-color: var(--bs-success-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-success-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-success-border-subtle);\n --bs-list-group-active-color: var(--bs-success-bg-subtle);\n --bs-list-group-active-bg: var(--bs-success-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-success-text-emphasis);\n}\n\n.list-group-item-info {\n --bs-list-group-color: var(--bs-info-text-emphasis);\n --bs-list-group-bg: var(--bs-info-bg-subtle);\n --bs-list-group-border-color: var(--bs-info-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-info-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-info-border-subtle);\n --bs-list-group-active-color: var(--bs-info-bg-subtle);\n --bs-list-group-active-bg: var(--bs-info-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-info-text-emphasis);\n}\n\n.list-group-item-warning {\n --bs-list-group-color: var(--bs-warning-text-emphasis);\n --bs-list-group-bg: var(--bs-warning-bg-subtle);\n --bs-list-group-border-color: var(--bs-warning-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-warning-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-warning-border-subtle);\n --bs-list-group-active-color: var(--bs-warning-bg-subtle);\n --bs-list-group-active-bg: var(--bs-warning-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-warning-text-emphasis);\n}\n\n.list-group-item-danger {\n --bs-list-group-color: var(--bs-danger-text-emphasis);\n --bs-list-group-bg: var(--bs-danger-bg-subtle);\n --bs-list-group-border-color: var(--bs-danger-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-danger-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-danger-border-subtle);\n --bs-list-group-active-color: var(--bs-danger-bg-subtle);\n --bs-list-group-active-bg: var(--bs-danger-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-danger-text-emphasis);\n}\n\n.list-group-item-light {\n --bs-list-group-color: var(--bs-light-text-emphasis);\n --bs-list-group-bg: var(--bs-light-bg-subtle);\n --bs-list-group-border-color: var(--bs-light-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-light-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-light-border-subtle);\n --bs-list-group-active-color: var(--bs-light-bg-subtle);\n --bs-list-group-active-bg: var(--bs-light-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-light-text-emphasis);\n}\n\n.list-group-item-dark {\n --bs-list-group-color: var(--bs-dark-text-emphasis);\n --bs-list-group-bg: var(--bs-dark-bg-subtle);\n --bs-list-group-border-color: var(--bs-dark-border-subtle);\n --bs-list-group-action-hover-color: var(--bs-emphasis-color);\n --bs-list-group-action-hover-bg: var(--bs-dark-border-subtle);\n --bs-list-group-action-active-color: var(--bs-emphasis-color);\n --bs-list-group-action-active-bg: var(--bs-dark-border-subtle);\n --bs-list-group-active-color: var(--bs-dark-bg-subtle);\n --bs-list-group-active-bg: var(--bs-dark-text-emphasis);\n --bs-list-group-active-border-color: var(--bs-dark-text-emphasis);\n}\n\n.btn-close {\n --bs-btn-close-color: #000;\n --bs-btn-close-bg: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 0 1 1.414 0L8 6.586 14.293.293a1 1 0 1 1 1.414 1.414L9.414 8l6.293 6.293a1 1 0 0 1-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L6.586 8 .293 1.707a1 1 0 0 1 0-1.414z'/%3e%3c/svg%3e\");\n --bs-btn-close-opacity: 0.5;\n --bs-btn-close-hover-opacity: 0.75;\n --bs-btn-close-focus-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);\n --bs-btn-close-focus-opacity: 1;\n --bs-btn-close-disabled-opacity: 0.25;\n --bs-btn-close-white-filter: invert(1) grayscale(100%) brightness(200%);\n box-sizing: content-box;\n width: 1em;\n height: 1em;\n padding: 0.25em 0.25em;\n color: var(--bs-btn-close-color);\n background: transparent var(--bs-btn-close-bg) center/1em auto no-repeat;\n border: 0;\n border-radius: 0.375rem;\n opacity: var(--bs-btn-close-opacity);\n}\n.btn-close:hover {\n color: var(--bs-btn-close-color);\n text-decoration: none;\n opacity: var(--bs-btn-close-hover-opacity);\n}\n.btn-close:focus {\n outline: 0;\n box-shadow: var(--bs-btn-close-focus-shadow);\n opacity: var(--bs-btn-close-focus-opacity);\n}\n.btn-close:disabled, .btn-close.disabled {\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n opacity: var(--bs-btn-close-disabled-opacity);\n}\n\n.btn-close-white {\n filter: var(--bs-btn-close-white-filter);\n}\n\n[data-bs-theme=dark] .btn-close {\n filter: var(--bs-btn-close-white-filter);\n}\n\n.toast {\n --bs-toast-zindex: 1090;\n --bs-toast-padding-x: 0.75rem;\n --bs-toast-padding-y: 0.5rem;\n --bs-toast-spacing: 1.5rem;\n --bs-toast-max-width: 350px;\n --bs-toast-font-size: 0.875rem;\n --bs-toast-color: ;\n --bs-toast-bg: rgba(var(--bs-body-bg-rgb), 0.85);\n --bs-toast-border-width: var(--bs-border-width);\n --bs-toast-border-color: var(--bs-border-color-translucent);\n --bs-toast-border-radius: var(--bs-border-radius);\n --bs-toast-box-shadow: var(--bs-box-shadow);\n --bs-toast-header-color: var(--bs-secondary-color);\n --bs-toast-header-bg: rgba(var(--bs-body-bg-rgb), 0.85);\n --bs-toast-header-border-color: var(--bs-border-color-translucent);\n width: var(--bs-toast-max-width);\n max-width: 100%;\n font-size: var(--bs-toast-font-size);\n color: var(--bs-toast-color);\n pointer-events: auto;\n background-color: var(--bs-toast-bg);\n background-clip: padding-box;\n border: var(--bs-toast-border-width) solid var(--bs-toast-border-color);\n box-shadow: var(--bs-toast-box-shadow);\n border-radius: var(--bs-toast-border-radius);\n}\n.toast.showing {\n opacity: 0;\n}\n.toast:not(.show) {\n display: none;\n}\n\n.toast-container {\n --bs-toast-zindex: 1090;\n position: absolute;\n z-index: var(--bs-toast-zindex);\n width: -webkit-max-content;\n width: -moz-max-content;\n width: max-content;\n max-width: 100%;\n pointer-events: none;\n}\n.toast-container > :not(:last-child) {\n margin-bottom: var(--bs-toast-spacing);\n}\n\n.toast-header {\n display: flex;\n align-items: center;\n padding: var(--bs-toast-padding-y) var(--bs-toast-padding-x);\n color: var(--bs-toast-header-color);\n background-color: var(--bs-toast-header-bg);\n background-clip: padding-box;\n border-bottom: var(--bs-toast-border-width) solid var(--bs-toast-header-border-color);\n border-top-left-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n border-top-right-radius: calc(var(--bs-toast-border-radius) - var(--bs-toast-border-width));\n}\n.toast-header .btn-close {\n margin-right: calc(-0.5 * var(--bs-toast-padding-x));\n margin-left: var(--bs-toast-padding-x);\n}\n\n.toast-body {\n padding: var(--bs-toast-padding-x);\n word-wrap: break-word;\n}\n\n.modal {\n --bs-modal-zindex: 1055;\n --bs-modal-width: 500px;\n --bs-modal-padding: 1rem;\n --bs-modal-margin: 0.5rem;\n --bs-modal-color: ;\n --bs-modal-bg: var(--bs-body-bg);\n --bs-modal-border-color: var(--bs-border-color-translucent);\n --bs-modal-border-width: var(--bs-border-width);\n --bs-modal-border-radius: var(--bs-border-radius-lg);\n --bs-modal-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n --bs-modal-inner-border-radius: calc(var(--bs-border-radius-lg) - (var(--bs-border-width)));\n --bs-modal-header-padding-x: 1rem;\n --bs-modal-header-padding-y: 1rem;\n --bs-modal-header-padding: 1rem 1rem;\n --bs-modal-header-border-color: var(--bs-border-color);\n --bs-modal-header-border-width: var(--bs-border-width);\n --bs-modal-title-line-height: 1.5;\n --bs-modal-footer-gap: 0.5rem;\n --bs-modal-footer-bg: ;\n --bs-modal-footer-border-color: var(--bs-border-color);\n --bs-modal-footer-border-width: var(--bs-border-width);\n position: fixed;\n top: 0;\n left: 0;\n z-index: var(--bs-modal-zindex);\n display: none;\n width: 100%;\n height: 100%;\n overflow-x: hidden;\n overflow-y: auto;\n outline: 0;\n}\n\n.modal-dialog {\n position: relative;\n width: auto;\n margin: var(--bs-modal-margin);\n pointer-events: none;\n}\n.modal.fade .modal-dialog {\n transition: transform 0.3s ease-out;\n transform: translate(0, -50px);\n}\n@media (prefers-reduced-motion: reduce) {\n .modal.fade .modal-dialog {\n transition: none;\n }\n}\n.modal.show .modal-dialog {\n transform: none;\n}\n.modal.modal-static .modal-dialog {\n transform: scale(1.02);\n}\n\n.modal-dialog-scrollable {\n height: calc(100% - var(--bs-modal-margin) * 2);\n}\n.modal-dialog-scrollable .modal-content {\n max-height: 100%;\n overflow: hidden;\n}\n.modal-dialog-scrollable .modal-body {\n overflow-y: auto;\n}\n\n.modal-dialog-centered {\n display: flex;\n align-items: center;\n min-height: calc(100% - var(--bs-modal-margin) * 2);\n}\n\n.modal-content {\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n color: var(--bs-modal-color);\n pointer-events: auto;\n background-color: var(--bs-modal-bg);\n background-clip: padding-box;\n border: var(--bs-modal-border-width) solid var(--bs-modal-border-color);\n border-radius: var(--bs-modal-border-radius);\n outline: 0;\n}\n\n.modal-backdrop {\n --bs-backdrop-zindex: 1050;\n --bs-backdrop-bg: #000;\n --bs-backdrop-opacity: 0.5;\n position: fixed;\n top: 0;\n left: 0;\n z-index: var(--bs-backdrop-zindex);\n width: 100vw;\n height: 100vh;\n background-color: var(--bs-backdrop-bg);\n}\n.modal-backdrop.fade {\n opacity: 0;\n}\n.modal-backdrop.show {\n opacity: var(--bs-backdrop-opacity);\n}\n\n.modal-header {\n display: flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: space-between;\n padding: var(--bs-modal-header-padding);\n border-bottom: var(--bs-modal-header-border-width) solid var(--bs-modal-header-border-color);\n border-top-left-radius: var(--bs-modal-inner-border-radius);\n border-top-right-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-header .btn-close {\n padding: calc(var(--bs-modal-header-padding-y) * 0.5) calc(var(--bs-modal-header-padding-x) * 0.5);\n margin: calc(-0.5 * var(--bs-modal-header-padding-y)) calc(-0.5 * var(--bs-modal-header-padding-x)) calc(-0.5 * var(--bs-modal-header-padding-y)) auto;\n}\n\n.modal-title {\n margin-bottom: 0;\n line-height: var(--bs-modal-title-line-height);\n}\n\n.modal-body {\n position: relative;\n flex: 1 1 auto;\n padding: var(--bs-modal-padding);\n}\n\n.modal-footer {\n display: flex;\n flex-shrink: 0;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n padding: calc(var(--bs-modal-padding) - var(--bs-modal-footer-gap) * 0.5);\n background-color: var(--bs-modal-footer-bg);\n border-top: var(--bs-modal-footer-border-width) solid var(--bs-modal-footer-border-color);\n border-bottom-right-radius: var(--bs-modal-inner-border-radius);\n border-bottom-left-radius: var(--bs-modal-inner-border-radius);\n}\n.modal-footer > * {\n margin: calc(var(--bs-modal-footer-gap) * 0.5);\n}\n\n@media (min-width: 576px) {\n .modal {\n --bs-modal-margin: 1.75rem;\n --bs-modal-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n }\n .modal-dialog {\n max-width: var(--bs-modal-width);\n margin-right: auto;\n margin-left: auto;\n }\n .modal-sm {\n --bs-modal-width: 300px;\n }\n}\n@media (min-width: 992px) {\n .modal-lg,\n .modal-xl {\n --bs-modal-width: 800px;\n }\n}\n@media (min-width: 1200px) {\n .modal-xl {\n --bs-modal-width: 1140px;\n }\n}\n.modal-fullscreen {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n}\n.modal-fullscreen .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n}\n.modal-fullscreen .modal-header,\n.modal-fullscreen .modal-footer {\n border-radius: 0;\n}\n.modal-fullscreen .modal-body {\n overflow-y: auto;\n}\n\n@media (max-width: 575.98px) {\n .modal-fullscreen-sm-down {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n }\n .modal-fullscreen-sm-down .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n }\n .modal-fullscreen-sm-down .modal-header,\n .modal-fullscreen-sm-down .modal-footer {\n border-radius: 0;\n }\n .modal-fullscreen-sm-down .modal-body {\n overflow-y: auto;\n }\n}\n@media (max-width: 767.98px) {\n .modal-fullscreen-md-down {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n }\n .modal-fullscreen-md-down .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n }\n .modal-fullscreen-md-down .modal-header,\n .modal-fullscreen-md-down .modal-footer {\n border-radius: 0;\n }\n .modal-fullscreen-md-down .modal-body {\n overflow-y: auto;\n }\n}\n@media (max-width: 991.98px) {\n .modal-fullscreen-lg-down {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n }\n .modal-fullscreen-lg-down .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n }\n .modal-fullscreen-lg-down .modal-header,\n .modal-fullscreen-lg-down .modal-footer {\n border-radius: 0;\n }\n .modal-fullscreen-lg-down .modal-body {\n overflow-y: auto;\n }\n}\n@media (max-width: 1199.98px) {\n .modal-fullscreen-xl-down {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n }\n .modal-fullscreen-xl-down .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n }\n .modal-fullscreen-xl-down .modal-header,\n .modal-fullscreen-xl-down .modal-footer {\n border-radius: 0;\n }\n .modal-fullscreen-xl-down .modal-body {\n overflow-y: auto;\n }\n}\n@media (max-width: 1399.98px) {\n .modal-fullscreen-xxl-down {\n width: 100vw;\n max-width: none;\n height: 100%;\n margin: 0;\n }\n .modal-fullscreen-xxl-down .modal-content {\n height: 100%;\n border: 0;\n border-radius: 0;\n }\n .modal-fullscreen-xxl-down .modal-header,\n .modal-fullscreen-xxl-down .modal-footer {\n border-radius: 0;\n }\n .modal-fullscreen-xxl-down .modal-body {\n overflow-y: auto;\n }\n}\n.tooltip {\n --bs-tooltip-zindex: 1080;\n --bs-tooltip-max-width: 200px;\n --bs-tooltip-padding-x: 0.5rem;\n --bs-tooltip-padding-y: 0.25rem;\n --bs-tooltip-margin: ;\n --bs-tooltip-font-size: 0.875rem;\n --bs-tooltip-color: var(--bs-body-bg);\n --bs-tooltip-bg: var(--bs-emphasis-color);\n --bs-tooltip-border-radius: var(--bs-border-radius);\n --bs-tooltip-opacity: 0.9;\n --bs-tooltip-arrow-width: 0.8rem;\n --bs-tooltip-arrow-height: 0.4rem;\n z-index: var(--bs-tooltip-zindex);\n display: block;\n margin: var(--bs-tooltip-margin);\n font-family: var(--bs-font-sans-serif);\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n white-space: normal;\n word-spacing: normal;\n line-break: auto;\n font-size: var(--bs-tooltip-font-size);\n word-wrap: break-word;\n opacity: 0;\n}\n.tooltip.show {\n opacity: var(--bs-tooltip-opacity);\n}\n.tooltip .tooltip-arrow {\n display: block;\n width: var(--bs-tooltip-arrow-width);\n height: var(--bs-tooltip-arrow-height);\n}\n.tooltip .tooltip-arrow::before {\n position: absolute;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n}\n\n.bs-tooltip-top .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow {\n bottom: calc(-1 * var(--bs-tooltip-arrow-height));\n}\n.bs-tooltip-top .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before {\n top: -1px;\n border-width: var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n border-top-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-end .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow {\n left: calc(-1 * var(--bs-tooltip-arrow-height));\n width: var(--bs-tooltip-arrow-height);\n height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-end .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before {\n right: -1px;\n border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height) calc(var(--bs-tooltip-arrow-width) * 0.5) 0;\n border-right-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.bs-tooltip-bottom .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow {\n top: calc(-1 * var(--bs-tooltip-arrow-height));\n}\n.bs-tooltip-bottom .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before {\n bottom: -1px;\n border-width: 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n border-bottom-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-tooltip-start .tooltip-arrow, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow {\n right: calc(-1 * var(--bs-tooltip-arrow-height));\n width: var(--bs-tooltip-arrow-height);\n height: var(--bs-tooltip-arrow-width);\n}\n.bs-tooltip-start .tooltip-arrow::before, .bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before {\n left: -1px;\n border-width: calc(var(--bs-tooltip-arrow-width) * 0.5) 0 calc(var(--bs-tooltip-arrow-width) * 0.5) var(--bs-tooltip-arrow-height);\n border-left-color: var(--bs-tooltip-bg);\n}\n\n/* rtl:end:ignore */\n.tooltip-inner {\n max-width: var(--bs-tooltip-max-width);\n padding: var(--bs-tooltip-padding-y) var(--bs-tooltip-padding-x);\n color: var(--bs-tooltip-color);\n text-align: center;\n background-color: var(--bs-tooltip-bg);\n border-radius: var(--bs-tooltip-border-radius);\n}\n\n.popover {\n --bs-popover-zindex: 1070;\n --bs-popover-max-width: 276px;\n --bs-popover-font-size: 0.875rem;\n --bs-popover-bg: var(--bs-body-bg);\n --bs-popover-border-width: var(--bs-border-width);\n --bs-popover-border-color: var(--bs-border-color-translucent);\n --bs-popover-border-radius: var(--bs-border-radius-lg);\n --bs-popover-inner-border-radius: calc(var(--bs-border-radius-lg) - var(--bs-border-width));\n --bs-popover-box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);\n --bs-popover-header-padding-x: 1rem;\n --bs-popover-header-padding-y: 0.5rem;\n --bs-popover-header-font-size: 1rem;\n --bs-popover-header-color: inherit;\n --bs-popover-header-bg: var(--bs-secondary-bg);\n --bs-popover-body-padding-x: 1rem;\n --bs-popover-body-padding-y: 1rem;\n --bs-popover-body-color: var(--bs-body-color);\n --bs-popover-arrow-width: 1rem;\n --bs-popover-arrow-height: 0.5rem;\n --bs-popover-arrow-border: var(--bs-popover-border-color);\n z-index: var(--bs-popover-zindex);\n display: block;\n max-width: var(--bs-popover-max-width);\n font-family: var(--bs-font-sans-serif);\n font-style: normal;\n font-weight: 400;\n line-height: 1.5;\n text-align: left;\n text-align: start;\n text-decoration: none;\n text-shadow: none;\n text-transform: none;\n letter-spacing: normal;\n word-break: normal;\n white-space: normal;\n word-spacing: normal;\n line-break: auto;\n font-size: var(--bs-popover-font-size);\n word-wrap: break-word;\n background-color: var(--bs-popover-bg);\n background-clip: padding-box;\n border: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n border-radius: var(--bs-popover-border-radius);\n}\n.popover .popover-arrow {\n display: block;\n width: var(--bs-popover-arrow-width);\n height: var(--bs-popover-arrow-height);\n}\n.popover .popover-arrow::before, .popover .popover-arrow::after {\n position: absolute;\n display: block;\n content: \"\";\n border-color: transparent;\n border-style: solid;\n border-width: 0;\n}\n\n.bs-popover-top > .popover-arrow, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow {\n bottom: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before, .bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n border-width: var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-top > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::before {\n bottom: 0;\n border-top-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-top > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=top] > .popover-arrow::after {\n bottom: var(--bs-popover-border-width);\n border-top-color: var(--bs-popover-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-end > .popover-arrow, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow {\n left: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n width: var(--bs-popover-arrow-height);\n height: var(--bs-popover-arrow-width);\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before, .bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n border-width: calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height) calc(var(--bs-popover-arrow-width) * 0.5) 0;\n}\n.bs-popover-end > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::before {\n left: 0;\n border-right-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-end > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=right] > .popover-arrow::after {\n left: var(--bs-popover-border-width);\n border-right-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.bs-popover-bottom > .popover-arrow, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow {\n top: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before, .bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n border-width: 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-bottom > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::before {\n top: 0;\n border-bottom-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-bottom > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=bottom] > .popover-arrow::after {\n top: var(--bs-popover-border-width);\n border-bottom-color: var(--bs-popover-bg);\n}\n.bs-popover-bottom .popover-header::before, .bs-popover-auto[data-popper-placement^=bottom] .popover-header::before {\n position: absolute;\n top: 0;\n left: 50%;\n display: block;\n width: var(--bs-popover-arrow-width);\n margin-left: calc(-0.5 * var(--bs-popover-arrow-width));\n content: \"\";\n border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-header-bg);\n}\n\n/* rtl:begin:ignore */\n.bs-popover-start > .popover-arrow, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow {\n right: calc(-1 * (var(--bs-popover-arrow-height)) - var(--bs-popover-border-width));\n width: var(--bs-popover-arrow-height);\n height: var(--bs-popover-arrow-width);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before, .bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n border-width: calc(var(--bs-popover-arrow-width) * 0.5) 0 calc(var(--bs-popover-arrow-width) * 0.5) var(--bs-popover-arrow-height);\n}\n.bs-popover-start > .popover-arrow::before, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::before {\n right: 0;\n border-left-color: var(--bs-popover-arrow-border);\n}\n.bs-popover-start > .popover-arrow::after, .bs-popover-auto[data-popper-placement^=left] > .popover-arrow::after {\n right: var(--bs-popover-border-width);\n border-left-color: var(--bs-popover-bg);\n}\n\n/* rtl:end:ignore */\n.popover-header {\n padding: var(--bs-popover-header-padding-y) var(--bs-popover-header-padding-x);\n margin-bottom: 0;\n font-size: var(--bs-popover-header-font-size);\n color: var(--bs-popover-header-color);\n background-color: var(--bs-popover-header-bg);\n border-bottom: var(--bs-popover-border-width) solid var(--bs-popover-border-color);\n border-top-left-radius: var(--bs-popover-inner-border-radius);\n border-top-right-radius: var(--bs-popover-inner-border-radius);\n}\n.popover-header:empty {\n display: none;\n}\n\n.popover-body {\n padding: var(--bs-popover-body-padding-y) var(--bs-popover-body-padding-x);\n color: var(--bs-popover-body-color);\n}\n\n.carousel {\n position: relative;\n}\n\n.carousel.pointer-event {\n touch-action: pan-y;\n}\n\n.carousel-inner {\n position: relative;\n width: 100%;\n overflow: hidden;\n}\n.carousel-inner::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.carousel-item {\n position: relative;\n display: none;\n float: left;\n width: 100%;\n margin-right: -100%;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n transition: transform 0.6s ease-in-out;\n}\n@media (prefers-reduced-motion: reduce) {\n .carousel-item {\n transition: none;\n }\n}\n\n.carousel-item.active,\n.carousel-item-next,\n.carousel-item-prev {\n display: block;\n}\n\n.carousel-item-next:not(.carousel-item-start),\n.active.carousel-item-end {\n transform: translateX(100%);\n}\n\n.carousel-item-prev:not(.carousel-item-end),\n.active.carousel-item-start {\n transform: translateX(-100%);\n}\n\n.carousel-fade .carousel-item {\n opacity: 0;\n transition-property: opacity;\n transform: none;\n}\n.carousel-fade .carousel-item.active,\n.carousel-fade .carousel-item-next.carousel-item-start,\n.carousel-fade .carousel-item-prev.carousel-item-end {\n z-index: 1;\n opacity: 1;\n}\n.carousel-fade .active.carousel-item-start,\n.carousel-fade .active.carousel-item-end {\n z-index: 0;\n opacity: 0;\n transition: opacity 0s 0.6s;\n}\n@media (prefers-reduced-motion: reduce) {\n .carousel-fade .active.carousel-item-start,\n .carousel-fade .active.carousel-item-end {\n transition: none;\n }\n}\n\n.carousel-control-prev,\n.carousel-control-next {\n position: absolute;\n top: 0;\n bottom: 0;\n z-index: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 15%;\n padding: 0;\n color: #fff;\n text-align: center;\n background: none;\n border: 0;\n opacity: 0.5;\n transition: opacity 0.15s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n .carousel-control-prev,\n .carousel-control-next {\n transition: none;\n }\n}\n.carousel-control-prev:hover, .carousel-control-prev:focus,\n.carousel-control-next:hover,\n.carousel-control-next:focus {\n color: #fff;\n text-decoration: none;\n outline: 0;\n opacity: 0.9;\n}\n\n.carousel-control-prev {\n left: 0;\n}\n\n.carousel-control-next {\n right: 0;\n}\n\n.carousel-control-prev-icon,\n.carousel-control-next-icon {\n display: inline-block;\n width: 2rem;\n height: 2rem;\n background-repeat: no-repeat;\n background-position: 50%;\n background-size: 100% 100%;\n}\n\n/* rtl:options: {\n \"autoRename\": true,\n \"stringMap\":[ {\n \"name\" : \"prev-next\",\n \"search\" : \"prev\",\n \"replace\" : \"next\"\n } ]\n} */\n.carousel-control-prev-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e\");\n}\n\n.carousel-control-next-icon {\n background-image: url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e\");\n}\n\n.carousel-indicators {\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 2;\n display: flex;\n justify-content: center;\n padding: 0;\n margin-right: 15%;\n margin-bottom: 1rem;\n margin-left: 15%;\n}\n.carousel-indicators [data-bs-target] {\n box-sizing: content-box;\n flex: 0 1 auto;\n width: 30px;\n height: 3px;\n padding: 0;\n margin-right: 3px;\n margin-left: 3px;\n text-indent: -999px;\n cursor: pointer;\n background-color: #fff;\n background-clip: padding-box;\n border: 0;\n border-top: 10px solid transparent;\n border-bottom: 10px solid transparent;\n opacity: 0.5;\n transition: opacity 0.6s ease;\n}\n@media (prefers-reduced-motion: reduce) {\n .carousel-indicators [data-bs-target] {\n transition: none;\n }\n}\n.carousel-indicators .active {\n opacity: 1;\n}\n\n.carousel-caption {\n position: absolute;\n right: 15%;\n bottom: 1.25rem;\n left: 15%;\n padding-top: 1.25rem;\n padding-bottom: 1.25rem;\n color: #fff;\n text-align: center;\n}\n\n.carousel-dark .carousel-control-prev-icon,\n.carousel-dark .carousel-control-next-icon {\n filter: invert(1) grayscale(100);\n}\n.carousel-dark .carousel-indicators [data-bs-target] {\n background-color: #000;\n}\n.carousel-dark .carousel-caption {\n color: #000;\n}\n\n[data-bs-theme=dark] .carousel .carousel-control-prev-icon,\n[data-bs-theme=dark] .carousel .carousel-control-next-icon, [data-bs-theme=dark].carousel .carousel-control-prev-icon,\n[data-bs-theme=dark].carousel .carousel-control-next-icon {\n filter: invert(1) grayscale(100);\n}\n[data-bs-theme=dark] .carousel .carousel-indicators [data-bs-target], [data-bs-theme=dark].carousel .carousel-indicators [data-bs-target] {\n background-color: #000;\n}\n[data-bs-theme=dark] .carousel .carousel-caption, [data-bs-theme=dark].carousel .carousel-caption {\n color: #000;\n}\n\n.spinner-grow,\n.spinner-border {\n display: inline-block;\n width: var(--bs-spinner-width);\n height: var(--bs-spinner-height);\n vertical-align: var(--bs-spinner-vertical-align);\n border-radius: 50%;\n animation: var(--bs-spinner-animation-speed) linear infinite var(--bs-spinner-animation-name);\n}\n\n@keyframes spinner-border {\n to {\n transform: rotate(360deg) /* rtl:ignore */;\n }\n}\n.spinner-border {\n --bs-spinner-width: 2rem;\n --bs-spinner-height: 2rem;\n --bs-spinner-vertical-align: -0.125em;\n --bs-spinner-border-width: 0.25em;\n --bs-spinner-animation-speed: 0.75s;\n --bs-spinner-animation-name: spinner-border;\n border: var(--bs-spinner-border-width) solid currentcolor;\n border-right-color: transparent;\n}\n\n.spinner-border-sm {\n --bs-spinner-width: 1rem;\n --bs-spinner-height: 1rem;\n --bs-spinner-border-width: 0.2em;\n}\n\n@keyframes spinner-grow {\n 0% {\n transform: scale(0);\n }\n 50% {\n opacity: 1;\n transform: none;\n }\n}\n.spinner-grow {\n --bs-spinner-width: 2rem;\n --bs-spinner-height: 2rem;\n --bs-spinner-vertical-align: -0.125em;\n --bs-spinner-animation-speed: 0.75s;\n --bs-spinner-animation-name: spinner-grow;\n background-color: currentcolor;\n opacity: 0;\n}\n\n.spinner-grow-sm {\n --bs-spinner-width: 1rem;\n --bs-spinner-height: 1rem;\n}\n\n@media (prefers-reduced-motion: reduce) {\n .spinner-border,\n .spinner-grow {\n --bs-spinner-animation-speed: 1.5s;\n }\n}\n.offcanvas, .offcanvas-xxl, .offcanvas-xl, .offcanvas-lg, .offcanvas-md, .offcanvas-sm {\n --bs-offcanvas-zindex: 1045;\n --bs-offcanvas-width: 400px;\n --bs-offcanvas-height: 30vh;\n --bs-offcanvas-padding-x: 1rem;\n --bs-offcanvas-padding-y: 1rem;\n --bs-offcanvas-color: var(--bs-body-color);\n --bs-offcanvas-bg: var(--bs-body-bg);\n --bs-offcanvas-border-width: var(--bs-border-width);\n --bs-offcanvas-border-color: var(--bs-border-color-translucent);\n --bs-offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);\n --bs-offcanvas-transition: transform 0.3s ease-in-out;\n --bs-offcanvas-title-line-height: 1.5;\n}\n\n@media (max-width: 575.98px) {\n .offcanvas-sm {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n }\n}\n@media (max-width: 575.98px) and (prefers-reduced-motion: reduce) {\n .offcanvas-sm {\n transition: none;\n }\n}\n@media (max-width: 575.98px) {\n .offcanvas-sm.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n }\n .offcanvas-sm.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n }\n .offcanvas-sm.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n }\n .offcanvas-sm.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n }\n .offcanvas-sm.showing, .offcanvas-sm.show:not(.hiding) {\n transform: none;\n }\n .offcanvas-sm.showing, .offcanvas-sm.hiding, .offcanvas-sm.show {\n visibility: visible;\n }\n}\n@media (min-width: 576px) {\n .offcanvas-sm {\n --bs-offcanvas-height: auto;\n --bs-offcanvas-border-width: 0;\n background-color: transparent !important;\n }\n .offcanvas-sm .offcanvas-header {\n display: none;\n }\n .offcanvas-sm .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n background-color: transparent !important;\n }\n}\n\n@media (max-width: 767.98px) {\n .offcanvas-md {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n }\n}\n@media (max-width: 767.98px) and (prefers-reduced-motion: reduce) {\n .offcanvas-md {\n transition: none;\n }\n}\n@media (max-width: 767.98px) {\n .offcanvas-md.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n }\n .offcanvas-md.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n }\n .offcanvas-md.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n }\n .offcanvas-md.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n }\n .offcanvas-md.showing, .offcanvas-md.show:not(.hiding) {\n transform: none;\n }\n .offcanvas-md.showing, .offcanvas-md.hiding, .offcanvas-md.show {\n visibility: visible;\n }\n}\n@media (min-width: 768px) {\n .offcanvas-md {\n --bs-offcanvas-height: auto;\n --bs-offcanvas-border-width: 0;\n background-color: transparent !important;\n }\n .offcanvas-md .offcanvas-header {\n display: none;\n }\n .offcanvas-md .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n background-color: transparent !important;\n }\n}\n\n@media (max-width: 991.98px) {\n .offcanvas-lg {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n }\n}\n@media (max-width: 991.98px) and (prefers-reduced-motion: reduce) {\n .offcanvas-lg {\n transition: none;\n }\n}\n@media (max-width: 991.98px) {\n .offcanvas-lg.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n }\n .offcanvas-lg.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n }\n .offcanvas-lg.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n }\n .offcanvas-lg.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n }\n .offcanvas-lg.showing, .offcanvas-lg.show:not(.hiding) {\n transform: none;\n }\n .offcanvas-lg.showing, .offcanvas-lg.hiding, .offcanvas-lg.show {\n visibility: visible;\n }\n}\n@media (min-width: 992px) {\n .offcanvas-lg {\n --bs-offcanvas-height: auto;\n --bs-offcanvas-border-width: 0;\n background-color: transparent !important;\n }\n .offcanvas-lg .offcanvas-header {\n display: none;\n }\n .offcanvas-lg .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n background-color: transparent !important;\n }\n}\n\n@media (max-width: 1199.98px) {\n .offcanvas-xl {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n }\n}\n@media (max-width: 1199.98px) and (prefers-reduced-motion: reduce) {\n .offcanvas-xl {\n transition: none;\n }\n}\n@media (max-width: 1199.98px) {\n .offcanvas-xl.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n }\n .offcanvas-xl.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n }\n .offcanvas-xl.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n }\n .offcanvas-xl.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n }\n .offcanvas-xl.showing, .offcanvas-xl.show:not(.hiding) {\n transform: none;\n }\n .offcanvas-xl.showing, .offcanvas-xl.hiding, .offcanvas-xl.show {\n visibility: visible;\n }\n}\n@media (min-width: 1200px) {\n .offcanvas-xl {\n --bs-offcanvas-height: auto;\n --bs-offcanvas-border-width: 0;\n background-color: transparent !important;\n }\n .offcanvas-xl .offcanvas-header {\n display: none;\n }\n .offcanvas-xl .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n background-color: transparent !important;\n }\n}\n\n@media (max-width: 1399.98px) {\n .offcanvas-xxl {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n }\n}\n@media (max-width: 1399.98px) and (prefers-reduced-motion: reduce) {\n .offcanvas-xxl {\n transition: none;\n }\n}\n@media (max-width: 1399.98px) {\n .offcanvas-xxl.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n }\n .offcanvas-xxl.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n }\n .offcanvas-xxl.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n }\n .offcanvas-xxl.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n }\n .offcanvas-xxl.showing, .offcanvas-xxl.show:not(.hiding) {\n transform: none;\n }\n .offcanvas-xxl.showing, .offcanvas-xxl.hiding, .offcanvas-xxl.show {\n visibility: visible;\n }\n}\n@media (min-width: 1400px) {\n .offcanvas-xxl {\n --bs-offcanvas-height: auto;\n --bs-offcanvas-border-width: 0;\n background-color: transparent !important;\n }\n .offcanvas-xxl .offcanvas-header {\n display: none;\n }\n .offcanvas-xxl .offcanvas-body {\n display: flex;\n flex-grow: 0;\n padding: 0;\n overflow-y: visible;\n background-color: transparent !important;\n }\n}\n\n.offcanvas {\n position: fixed;\n bottom: 0;\n z-index: var(--bs-offcanvas-zindex);\n display: flex;\n flex-direction: column;\n max-width: 100%;\n color: var(--bs-offcanvas-color);\n visibility: hidden;\n background-color: var(--bs-offcanvas-bg);\n background-clip: padding-box;\n outline: 0;\n transition: var(--bs-offcanvas-transition);\n}\n@media (prefers-reduced-motion: reduce) {\n .offcanvas {\n transition: none;\n }\n}\n.offcanvas.offcanvas-start {\n top: 0;\n left: 0;\n width: var(--bs-offcanvas-width);\n border-right: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(-100%);\n}\n.offcanvas.offcanvas-end {\n top: 0;\n right: 0;\n width: var(--bs-offcanvas-width);\n border-left: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateX(100%);\n}\n.offcanvas.offcanvas-top {\n top: 0;\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-bottom: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(-100%);\n}\n.offcanvas.offcanvas-bottom {\n right: 0;\n left: 0;\n height: var(--bs-offcanvas-height);\n max-height: 100%;\n border-top: var(--bs-offcanvas-border-width) solid var(--bs-offcanvas-border-color);\n transform: translateY(100%);\n}\n.offcanvas.showing, .offcanvas.show:not(.hiding) {\n transform: none;\n}\n.offcanvas.showing, .offcanvas.hiding, .offcanvas.show {\n visibility: visible;\n}\n\n.offcanvas-backdrop {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1040;\n width: 100vw;\n height: 100vh;\n background-color: #000;\n}\n.offcanvas-backdrop.fade {\n opacity: 0;\n}\n.offcanvas-backdrop.show {\n opacity: 0.5;\n}\n\n.offcanvas-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n}\n.offcanvas-header .btn-close {\n padding: calc(var(--bs-offcanvas-padding-y) * 0.5) calc(var(--bs-offcanvas-padding-x) * 0.5);\n margin-top: calc(-0.5 * var(--bs-offcanvas-padding-y));\n margin-right: calc(-0.5 * var(--bs-offcanvas-padding-x));\n margin-bottom: calc(-0.5 * var(--bs-offcanvas-padding-y));\n}\n\n.offcanvas-title {\n margin-bottom: 0;\n line-height: var(--bs-offcanvas-title-line-height);\n}\n\n.offcanvas-body {\n flex-grow: 1;\n padding: var(--bs-offcanvas-padding-y) var(--bs-offcanvas-padding-x);\n overflow-y: auto;\n}\n\n.placeholder {\n display: inline-block;\n min-height: 1em;\n vertical-align: middle;\n cursor: wait;\n background-color: currentcolor;\n opacity: 0.5;\n}\n.placeholder.btn::before {\n display: inline-block;\n content: \"\";\n}\n\n.placeholder-xs {\n min-height: 0.6em;\n}\n\n.placeholder-sm {\n min-height: 0.8em;\n}\n\n.placeholder-lg {\n min-height: 1.2em;\n}\n\n.placeholder-glow .placeholder {\n animation: placeholder-glow 2s ease-in-out infinite;\n}\n\n@keyframes placeholder-glow {\n 50% {\n opacity: 0.2;\n }\n}\n.placeholder-wave {\n -webkit-mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n mask-image: linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);\n -webkit-mask-size: 200% 100%;\n mask-size: 200% 100%;\n animation: placeholder-wave 2s linear infinite;\n}\n\n@keyframes placeholder-wave {\n 100% {\n -webkit-mask-position: -200% 0%;\n mask-position: -200% 0%;\n }\n}\n.clearfix::after {\n display: block;\n clear: both;\n content: \"\";\n}\n\n.text-bg-primary {\n color: #fff !important;\n background-color: RGBA(13, 110, 253, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-secondary {\n color: #fff !important;\n background-color: RGBA(108, 117, 125, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-success {\n color: #fff !important;\n background-color: RGBA(25, 135, 84, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-info {\n color: #000 !important;\n background-color: RGBA(13, 202, 240, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-warning {\n color: #000 !important;\n background-color: RGBA(255, 193, 7, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-danger {\n color: #fff !important;\n background-color: RGBA(220, 53, 69, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-light {\n color: #000 !important;\n background-color: RGBA(248, 249, 250, var(--bs-bg-opacity, 1)) !important;\n}\n\n.text-bg-dark {\n color: #fff !important;\n background-color: RGBA(33, 37, 41, var(--bs-bg-opacity, 1)) !important;\n}\n\n.link-primary {\n color: RGBA(var(--bs-primary-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-primary-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-primary:hover, .link-primary:focus {\n color: RGBA(10, 88, 202, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(10, 88, 202, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(10, 88, 202, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-secondary {\n color: RGBA(var(--bs-secondary-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-secondary-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-secondary:hover, .link-secondary:focus {\n color: RGBA(86, 94, 100, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(86, 94, 100, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-success {\n color: RGBA(var(--bs-success-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-success-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-success:hover, .link-success:focus {\n color: RGBA(20, 108, 67, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(20, 108, 67, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(20, 108, 67, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-info {\n color: RGBA(var(--bs-info-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-info-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-info:hover, .link-info:focus {\n color: RGBA(61, 213, 243, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(61, 213, 243, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(61, 213, 243, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-warning {\n color: RGBA(var(--bs-warning-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-warning-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-warning:hover, .link-warning:focus {\n color: RGBA(255, 205, 57, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(255, 205, 57, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(255, 205, 57, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-danger {\n color: RGBA(var(--bs-danger-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-danger-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-danger:hover, .link-danger:focus {\n color: RGBA(176, 42, 55, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(176, 42, 55, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(176, 42, 55, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-light {\n color: RGBA(var(--bs-light-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-light-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-light:hover, .link-light:focus {\n color: RGBA(249, 250, 251, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(249, 250, 251, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-dark {\n color: RGBA(var(--bs-dark-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-dark-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-dark:hover, .link-dark:focus {\n color: RGBA(26, 30, 33, var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(26, 30, 33, var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-body-emphasis {\n color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 1)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n.link-body-emphasis:hover, .link-body-emphasis:focus {\n color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-opacity, 0.75)) !important;\n -webkit-text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important;\n text-decoration-color: RGBA(var(--bs-emphasis-color-rgb), var(--bs-link-underline-opacity, 0.75)) !important;\n}\n\n.focus-ring:focus {\n outline: 0;\n box-shadow: var(--bs-focus-ring-x, 0) var(--bs-focus-ring-y, 0) var(--bs-focus-ring-blur, 0) var(--bs-focus-ring-width) var(--bs-focus-ring-color);\n}\n\n.icon-link {\n display: inline-flex;\n gap: 0.375rem;\n align-items: center;\n -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));\n text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-opacity, 0.5));\n text-underline-offset: 0.25em;\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n}\n.icon-link > .bi {\n flex-shrink: 0;\n width: 1em;\n height: 1em;\n fill: currentcolor;\n transition: 0.2s ease-in-out transform;\n}\n@media (prefers-reduced-motion: reduce) {\n .icon-link > .bi {\n transition: none;\n }\n}\n\n.icon-link-hover:hover > .bi, .icon-link-hover:focus-visible > .bi {\n transform: var(--bs-icon-link-transform, translate3d(0.25em, 0, 0));\n}\n\n.ratio {\n position: relative;\n width: 100%;\n}\n.ratio::before {\n display: block;\n padding-top: var(--bs-aspect-ratio);\n content: \"\";\n}\n.ratio > * {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n}\n\n.ratio-1x1 {\n --bs-aspect-ratio: 100%;\n}\n\n.ratio-4x3 {\n --bs-aspect-ratio: 75%;\n}\n\n.ratio-16x9 {\n --bs-aspect-ratio: 56.25%;\n}\n\n.ratio-21x9 {\n --bs-aspect-ratio: 42.8571428571%;\n}\n\n.fixed-top {\n position: fixed;\n top: 0;\n right: 0;\n left: 0;\n z-index: 1030;\n}\n\n.fixed-bottom {\n position: fixed;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1030;\n}\n\n.sticky-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n}\n\n.sticky-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n}\n\n@media (min-width: 576px) {\n .sticky-sm-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n .sticky-sm-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n }\n}\n@media (min-width: 768px) {\n .sticky-md-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n .sticky-md-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n }\n}\n@media (min-width: 992px) {\n .sticky-lg-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n .sticky-lg-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n }\n}\n@media (min-width: 1200px) {\n .sticky-xl-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n .sticky-xl-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n }\n}\n@media (min-width: 1400px) {\n .sticky-xxl-top {\n position: -webkit-sticky;\n position: sticky;\n top: 0;\n z-index: 1020;\n }\n .sticky-xxl-bottom {\n position: -webkit-sticky;\n position: sticky;\n bottom: 0;\n z-index: 1020;\n }\n}\n.hstack {\n display: flex;\n flex-direction: row;\n align-items: center;\n align-self: stretch;\n}\n\n.vstack {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n align-self: stretch;\n}\n\n.visually-hidden,\n.visually-hidden-focusable:not(:focus):not(:focus-within) {\n width: 1px !important;\n height: 1px !important;\n padding: 0 !important;\n margin: -1px !important;\n overflow: hidden !important;\n clip: rect(0, 0, 0, 0) !important;\n white-space: nowrap !important;\n border: 0 !important;\n}\n.visually-hidden:not(caption),\n.visually-hidden-focusable:not(:focus):not(:focus-within):not(caption) {\n position: absolute !important;\n}\n\n.stretched-link::after {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: 1;\n content: \"\";\n}\n\n.text-truncate {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.vr {\n display: inline-block;\n align-self: stretch;\n width: 1px;\n min-height: 1em;\n background-color: currentcolor;\n opacity: 0.25;\n}\n\n.align-baseline {\n vertical-align: baseline !important;\n}\n\n.align-top {\n vertical-align: top !important;\n}\n\n.align-middle {\n vertical-align: middle !important;\n}\n\n.align-bottom {\n vertical-align: bottom !important;\n}\n\n.align-text-bottom {\n vertical-align: text-bottom !important;\n}\n\n.align-text-top {\n vertical-align: text-top !important;\n}\n\n.float-start {\n float: left !important;\n}\n\n.float-end {\n float: right !important;\n}\n\n.float-none {\n float: none !important;\n}\n\n.object-fit-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n}\n\n.object-fit-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n}\n\n.object-fit-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n}\n\n.object-fit-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n}\n\n.object-fit-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n}\n\n.opacity-0 {\n opacity: 0 !important;\n}\n\n.opacity-25 {\n opacity: 0.25 !important;\n}\n\n.opacity-50 {\n opacity: 0.5 !important;\n}\n\n.opacity-75 {\n opacity: 0.75 !important;\n}\n\n.opacity-100 {\n opacity: 1 !important;\n}\n\n.overflow-auto {\n overflow: auto !important;\n}\n\n.overflow-hidden {\n overflow: hidden !important;\n}\n\n.overflow-visible {\n overflow: visible !important;\n}\n\n.overflow-scroll {\n overflow: scroll !important;\n}\n\n.overflow-x-auto {\n overflow-x: auto !important;\n}\n\n.overflow-x-hidden {\n overflow-x: hidden !important;\n}\n\n.overflow-x-visible {\n overflow-x: visible !important;\n}\n\n.overflow-x-scroll {\n overflow-x: scroll !important;\n}\n\n.overflow-y-auto {\n overflow-y: auto !important;\n}\n\n.overflow-y-hidden {\n overflow-y: hidden !important;\n}\n\n.overflow-y-visible {\n overflow-y: visible !important;\n}\n\n.overflow-y-scroll {\n overflow-y: scroll !important;\n}\n\n.d-inline {\n display: inline !important;\n}\n\n.d-inline-block {\n display: inline-block !important;\n}\n\n.d-block {\n display: block !important;\n}\n\n.d-grid {\n display: grid !important;\n}\n\n.d-inline-grid {\n display: inline-grid !important;\n}\n\n.d-table {\n display: table !important;\n}\n\n.d-table-row {\n display: table-row !important;\n}\n\n.d-table-cell {\n display: table-cell !important;\n}\n\n.d-flex {\n display: flex !important;\n}\n\n.d-inline-flex {\n display: inline-flex !important;\n}\n\n.d-none {\n display: none !important;\n}\n\n.shadow {\n box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;\n}\n\n.shadow-sm {\n box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;\n}\n\n.shadow-lg {\n box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;\n}\n\n.shadow-none {\n box-shadow: none !important;\n}\n\n.focus-ring-primary {\n --bs-focus-ring-color: rgba(var(--bs-primary-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-secondary {\n --bs-focus-ring-color: rgba(var(--bs-secondary-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-success {\n --bs-focus-ring-color: rgba(var(--bs-success-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-info {\n --bs-focus-ring-color: rgba(var(--bs-info-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-warning {\n --bs-focus-ring-color: rgba(var(--bs-warning-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-danger {\n --bs-focus-ring-color: rgba(var(--bs-danger-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-light {\n --bs-focus-ring-color: rgba(var(--bs-light-rgb), var(--bs-focus-ring-opacity));\n}\n\n.focus-ring-dark {\n --bs-focus-ring-color: rgba(var(--bs-dark-rgb), var(--bs-focus-ring-opacity));\n}\n\n.position-static {\n position: static !important;\n}\n\n.position-relative {\n position: relative !important;\n}\n\n.position-absolute {\n position: absolute !important;\n}\n\n.position-fixed {\n position: fixed !important;\n}\n\n.position-sticky {\n position: -webkit-sticky !important;\n position: sticky !important;\n}\n\n.top-0 {\n top: 0 !important;\n}\n\n.top-50 {\n top: 50% !important;\n}\n\n.top-100 {\n top: 100% !important;\n}\n\n.bottom-0 {\n bottom: 0 !important;\n}\n\n.bottom-50 {\n bottom: 50% !important;\n}\n\n.bottom-100 {\n bottom: 100% !important;\n}\n\n.start-0 {\n left: 0 !important;\n}\n\n.start-50 {\n left: 50% !important;\n}\n\n.start-100 {\n left: 100% !important;\n}\n\n.end-0 {\n right: 0 !important;\n}\n\n.end-50 {\n right: 50% !important;\n}\n\n.end-100 {\n right: 100% !important;\n}\n\n.translate-middle {\n transform: translate(-50%, -50%) !important;\n}\n\n.translate-middle-x {\n transform: translateX(-50%) !important;\n}\n\n.translate-middle-y {\n transform: translateY(-50%) !important;\n}\n\n.border {\n border: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-0 {\n border: 0 !important;\n}\n\n.border-top {\n border-top: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-top-0 {\n border-top: 0 !important;\n}\n\n.border-end {\n border-right: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-end-0 {\n border-right: 0 !important;\n}\n\n.border-bottom {\n border-bottom: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-bottom-0 {\n border-bottom: 0 !important;\n}\n\n.border-start {\n border-left: var(--bs-border-width) var(--bs-border-style) var(--bs-border-color) !important;\n}\n\n.border-start-0 {\n border-left: 0 !important;\n}\n\n.border-primary {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-primary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-secondary {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-secondary-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-success {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-success-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-info {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-info-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-warning {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-warning-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-danger {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-danger-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-light {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-light-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-dark {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-dark-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-black {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-black-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-white {\n --bs-border-opacity: 1;\n border-color: rgba(var(--bs-white-rgb), var(--bs-border-opacity)) !important;\n}\n\n.border-primary-subtle {\n border-color: var(--bs-primary-border-subtle) !important;\n}\n\n.border-secondary-subtle {\n border-color: var(--bs-secondary-border-subtle) !important;\n}\n\n.border-success-subtle {\n border-color: var(--bs-success-border-subtle) !important;\n}\n\n.border-info-subtle {\n border-color: var(--bs-info-border-subtle) !important;\n}\n\n.border-warning-subtle {\n border-color: var(--bs-warning-border-subtle) !important;\n}\n\n.border-danger-subtle {\n border-color: var(--bs-danger-border-subtle) !important;\n}\n\n.border-light-subtle {\n border-color: var(--bs-light-border-subtle) !important;\n}\n\n.border-dark-subtle {\n border-color: var(--bs-dark-border-subtle) !important;\n}\n\n.border-1 {\n border-width: 1px !important;\n}\n\n.border-2 {\n border-width: 2px !important;\n}\n\n.border-3 {\n border-width: 3px !important;\n}\n\n.border-4 {\n border-width: 4px !important;\n}\n\n.border-5 {\n border-width: 5px !important;\n}\n\n.border-opacity-10 {\n --bs-border-opacity: 0.1;\n}\n\n.border-opacity-25 {\n --bs-border-opacity: 0.25;\n}\n\n.border-opacity-50 {\n --bs-border-opacity: 0.5;\n}\n\n.border-opacity-75 {\n --bs-border-opacity: 0.75;\n}\n\n.border-opacity-100 {\n --bs-border-opacity: 1;\n}\n\n.w-25 {\n width: 25% !important;\n}\n\n.w-50 {\n width: 50% !important;\n}\n\n.w-75 {\n width: 75% !important;\n}\n\n.w-100 {\n width: 100% !important;\n}\n\n.w-auto {\n width: auto !important;\n}\n\n.mw-100 {\n max-width: 100% !important;\n}\n\n.vw-100 {\n width: 100vw !important;\n}\n\n.min-vw-100 {\n min-width: 100vw !important;\n}\n\n.h-25 {\n height: 25% !important;\n}\n\n.h-50 {\n height: 50% !important;\n}\n\n.h-75 {\n height: 75% !important;\n}\n\n.h-100 {\n height: 100% !important;\n}\n\n.h-auto {\n height: auto !important;\n}\n\n.mh-100 {\n max-height: 100% !important;\n}\n\n.vh-100 {\n height: 100vh !important;\n}\n\n.min-vh-100 {\n min-height: 100vh !important;\n}\n\n.flex-fill {\n flex: 1 1 auto !important;\n}\n\n.flex-row {\n flex-direction: row !important;\n}\n\n.flex-column {\n flex-direction: column !important;\n}\n\n.flex-row-reverse {\n flex-direction: row-reverse !important;\n}\n\n.flex-column-reverse {\n flex-direction: column-reverse !important;\n}\n\n.flex-grow-0 {\n flex-grow: 0 !important;\n}\n\n.flex-grow-1 {\n flex-grow: 1 !important;\n}\n\n.flex-shrink-0 {\n flex-shrink: 0 !important;\n}\n\n.flex-shrink-1 {\n flex-shrink: 1 !important;\n}\n\n.flex-wrap {\n flex-wrap: wrap !important;\n}\n\n.flex-nowrap {\n flex-wrap: nowrap !important;\n}\n\n.flex-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n}\n\n.justify-content-start {\n justify-content: flex-start !important;\n}\n\n.justify-content-end {\n justify-content: flex-end !important;\n}\n\n.justify-content-center {\n justify-content: center !important;\n}\n\n.justify-content-between {\n justify-content: space-between !important;\n}\n\n.justify-content-around {\n justify-content: space-around !important;\n}\n\n.justify-content-evenly {\n justify-content: space-evenly !important;\n}\n\n.align-items-start {\n align-items: flex-start !important;\n}\n\n.align-items-end {\n align-items: flex-end !important;\n}\n\n.align-items-center {\n align-items: center !important;\n}\n\n.align-items-baseline {\n align-items: baseline !important;\n}\n\n.align-items-stretch {\n align-items: stretch !important;\n}\n\n.align-content-start {\n align-content: flex-start !important;\n}\n\n.align-content-end {\n align-content: flex-end !important;\n}\n\n.align-content-center {\n align-content: center !important;\n}\n\n.align-content-between {\n align-content: space-between !important;\n}\n\n.align-content-around {\n align-content: space-around !important;\n}\n\n.align-content-stretch {\n align-content: stretch !important;\n}\n\n.align-self-auto {\n align-self: auto !important;\n}\n\n.align-self-start {\n align-self: flex-start !important;\n}\n\n.align-self-end {\n align-self: flex-end !important;\n}\n\n.align-self-center {\n align-self: center !important;\n}\n\n.align-self-baseline {\n align-self: baseline !important;\n}\n\n.align-self-stretch {\n align-self: stretch !important;\n}\n\n.order-first {\n order: -1 !important;\n}\n\n.order-0 {\n order: 0 !important;\n}\n\n.order-1 {\n order: 1 !important;\n}\n\n.order-2 {\n order: 2 !important;\n}\n\n.order-3 {\n order: 3 !important;\n}\n\n.order-4 {\n order: 4 !important;\n}\n\n.order-5 {\n order: 5 !important;\n}\n\n.order-last {\n order: 6 !important;\n}\n\n.m-0 {\n margin: 0 !important;\n}\n\n.m-1 {\n margin: 0.25rem !important;\n}\n\n.m-2 {\n margin: 0.5rem !important;\n}\n\n.m-3 {\n margin: 1rem !important;\n}\n\n.m-4 {\n margin: 1.5rem !important;\n}\n\n.m-5 {\n margin: 3rem !important;\n}\n\n.m-auto {\n margin: auto !important;\n}\n\n.mx-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n}\n\n.mx-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n}\n\n.mx-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n}\n\n.mx-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n}\n\n.mx-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n}\n\n.mx-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n}\n\n.mx-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n}\n\n.my-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n}\n\n.my-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n}\n\n.my-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n}\n\n.my-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n}\n\n.my-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n}\n\n.my-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n}\n\n.my-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n}\n\n.mt-0 {\n margin-top: 0 !important;\n}\n\n.mt-1 {\n margin-top: 0.25rem !important;\n}\n\n.mt-2 {\n margin-top: 0.5rem !important;\n}\n\n.mt-3 {\n margin-top: 1rem !important;\n}\n\n.mt-4 {\n margin-top: 1.5rem !important;\n}\n\n.mt-5 {\n margin-top: 3rem !important;\n}\n\n.mt-auto {\n margin-top: auto !important;\n}\n\n.me-0 {\n margin-right: 0 !important;\n}\n\n.me-1 {\n margin-right: 0.25rem !important;\n}\n\n.me-2 {\n margin-right: 0.5rem !important;\n}\n\n.me-3 {\n margin-right: 1rem !important;\n}\n\n.me-4 {\n margin-right: 1.5rem !important;\n}\n\n.me-5 {\n margin-right: 3rem !important;\n}\n\n.me-auto {\n margin-right: auto !important;\n}\n\n.mb-0 {\n margin-bottom: 0 !important;\n}\n\n.mb-1 {\n margin-bottom: 0.25rem !important;\n}\n\n.mb-2 {\n margin-bottom: 0.5rem !important;\n}\n\n.mb-3 {\n margin-bottom: 1rem !important;\n}\n\n.mb-4 {\n margin-bottom: 1.5rem !important;\n}\n\n.mb-5 {\n margin-bottom: 3rem !important;\n}\n\n.mb-auto {\n margin-bottom: auto !important;\n}\n\n.ms-0 {\n margin-left: 0 !important;\n}\n\n.ms-1 {\n margin-left: 0.25rem !important;\n}\n\n.ms-2 {\n margin-left: 0.5rem !important;\n}\n\n.ms-3 {\n margin-left: 1rem !important;\n}\n\n.ms-4 {\n margin-left: 1.5rem !important;\n}\n\n.ms-5 {\n margin-left: 3rem !important;\n}\n\n.ms-auto {\n margin-left: auto !important;\n}\n\n.p-0 {\n padding: 0 !important;\n}\n\n.p-1 {\n padding: 0.25rem !important;\n}\n\n.p-2 {\n padding: 0.5rem !important;\n}\n\n.p-3 {\n padding: 1rem !important;\n}\n\n.p-4 {\n padding: 1.5rem !important;\n}\n\n.p-5 {\n padding: 3rem !important;\n}\n\n.px-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n}\n\n.px-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n}\n\n.px-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n}\n\n.px-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n}\n\n.px-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n}\n\n.px-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n}\n\n.py-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n}\n\n.py-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n}\n\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n\n.py-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n}\n\n.py-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n}\n\n.py-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n}\n\n.pt-0 {\n padding-top: 0 !important;\n}\n\n.pt-1 {\n padding-top: 0.25rem !important;\n}\n\n.pt-2 {\n padding-top: 0.5rem !important;\n}\n\n.pt-3 {\n padding-top: 1rem !important;\n}\n\n.pt-4 {\n padding-top: 1.5rem !important;\n}\n\n.pt-5 {\n padding-top: 3rem !important;\n}\n\n.pe-0 {\n padding-right: 0 !important;\n}\n\n.pe-1 {\n padding-right: 0.25rem !important;\n}\n\n.pe-2 {\n padding-right: 0.5rem !important;\n}\n\n.pe-3 {\n padding-right: 1rem !important;\n}\n\n.pe-4 {\n padding-right: 1.5rem !important;\n}\n\n.pe-5 {\n padding-right: 3rem !important;\n}\n\n.pb-0 {\n padding-bottom: 0 !important;\n}\n\n.pb-1 {\n padding-bottom: 0.25rem !important;\n}\n\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n\n.pb-3 {\n padding-bottom: 1rem !important;\n}\n\n.pb-4 {\n padding-bottom: 1.5rem !important;\n}\n\n.pb-5 {\n padding-bottom: 3rem !important;\n}\n\n.ps-0 {\n padding-left: 0 !important;\n}\n\n.ps-1 {\n padding-left: 0.25rem !important;\n}\n\n.ps-2 {\n padding-left: 0.5rem !important;\n}\n\n.ps-3 {\n padding-left: 1rem !important;\n}\n\n.ps-4 {\n padding-left: 1.5rem !important;\n}\n\n.ps-5 {\n padding-left: 3rem !important;\n}\n\n.gap-0 {\n gap: 0 !important;\n}\n\n.gap-1 {\n gap: 0.25rem !important;\n}\n\n.gap-2 {\n gap: 0.5rem !important;\n}\n\n.gap-3 {\n gap: 1rem !important;\n}\n\n.gap-4 {\n gap: 1.5rem !important;\n}\n\n.gap-5 {\n gap: 3rem !important;\n}\n\n.row-gap-0 {\n row-gap: 0 !important;\n}\n\n.row-gap-1 {\n row-gap: 0.25rem !important;\n}\n\n.row-gap-2 {\n row-gap: 0.5rem !important;\n}\n\n.row-gap-3 {\n row-gap: 1rem !important;\n}\n\n.row-gap-4 {\n row-gap: 1.5rem !important;\n}\n\n.row-gap-5 {\n row-gap: 3rem !important;\n}\n\n.column-gap-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n}\n\n.column-gap-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n}\n\n.column-gap-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n}\n\n.column-gap-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n}\n\n.column-gap-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n}\n\n.column-gap-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n}\n\n.font-monospace {\n font-family: var(--bs-font-monospace) !important;\n}\n\n.fs-1 {\n font-size: calc(1.375rem + 1.5vw) !important;\n}\n\n.fs-2 {\n font-size: calc(1.325rem + 0.9vw) !important;\n}\n\n.fs-3 {\n font-size: calc(1.3rem + 0.6vw) !important;\n}\n\n.fs-4 {\n font-size: calc(1.275rem + 0.3vw) !important;\n}\n\n.fs-5 {\n font-size: 1.25rem !important;\n}\n\n.fs-6 {\n font-size: 1rem !important;\n}\n\n.fst-italic {\n font-style: italic !important;\n}\n\n.fst-normal {\n font-style: normal !important;\n}\n\n.fw-lighter {\n font-weight: lighter !important;\n}\n\n.fw-light {\n font-weight: 300 !important;\n}\n\n.fw-normal {\n font-weight: 400 !important;\n}\n\n.fw-medium {\n font-weight: 500 !important;\n}\n\n.fw-semibold {\n font-weight: 600 !important;\n}\n\n.fw-bold {\n font-weight: 700 !important;\n}\n\n.fw-bolder {\n font-weight: bolder !important;\n}\n\n.lh-1 {\n line-height: 1 !important;\n}\n\n.lh-sm {\n line-height: 1.25 !important;\n}\n\n.lh-base {\n line-height: 1.5 !important;\n}\n\n.lh-lg {\n line-height: 2 !important;\n}\n\n.text-start {\n text-align: left !important;\n}\n\n.text-end {\n text-align: right !important;\n}\n\n.text-center {\n text-align: center !important;\n}\n\n.text-decoration-none {\n text-decoration: none !important;\n}\n\n.text-decoration-underline {\n text-decoration: underline !important;\n}\n\n.text-decoration-line-through {\n text-decoration: line-through !important;\n}\n\n.text-lowercase {\n text-transform: lowercase !important;\n}\n\n.text-uppercase {\n text-transform: uppercase !important;\n}\n\n.text-capitalize {\n text-transform: capitalize !important;\n}\n\n.text-wrap {\n white-space: normal !important;\n}\n\n.text-nowrap {\n white-space: nowrap !important;\n}\n\n/* rtl:begin:remove */\n.text-break {\n word-wrap: break-word !important;\n word-break: break-word !important;\n}\n\n/* rtl:end:remove */\n.text-primary {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-secondary {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-success {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-info {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-warning {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-danger {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-light {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-dark {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-black {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-white {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-body {\n --bs-text-opacity: 1;\n color: rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important;\n}\n\n.text-muted {\n --bs-text-opacity: 1;\n color: var(--bs-secondary-color) !important;\n}\n\n.text-black-50 {\n --bs-text-opacity: 1;\n color: rgba(0, 0, 0, 0.5) !important;\n}\n\n.text-white-50 {\n --bs-text-opacity: 1;\n color: rgba(255, 255, 255, 0.5) !important;\n}\n\n.text-body-secondary {\n --bs-text-opacity: 1;\n color: var(--bs-secondary-color) !important;\n}\n\n.text-body-tertiary {\n --bs-text-opacity: 1;\n color: var(--bs-tertiary-color) !important;\n}\n\n.text-body-emphasis {\n --bs-text-opacity: 1;\n color: var(--bs-emphasis-color) !important;\n}\n\n.text-reset {\n --bs-text-opacity: 1;\n color: inherit !important;\n}\n\n.text-opacity-25 {\n --bs-text-opacity: 0.25;\n}\n\n.text-opacity-50 {\n --bs-text-opacity: 0.5;\n}\n\n.text-opacity-75 {\n --bs-text-opacity: 0.75;\n}\n\n.text-opacity-100 {\n --bs-text-opacity: 1;\n}\n\n.text-primary-emphasis {\n color: var(--bs-primary-text-emphasis) !important;\n}\n\n.text-secondary-emphasis {\n color: var(--bs-secondary-text-emphasis) !important;\n}\n\n.text-success-emphasis {\n color: var(--bs-success-text-emphasis) !important;\n}\n\n.text-info-emphasis {\n color: var(--bs-info-text-emphasis) !important;\n}\n\n.text-warning-emphasis {\n color: var(--bs-warning-text-emphasis) !important;\n}\n\n.text-danger-emphasis {\n color: var(--bs-danger-text-emphasis) !important;\n}\n\n.text-light-emphasis {\n color: var(--bs-light-text-emphasis) !important;\n}\n\n.text-dark-emphasis {\n color: var(--bs-dark-text-emphasis) !important;\n}\n\n.link-opacity-10 {\n --bs-link-opacity: 0.1;\n}\n\n.link-opacity-10-hover:hover {\n --bs-link-opacity: 0.1;\n}\n\n.link-opacity-25 {\n --bs-link-opacity: 0.25;\n}\n\n.link-opacity-25-hover:hover {\n --bs-link-opacity: 0.25;\n}\n\n.link-opacity-50 {\n --bs-link-opacity: 0.5;\n}\n\n.link-opacity-50-hover:hover {\n --bs-link-opacity: 0.5;\n}\n\n.link-opacity-75 {\n --bs-link-opacity: 0.75;\n}\n\n.link-opacity-75-hover:hover {\n --bs-link-opacity: 0.75;\n}\n\n.link-opacity-100 {\n --bs-link-opacity: 1;\n}\n\n.link-opacity-100-hover:hover {\n --bs-link-opacity: 1;\n}\n\n.link-offset-1 {\n text-underline-offset: 0.125em !important;\n}\n\n.link-offset-1-hover:hover {\n text-underline-offset: 0.125em !important;\n}\n\n.link-offset-2 {\n text-underline-offset: 0.25em !important;\n}\n\n.link-offset-2-hover:hover {\n text-underline-offset: 0.25em !important;\n}\n\n.link-offset-3 {\n text-underline-offset: 0.375em !important;\n}\n\n.link-offset-3-hover:hover {\n text-underline-offset: 0.375em !important;\n}\n\n.link-underline-primary {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-primary-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-secondary {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-secondary-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-success {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-success-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-info {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-info-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-warning {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-warning-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-danger {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-danger-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-light {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-light-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline-dark {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important;\n text-decoration-color: rgba(var(--bs-dark-rgb), var(--bs-link-underline-opacity)) !important;\n}\n\n.link-underline {\n --bs-link-underline-opacity: 1;\n -webkit-text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important;\n text-decoration-color: rgba(var(--bs-link-color-rgb), var(--bs-link-underline-opacity, 1)) !important;\n}\n\n.link-underline-opacity-0 {\n --bs-link-underline-opacity: 0;\n}\n\n.link-underline-opacity-0-hover:hover {\n --bs-link-underline-opacity: 0;\n}\n\n.link-underline-opacity-10 {\n --bs-link-underline-opacity: 0.1;\n}\n\n.link-underline-opacity-10-hover:hover {\n --bs-link-underline-opacity: 0.1;\n}\n\n.link-underline-opacity-25 {\n --bs-link-underline-opacity: 0.25;\n}\n\n.link-underline-opacity-25-hover:hover {\n --bs-link-underline-opacity: 0.25;\n}\n\n.link-underline-opacity-50 {\n --bs-link-underline-opacity: 0.5;\n}\n\n.link-underline-opacity-50-hover:hover {\n --bs-link-underline-opacity: 0.5;\n}\n\n.link-underline-opacity-75 {\n --bs-link-underline-opacity: 0.75;\n}\n\n.link-underline-opacity-75-hover:hover {\n --bs-link-underline-opacity: 0.75;\n}\n\n.link-underline-opacity-100 {\n --bs-link-underline-opacity: 1;\n}\n\n.link-underline-opacity-100-hover:hover {\n --bs-link-underline-opacity: 1;\n}\n\n.bg-primary {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-secondary {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-success {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-info {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-warning {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-danger {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-light {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-dark {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-black {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-white {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-transparent {\n --bs-bg-opacity: 1;\n background-color: transparent !important;\n}\n\n.bg-body-secondary {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-secondary-bg-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-body-tertiary {\n --bs-bg-opacity: 1;\n background-color: rgba(var(--bs-tertiary-bg-rgb), var(--bs-bg-opacity)) !important;\n}\n\n.bg-opacity-10 {\n --bs-bg-opacity: 0.1;\n}\n\n.bg-opacity-25 {\n --bs-bg-opacity: 0.25;\n}\n\n.bg-opacity-50 {\n --bs-bg-opacity: 0.5;\n}\n\n.bg-opacity-75 {\n --bs-bg-opacity: 0.75;\n}\n\n.bg-opacity-100 {\n --bs-bg-opacity: 1;\n}\n\n.bg-primary-subtle {\n background-color: var(--bs-primary-bg-subtle) !important;\n}\n\n.bg-secondary-subtle {\n background-color: var(--bs-secondary-bg-subtle) !important;\n}\n\n.bg-success-subtle {\n background-color: var(--bs-success-bg-subtle) !important;\n}\n\n.bg-info-subtle {\n background-color: var(--bs-info-bg-subtle) !important;\n}\n\n.bg-warning-subtle {\n background-color: var(--bs-warning-bg-subtle) !important;\n}\n\n.bg-danger-subtle {\n background-color: var(--bs-danger-bg-subtle) !important;\n}\n\n.bg-light-subtle {\n background-color: var(--bs-light-bg-subtle) !important;\n}\n\n.bg-dark-subtle {\n background-color: var(--bs-dark-bg-subtle) !important;\n}\n\n.bg-gradient {\n background-image: var(--bs-gradient) !important;\n}\n\n.user-select-all {\n -webkit-user-select: all !important;\n -moz-user-select: all !important;\n user-select: all !important;\n}\n\n.user-select-auto {\n -webkit-user-select: auto !important;\n -moz-user-select: auto !important;\n user-select: auto !important;\n}\n\n.user-select-none {\n -webkit-user-select: none !important;\n -moz-user-select: none !important;\n user-select: none !important;\n}\n\n.pe-none {\n pointer-events: none !important;\n}\n\n.pe-auto {\n pointer-events: auto !important;\n}\n\n.rounded {\n border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-0 {\n border-radius: 0 !important;\n}\n\n.rounded-1 {\n border-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-2 {\n border-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-3 {\n border-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-4 {\n border-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-5 {\n border-radius: var(--bs-border-radius-xxl) !important;\n}\n\n.rounded-circle {\n border-radius: 50% !important;\n}\n\n.rounded-pill {\n border-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-top {\n border-top-left-radius: var(--bs-border-radius) !important;\n border-top-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-top-0 {\n border-top-left-radius: 0 !important;\n border-top-right-radius: 0 !important;\n}\n\n.rounded-top-1 {\n border-top-left-radius: var(--bs-border-radius-sm) !important;\n border-top-right-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-top-2 {\n border-top-left-radius: var(--bs-border-radius) !important;\n border-top-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-top-3 {\n border-top-left-radius: var(--bs-border-radius-lg) !important;\n border-top-right-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-top-4 {\n border-top-left-radius: var(--bs-border-radius-xl) !important;\n border-top-right-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-top-5 {\n border-top-left-radius: var(--bs-border-radius-xxl) !important;\n border-top-right-radius: var(--bs-border-radius-xxl) !important;\n}\n\n.rounded-top-circle {\n border-top-left-radius: 50% !important;\n border-top-right-radius: 50% !important;\n}\n\n.rounded-top-pill {\n border-top-left-radius: var(--bs-border-radius-pill) !important;\n border-top-right-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-end {\n border-top-right-radius: var(--bs-border-radius) !important;\n border-bottom-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-end-0 {\n border-top-right-radius: 0 !important;\n border-bottom-right-radius: 0 !important;\n}\n\n.rounded-end-1 {\n border-top-right-radius: var(--bs-border-radius-sm) !important;\n border-bottom-right-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-end-2 {\n border-top-right-radius: var(--bs-border-radius) !important;\n border-bottom-right-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-end-3 {\n border-top-right-radius: var(--bs-border-radius-lg) !important;\n border-bottom-right-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-end-4 {\n border-top-right-radius: var(--bs-border-radius-xl) !important;\n border-bottom-right-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-end-5 {\n border-top-right-radius: var(--bs-border-radius-xxl) !important;\n border-bottom-right-radius: var(--bs-border-radius-xxl) !important;\n}\n\n.rounded-end-circle {\n border-top-right-radius: 50% !important;\n border-bottom-right-radius: 50% !important;\n}\n\n.rounded-end-pill {\n border-top-right-radius: var(--bs-border-radius-pill) !important;\n border-bottom-right-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-bottom {\n border-bottom-right-radius: var(--bs-border-radius) !important;\n border-bottom-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-bottom-0 {\n border-bottom-right-radius: 0 !important;\n border-bottom-left-radius: 0 !important;\n}\n\n.rounded-bottom-1 {\n border-bottom-right-radius: var(--bs-border-radius-sm) !important;\n border-bottom-left-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-bottom-2 {\n border-bottom-right-radius: var(--bs-border-radius) !important;\n border-bottom-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-bottom-3 {\n border-bottom-right-radius: var(--bs-border-radius-lg) !important;\n border-bottom-left-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-bottom-4 {\n border-bottom-right-radius: var(--bs-border-radius-xl) !important;\n border-bottom-left-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-bottom-5 {\n border-bottom-right-radius: var(--bs-border-radius-xxl) !important;\n border-bottom-left-radius: var(--bs-border-radius-xxl) !important;\n}\n\n.rounded-bottom-circle {\n border-bottom-right-radius: 50% !important;\n border-bottom-left-radius: 50% !important;\n}\n\n.rounded-bottom-pill {\n border-bottom-right-radius: var(--bs-border-radius-pill) !important;\n border-bottom-left-radius: var(--bs-border-radius-pill) !important;\n}\n\n.rounded-start {\n border-bottom-left-radius: var(--bs-border-radius) !important;\n border-top-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-start-0 {\n border-bottom-left-radius: 0 !important;\n border-top-left-radius: 0 !important;\n}\n\n.rounded-start-1 {\n border-bottom-left-radius: var(--bs-border-radius-sm) !important;\n border-top-left-radius: var(--bs-border-radius-sm) !important;\n}\n\n.rounded-start-2 {\n border-bottom-left-radius: var(--bs-border-radius) !important;\n border-top-left-radius: var(--bs-border-radius) !important;\n}\n\n.rounded-start-3 {\n border-bottom-left-radius: var(--bs-border-radius-lg) !important;\n border-top-left-radius: var(--bs-border-radius-lg) !important;\n}\n\n.rounded-start-4 {\n border-bottom-left-radius: var(--bs-border-radius-xl) !important;\n border-top-left-radius: var(--bs-border-radius-xl) !important;\n}\n\n.rounded-start-5 {\n border-bottom-left-radius: var(--bs-border-radius-xxl) !important;\n border-top-left-radius: var(--bs-border-radius-xxl) !important;\n}\n\n.rounded-start-circle {\n border-bottom-left-radius: 50% !important;\n border-top-left-radius: 50% !important;\n}\n\n.rounded-start-pill {\n border-bottom-left-radius: var(--bs-border-radius-pill) !important;\n border-top-left-radius: var(--bs-border-radius-pill) !important;\n}\n\n.visible {\n visibility: visible !important;\n}\n\n.invisible {\n visibility: hidden !important;\n}\n\n.z-n1 {\n z-index: -1 !important;\n}\n\n.z-0 {\n z-index: 0 !important;\n}\n\n.z-1 {\n z-index: 1 !important;\n}\n\n.z-2 {\n z-index: 2 !important;\n}\n\n.z-3 {\n z-index: 3 !important;\n}\n\n@media (min-width: 576px) {\n .float-sm-start {\n float: left !important;\n }\n .float-sm-end {\n float: right !important;\n }\n .float-sm-none {\n float: none !important;\n }\n .object-fit-sm-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n }\n .object-fit-sm-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n }\n .object-fit-sm-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n }\n .object-fit-sm-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n }\n .object-fit-sm-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n }\n .d-sm-inline {\n display: inline !important;\n }\n .d-sm-inline-block {\n display: inline-block !important;\n }\n .d-sm-block {\n display: block !important;\n }\n .d-sm-grid {\n display: grid !important;\n }\n .d-sm-inline-grid {\n display: inline-grid !important;\n }\n .d-sm-table {\n display: table !important;\n }\n .d-sm-table-row {\n display: table-row !important;\n }\n .d-sm-table-cell {\n display: table-cell !important;\n }\n .d-sm-flex {\n display: flex !important;\n }\n .d-sm-inline-flex {\n display: inline-flex !important;\n }\n .d-sm-none {\n display: none !important;\n }\n .flex-sm-fill {\n flex: 1 1 auto !important;\n }\n .flex-sm-row {\n flex-direction: row !important;\n }\n .flex-sm-column {\n flex-direction: column !important;\n }\n .flex-sm-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-sm-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-sm-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-sm-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-sm-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-sm-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-sm-wrap {\n flex-wrap: wrap !important;\n }\n .flex-sm-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-sm-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-sm-start {\n justify-content: flex-start !important;\n }\n .justify-content-sm-end {\n justify-content: flex-end !important;\n }\n .justify-content-sm-center {\n justify-content: center !important;\n }\n .justify-content-sm-between {\n justify-content: space-between !important;\n }\n .justify-content-sm-around {\n justify-content: space-around !important;\n }\n .justify-content-sm-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-sm-start {\n align-items: flex-start !important;\n }\n .align-items-sm-end {\n align-items: flex-end !important;\n }\n .align-items-sm-center {\n align-items: center !important;\n }\n .align-items-sm-baseline {\n align-items: baseline !important;\n }\n .align-items-sm-stretch {\n align-items: stretch !important;\n }\n .align-content-sm-start {\n align-content: flex-start !important;\n }\n .align-content-sm-end {\n align-content: flex-end !important;\n }\n .align-content-sm-center {\n align-content: center !important;\n }\n .align-content-sm-between {\n align-content: space-between !important;\n }\n .align-content-sm-around {\n align-content: space-around !important;\n }\n .align-content-sm-stretch {\n align-content: stretch !important;\n }\n .align-self-sm-auto {\n align-self: auto !important;\n }\n .align-self-sm-start {\n align-self: flex-start !important;\n }\n .align-self-sm-end {\n align-self: flex-end !important;\n }\n .align-self-sm-center {\n align-self: center !important;\n }\n .align-self-sm-baseline {\n align-self: baseline !important;\n }\n .align-self-sm-stretch {\n align-self: stretch !important;\n }\n .order-sm-first {\n order: -1 !important;\n }\n .order-sm-0 {\n order: 0 !important;\n }\n .order-sm-1 {\n order: 1 !important;\n }\n .order-sm-2 {\n order: 2 !important;\n }\n .order-sm-3 {\n order: 3 !important;\n }\n .order-sm-4 {\n order: 4 !important;\n }\n .order-sm-5 {\n order: 5 !important;\n }\n .order-sm-last {\n order: 6 !important;\n }\n .m-sm-0 {\n margin: 0 !important;\n }\n .m-sm-1 {\n margin: 0.25rem !important;\n }\n .m-sm-2 {\n margin: 0.5rem !important;\n }\n .m-sm-3 {\n margin: 1rem !important;\n }\n .m-sm-4 {\n margin: 1.5rem !important;\n }\n .m-sm-5 {\n margin: 3rem !important;\n }\n .m-sm-auto {\n margin: auto !important;\n }\n .mx-sm-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-sm-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-sm-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-sm-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-sm-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-sm-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-sm-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-sm-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-sm-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-sm-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-sm-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-sm-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-sm-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-sm-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-sm-0 {\n margin-top: 0 !important;\n }\n .mt-sm-1 {\n margin-top: 0.25rem !important;\n }\n .mt-sm-2 {\n margin-top: 0.5rem !important;\n }\n .mt-sm-3 {\n margin-top: 1rem !important;\n }\n .mt-sm-4 {\n margin-top: 1.5rem !important;\n }\n .mt-sm-5 {\n margin-top: 3rem !important;\n }\n .mt-sm-auto {\n margin-top: auto !important;\n }\n .me-sm-0 {\n margin-right: 0 !important;\n }\n .me-sm-1 {\n margin-right: 0.25rem !important;\n }\n .me-sm-2 {\n margin-right: 0.5rem !important;\n }\n .me-sm-3 {\n margin-right: 1rem !important;\n }\n .me-sm-4 {\n margin-right: 1.5rem !important;\n }\n .me-sm-5 {\n margin-right: 3rem !important;\n }\n .me-sm-auto {\n margin-right: auto !important;\n }\n .mb-sm-0 {\n margin-bottom: 0 !important;\n }\n .mb-sm-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-sm-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-sm-3 {\n margin-bottom: 1rem !important;\n }\n .mb-sm-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-sm-5 {\n margin-bottom: 3rem !important;\n }\n .mb-sm-auto {\n margin-bottom: auto !important;\n }\n .ms-sm-0 {\n margin-left: 0 !important;\n }\n .ms-sm-1 {\n margin-left: 0.25rem !important;\n }\n .ms-sm-2 {\n margin-left: 0.5rem !important;\n }\n .ms-sm-3 {\n margin-left: 1rem !important;\n }\n .ms-sm-4 {\n margin-left: 1.5rem !important;\n }\n .ms-sm-5 {\n margin-left: 3rem !important;\n }\n .ms-sm-auto {\n margin-left: auto !important;\n }\n .p-sm-0 {\n padding: 0 !important;\n }\n .p-sm-1 {\n padding: 0.25rem !important;\n }\n .p-sm-2 {\n padding: 0.5rem !important;\n }\n .p-sm-3 {\n padding: 1rem !important;\n }\n .p-sm-4 {\n padding: 1.5rem !important;\n }\n .p-sm-5 {\n padding: 3rem !important;\n }\n .px-sm-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-sm-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-sm-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-sm-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-sm-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-sm-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-sm-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-sm-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-sm-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-sm-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-sm-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-sm-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-sm-0 {\n padding-top: 0 !important;\n }\n .pt-sm-1 {\n padding-top: 0.25rem !important;\n }\n .pt-sm-2 {\n padding-top: 0.5rem !important;\n }\n .pt-sm-3 {\n padding-top: 1rem !important;\n }\n .pt-sm-4 {\n padding-top: 1.5rem !important;\n }\n .pt-sm-5 {\n padding-top: 3rem !important;\n }\n .pe-sm-0 {\n padding-right: 0 !important;\n }\n .pe-sm-1 {\n padding-right: 0.25rem !important;\n }\n .pe-sm-2 {\n padding-right: 0.5rem !important;\n }\n .pe-sm-3 {\n padding-right: 1rem !important;\n }\n .pe-sm-4 {\n padding-right: 1.5rem !important;\n }\n .pe-sm-5 {\n padding-right: 3rem !important;\n }\n .pb-sm-0 {\n padding-bottom: 0 !important;\n }\n .pb-sm-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-sm-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-sm-3 {\n padding-bottom: 1rem !important;\n }\n .pb-sm-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-sm-5 {\n padding-bottom: 3rem !important;\n }\n .ps-sm-0 {\n padding-left: 0 !important;\n }\n .ps-sm-1 {\n padding-left: 0.25rem !important;\n }\n .ps-sm-2 {\n padding-left: 0.5rem !important;\n }\n .ps-sm-3 {\n padding-left: 1rem !important;\n }\n .ps-sm-4 {\n padding-left: 1.5rem !important;\n }\n .ps-sm-5 {\n padding-left: 3rem !important;\n }\n .gap-sm-0 {\n gap: 0 !important;\n }\n .gap-sm-1 {\n gap: 0.25rem !important;\n }\n .gap-sm-2 {\n gap: 0.5rem !important;\n }\n .gap-sm-3 {\n gap: 1rem !important;\n }\n .gap-sm-4 {\n gap: 1.5rem !important;\n }\n .gap-sm-5 {\n gap: 3rem !important;\n }\n .row-gap-sm-0 {\n row-gap: 0 !important;\n }\n .row-gap-sm-1 {\n row-gap: 0.25rem !important;\n }\n .row-gap-sm-2 {\n row-gap: 0.5rem !important;\n }\n .row-gap-sm-3 {\n row-gap: 1rem !important;\n }\n .row-gap-sm-4 {\n row-gap: 1.5rem !important;\n }\n .row-gap-sm-5 {\n row-gap: 3rem !important;\n }\n .column-gap-sm-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n }\n .column-gap-sm-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n }\n .column-gap-sm-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n }\n .column-gap-sm-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n }\n .column-gap-sm-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n }\n .column-gap-sm-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n }\n .text-sm-start {\n text-align: left !important;\n }\n .text-sm-end {\n text-align: right !important;\n }\n .text-sm-center {\n text-align: center !important;\n }\n}\n@media (min-width: 768px) {\n .float-md-start {\n float: left !important;\n }\n .float-md-end {\n float: right !important;\n }\n .float-md-none {\n float: none !important;\n }\n .object-fit-md-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n }\n .object-fit-md-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n }\n .object-fit-md-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n }\n .object-fit-md-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n }\n .object-fit-md-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n }\n .d-md-inline {\n display: inline !important;\n }\n .d-md-inline-block {\n display: inline-block !important;\n }\n .d-md-block {\n display: block !important;\n }\n .d-md-grid {\n display: grid !important;\n }\n .d-md-inline-grid {\n display: inline-grid !important;\n }\n .d-md-table {\n display: table !important;\n }\n .d-md-table-row {\n display: table-row !important;\n }\n .d-md-table-cell {\n display: table-cell !important;\n }\n .d-md-flex {\n display: flex !important;\n }\n .d-md-inline-flex {\n display: inline-flex !important;\n }\n .d-md-none {\n display: none !important;\n }\n .flex-md-fill {\n flex: 1 1 auto !important;\n }\n .flex-md-row {\n flex-direction: row !important;\n }\n .flex-md-column {\n flex-direction: column !important;\n }\n .flex-md-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-md-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-md-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-md-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-md-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-md-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-md-wrap {\n flex-wrap: wrap !important;\n }\n .flex-md-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-md-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-md-start {\n justify-content: flex-start !important;\n }\n .justify-content-md-end {\n justify-content: flex-end !important;\n }\n .justify-content-md-center {\n justify-content: center !important;\n }\n .justify-content-md-between {\n justify-content: space-between !important;\n }\n .justify-content-md-around {\n justify-content: space-around !important;\n }\n .justify-content-md-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-md-start {\n align-items: flex-start !important;\n }\n .align-items-md-end {\n align-items: flex-end !important;\n }\n .align-items-md-center {\n align-items: center !important;\n }\n .align-items-md-baseline {\n align-items: baseline !important;\n }\n .align-items-md-stretch {\n align-items: stretch !important;\n }\n .align-content-md-start {\n align-content: flex-start !important;\n }\n .align-content-md-end {\n align-content: flex-end !important;\n }\n .align-content-md-center {\n align-content: center !important;\n }\n .align-content-md-between {\n align-content: space-between !important;\n }\n .align-content-md-around {\n align-content: space-around !important;\n }\n .align-content-md-stretch {\n align-content: stretch !important;\n }\n .align-self-md-auto {\n align-self: auto !important;\n }\n .align-self-md-start {\n align-self: flex-start !important;\n }\n .align-self-md-end {\n align-self: flex-end !important;\n }\n .align-self-md-center {\n align-self: center !important;\n }\n .align-self-md-baseline {\n align-self: baseline !important;\n }\n .align-self-md-stretch {\n align-self: stretch !important;\n }\n .order-md-first {\n order: -1 !important;\n }\n .order-md-0 {\n order: 0 !important;\n }\n .order-md-1 {\n order: 1 !important;\n }\n .order-md-2 {\n order: 2 !important;\n }\n .order-md-3 {\n order: 3 !important;\n }\n .order-md-4 {\n order: 4 !important;\n }\n .order-md-5 {\n order: 5 !important;\n }\n .order-md-last {\n order: 6 !important;\n }\n .m-md-0 {\n margin: 0 !important;\n }\n .m-md-1 {\n margin: 0.25rem !important;\n }\n .m-md-2 {\n margin: 0.5rem !important;\n }\n .m-md-3 {\n margin: 1rem !important;\n }\n .m-md-4 {\n margin: 1.5rem !important;\n }\n .m-md-5 {\n margin: 3rem !important;\n }\n .m-md-auto {\n margin: auto !important;\n }\n .mx-md-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-md-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-md-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-md-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-md-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-md-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-md-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-md-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-md-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-md-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-md-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-md-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-md-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-md-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-md-0 {\n margin-top: 0 !important;\n }\n .mt-md-1 {\n margin-top: 0.25rem !important;\n }\n .mt-md-2 {\n margin-top: 0.5rem !important;\n }\n .mt-md-3 {\n margin-top: 1rem !important;\n }\n .mt-md-4 {\n margin-top: 1.5rem !important;\n }\n .mt-md-5 {\n margin-top: 3rem !important;\n }\n .mt-md-auto {\n margin-top: auto !important;\n }\n .me-md-0 {\n margin-right: 0 !important;\n }\n .me-md-1 {\n margin-right: 0.25rem !important;\n }\n .me-md-2 {\n margin-right: 0.5rem !important;\n }\n .me-md-3 {\n margin-right: 1rem !important;\n }\n .me-md-4 {\n margin-right: 1.5rem !important;\n }\n .me-md-5 {\n margin-right: 3rem !important;\n }\n .me-md-auto {\n margin-right: auto !important;\n }\n .mb-md-0 {\n margin-bottom: 0 !important;\n }\n .mb-md-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-md-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-md-3 {\n margin-bottom: 1rem !important;\n }\n .mb-md-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-md-5 {\n margin-bottom: 3rem !important;\n }\n .mb-md-auto {\n margin-bottom: auto !important;\n }\n .ms-md-0 {\n margin-left: 0 !important;\n }\n .ms-md-1 {\n margin-left: 0.25rem !important;\n }\n .ms-md-2 {\n margin-left: 0.5rem !important;\n }\n .ms-md-3 {\n margin-left: 1rem !important;\n }\n .ms-md-4 {\n margin-left: 1.5rem !important;\n }\n .ms-md-5 {\n margin-left: 3rem !important;\n }\n .ms-md-auto {\n margin-left: auto !important;\n }\n .p-md-0 {\n padding: 0 !important;\n }\n .p-md-1 {\n padding: 0.25rem !important;\n }\n .p-md-2 {\n padding: 0.5rem !important;\n }\n .p-md-3 {\n padding: 1rem !important;\n }\n .p-md-4 {\n padding: 1.5rem !important;\n }\n .p-md-5 {\n padding: 3rem !important;\n }\n .px-md-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-md-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-md-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-md-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-md-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-md-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-md-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-md-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-md-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-md-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-md-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-md-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-md-0 {\n padding-top: 0 !important;\n }\n .pt-md-1 {\n padding-top: 0.25rem !important;\n }\n .pt-md-2 {\n padding-top: 0.5rem !important;\n }\n .pt-md-3 {\n padding-top: 1rem !important;\n }\n .pt-md-4 {\n padding-top: 1.5rem !important;\n }\n .pt-md-5 {\n padding-top: 3rem !important;\n }\n .pe-md-0 {\n padding-right: 0 !important;\n }\n .pe-md-1 {\n padding-right: 0.25rem !important;\n }\n .pe-md-2 {\n padding-right: 0.5rem !important;\n }\n .pe-md-3 {\n padding-right: 1rem !important;\n }\n .pe-md-4 {\n padding-right: 1.5rem !important;\n }\n .pe-md-5 {\n padding-right: 3rem !important;\n }\n .pb-md-0 {\n padding-bottom: 0 !important;\n }\n .pb-md-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-md-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-md-3 {\n padding-bottom: 1rem !important;\n }\n .pb-md-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-md-5 {\n padding-bottom: 3rem !important;\n }\n .ps-md-0 {\n padding-left: 0 !important;\n }\n .ps-md-1 {\n padding-left: 0.25rem !important;\n }\n .ps-md-2 {\n padding-left: 0.5rem !important;\n }\n .ps-md-3 {\n padding-left: 1rem !important;\n }\n .ps-md-4 {\n padding-left: 1.5rem !important;\n }\n .ps-md-5 {\n padding-left: 3rem !important;\n }\n .gap-md-0 {\n gap: 0 !important;\n }\n .gap-md-1 {\n gap: 0.25rem !important;\n }\n .gap-md-2 {\n gap: 0.5rem !important;\n }\n .gap-md-3 {\n gap: 1rem !important;\n }\n .gap-md-4 {\n gap: 1.5rem !important;\n }\n .gap-md-5 {\n gap: 3rem !important;\n }\n .row-gap-md-0 {\n row-gap: 0 !important;\n }\n .row-gap-md-1 {\n row-gap: 0.25rem !important;\n }\n .row-gap-md-2 {\n row-gap: 0.5rem !important;\n }\n .row-gap-md-3 {\n row-gap: 1rem !important;\n }\n .row-gap-md-4 {\n row-gap: 1.5rem !important;\n }\n .row-gap-md-5 {\n row-gap: 3rem !important;\n }\n .column-gap-md-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n }\n .column-gap-md-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n }\n .column-gap-md-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n }\n .column-gap-md-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n }\n .column-gap-md-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n }\n .column-gap-md-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n }\n .text-md-start {\n text-align: left !important;\n }\n .text-md-end {\n text-align: right !important;\n }\n .text-md-center {\n text-align: center !important;\n }\n}\n@media (min-width: 992px) {\n .float-lg-start {\n float: left !important;\n }\n .float-lg-end {\n float: right !important;\n }\n .float-lg-none {\n float: none !important;\n }\n .object-fit-lg-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n }\n .object-fit-lg-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n }\n .object-fit-lg-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n }\n .object-fit-lg-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n }\n .object-fit-lg-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n }\n .d-lg-inline {\n display: inline !important;\n }\n .d-lg-inline-block {\n display: inline-block !important;\n }\n .d-lg-block {\n display: block !important;\n }\n .d-lg-grid {\n display: grid !important;\n }\n .d-lg-inline-grid {\n display: inline-grid !important;\n }\n .d-lg-table {\n display: table !important;\n }\n .d-lg-table-row {\n display: table-row !important;\n }\n .d-lg-table-cell {\n display: table-cell !important;\n }\n .d-lg-flex {\n display: flex !important;\n }\n .d-lg-inline-flex {\n display: inline-flex !important;\n }\n .d-lg-none {\n display: none !important;\n }\n .flex-lg-fill {\n flex: 1 1 auto !important;\n }\n .flex-lg-row {\n flex-direction: row !important;\n }\n .flex-lg-column {\n flex-direction: column !important;\n }\n .flex-lg-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-lg-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-lg-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-lg-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-lg-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-lg-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-lg-wrap {\n flex-wrap: wrap !important;\n }\n .flex-lg-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-lg-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-lg-start {\n justify-content: flex-start !important;\n }\n .justify-content-lg-end {\n justify-content: flex-end !important;\n }\n .justify-content-lg-center {\n justify-content: center !important;\n }\n .justify-content-lg-between {\n justify-content: space-between !important;\n }\n .justify-content-lg-around {\n justify-content: space-around !important;\n }\n .justify-content-lg-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-lg-start {\n align-items: flex-start !important;\n }\n .align-items-lg-end {\n align-items: flex-end !important;\n }\n .align-items-lg-center {\n align-items: center !important;\n }\n .align-items-lg-baseline {\n align-items: baseline !important;\n }\n .align-items-lg-stretch {\n align-items: stretch !important;\n }\n .align-content-lg-start {\n align-content: flex-start !important;\n }\n .align-content-lg-end {\n align-content: flex-end !important;\n }\n .align-content-lg-center {\n align-content: center !important;\n }\n .align-content-lg-between {\n align-content: space-between !important;\n }\n .align-content-lg-around {\n align-content: space-around !important;\n }\n .align-content-lg-stretch {\n align-content: stretch !important;\n }\n .align-self-lg-auto {\n align-self: auto !important;\n }\n .align-self-lg-start {\n align-self: flex-start !important;\n }\n .align-self-lg-end {\n align-self: flex-end !important;\n }\n .align-self-lg-center {\n align-self: center !important;\n }\n .align-self-lg-baseline {\n align-self: baseline !important;\n }\n .align-self-lg-stretch {\n align-self: stretch !important;\n }\n .order-lg-first {\n order: -1 !important;\n }\n .order-lg-0 {\n order: 0 !important;\n }\n .order-lg-1 {\n order: 1 !important;\n }\n .order-lg-2 {\n order: 2 !important;\n }\n .order-lg-3 {\n order: 3 !important;\n }\n .order-lg-4 {\n order: 4 !important;\n }\n .order-lg-5 {\n order: 5 !important;\n }\n .order-lg-last {\n order: 6 !important;\n }\n .m-lg-0 {\n margin: 0 !important;\n }\n .m-lg-1 {\n margin: 0.25rem !important;\n }\n .m-lg-2 {\n margin: 0.5rem !important;\n }\n .m-lg-3 {\n margin: 1rem !important;\n }\n .m-lg-4 {\n margin: 1.5rem !important;\n }\n .m-lg-5 {\n margin: 3rem !important;\n }\n .m-lg-auto {\n margin: auto !important;\n }\n .mx-lg-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-lg-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-lg-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-lg-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-lg-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-lg-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-lg-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-lg-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-lg-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-lg-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-lg-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-lg-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-lg-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-lg-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-lg-0 {\n margin-top: 0 !important;\n }\n .mt-lg-1 {\n margin-top: 0.25rem !important;\n }\n .mt-lg-2 {\n margin-top: 0.5rem !important;\n }\n .mt-lg-3 {\n margin-top: 1rem !important;\n }\n .mt-lg-4 {\n margin-top: 1.5rem !important;\n }\n .mt-lg-5 {\n margin-top: 3rem !important;\n }\n .mt-lg-auto {\n margin-top: auto !important;\n }\n .me-lg-0 {\n margin-right: 0 !important;\n }\n .me-lg-1 {\n margin-right: 0.25rem !important;\n }\n .me-lg-2 {\n margin-right: 0.5rem !important;\n }\n .me-lg-3 {\n margin-right: 1rem !important;\n }\n .me-lg-4 {\n margin-right: 1.5rem !important;\n }\n .me-lg-5 {\n margin-right: 3rem !important;\n }\n .me-lg-auto {\n margin-right: auto !important;\n }\n .mb-lg-0 {\n margin-bottom: 0 !important;\n }\n .mb-lg-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-lg-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-lg-3 {\n margin-bottom: 1rem !important;\n }\n .mb-lg-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-lg-5 {\n margin-bottom: 3rem !important;\n }\n .mb-lg-auto {\n margin-bottom: auto !important;\n }\n .ms-lg-0 {\n margin-left: 0 !important;\n }\n .ms-lg-1 {\n margin-left: 0.25rem !important;\n }\n .ms-lg-2 {\n margin-left: 0.5rem !important;\n }\n .ms-lg-3 {\n margin-left: 1rem !important;\n }\n .ms-lg-4 {\n margin-left: 1.5rem !important;\n }\n .ms-lg-5 {\n margin-left: 3rem !important;\n }\n .ms-lg-auto {\n margin-left: auto !important;\n }\n .p-lg-0 {\n padding: 0 !important;\n }\n .p-lg-1 {\n padding: 0.25rem !important;\n }\n .p-lg-2 {\n padding: 0.5rem !important;\n }\n .p-lg-3 {\n padding: 1rem !important;\n }\n .p-lg-4 {\n padding: 1.5rem !important;\n }\n .p-lg-5 {\n padding: 3rem !important;\n }\n .px-lg-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-lg-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-lg-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-lg-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-lg-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-lg-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-lg-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-lg-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-lg-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-lg-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-lg-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-lg-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-lg-0 {\n padding-top: 0 !important;\n }\n .pt-lg-1 {\n padding-top: 0.25rem !important;\n }\n .pt-lg-2 {\n padding-top: 0.5rem !important;\n }\n .pt-lg-3 {\n padding-top: 1rem !important;\n }\n .pt-lg-4 {\n padding-top: 1.5rem !important;\n }\n .pt-lg-5 {\n padding-top: 3rem !important;\n }\n .pe-lg-0 {\n padding-right: 0 !important;\n }\n .pe-lg-1 {\n padding-right: 0.25rem !important;\n }\n .pe-lg-2 {\n padding-right: 0.5rem !important;\n }\n .pe-lg-3 {\n padding-right: 1rem !important;\n }\n .pe-lg-4 {\n padding-right: 1.5rem !important;\n }\n .pe-lg-5 {\n padding-right: 3rem !important;\n }\n .pb-lg-0 {\n padding-bottom: 0 !important;\n }\n .pb-lg-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-lg-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-lg-3 {\n padding-bottom: 1rem !important;\n }\n .pb-lg-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-lg-5 {\n padding-bottom: 3rem !important;\n }\n .ps-lg-0 {\n padding-left: 0 !important;\n }\n .ps-lg-1 {\n padding-left: 0.25rem !important;\n }\n .ps-lg-2 {\n padding-left: 0.5rem !important;\n }\n .ps-lg-3 {\n padding-left: 1rem !important;\n }\n .ps-lg-4 {\n padding-left: 1.5rem !important;\n }\n .ps-lg-5 {\n padding-left: 3rem !important;\n }\n .gap-lg-0 {\n gap: 0 !important;\n }\n .gap-lg-1 {\n gap: 0.25rem !important;\n }\n .gap-lg-2 {\n gap: 0.5rem !important;\n }\n .gap-lg-3 {\n gap: 1rem !important;\n }\n .gap-lg-4 {\n gap: 1.5rem !important;\n }\n .gap-lg-5 {\n gap: 3rem !important;\n }\n .row-gap-lg-0 {\n row-gap: 0 !important;\n }\n .row-gap-lg-1 {\n row-gap: 0.25rem !important;\n }\n .row-gap-lg-2 {\n row-gap: 0.5rem !important;\n }\n .row-gap-lg-3 {\n row-gap: 1rem !important;\n }\n .row-gap-lg-4 {\n row-gap: 1.5rem !important;\n }\n .row-gap-lg-5 {\n row-gap: 3rem !important;\n }\n .column-gap-lg-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n }\n .column-gap-lg-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n }\n .column-gap-lg-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n }\n .column-gap-lg-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n }\n .column-gap-lg-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n }\n .column-gap-lg-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n }\n .text-lg-start {\n text-align: left !important;\n }\n .text-lg-end {\n text-align: right !important;\n }\n .text-lg-center {\n text-align: center !important;\n }\n}\n@media (min-width: 1200px) {\n .float-xl-start {\n float: left !important;\n }\n .float-xl-end {\n float: right !important;\n }\n .float-xl-none {\n float: none !important;\n }\n .object-fit-xl-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n }\n .object-fit-xl-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n }\n .object-fit-xl-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n }\n .object-fit-xl-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n }\n .object-fit-xl-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n }\n .d-xl-inline {\n display: inline !important;\n }\n .d-xl-inline-block {\n display: inline-block !important;\n }\n .d-xl-block {\n display: block !important;\n }\n .d-xl-grid {\n display: grid !important;\n }\n .d-xl-inline-grid {\n display: inline-grid !important;\n }\n .d-xl-table {\n display: table !important;\n }\n .d-xl-table-row {\n display: table-row !important;\n }\n .d-xl-table-cell {\n display: table-cell !important;\n }\n .d-xl-flex {\n display: flex !important;\n }\n .d-xl-inline-flex {\n display: inline-flex !important;\n }\n .d-xl-none {\n display: none !important;\n }\n .flex-xl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xl-row {\n flex-direction: row !important;\n }\n .flex-xl-column {\n flex-direction: column !important;\n }\n .flex-xl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xl-center {\n justify-content: center !important;\n }\n .justify-content-xl-between {\n justify-content: space-between !important;\n }\n .justify-content-xl-around {\n justify-content: space-around !important;\n }\n .justify-content-xl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xl-start {\n align-items: flex-start !important;\n }\n .align-items-xl-end {\n align-items: flex-end !important;\n }\n .align-items-xl-center {\n align-items: center !important;\n }\n .align-items-xl-baseline {\n align-items: baseline !important;\n }\n .align-items-xl-stretch {\n align-items: stretch !important;\n }\n .align-content-xl-start {\n align-content: flex-start !important;\n }\n .align-content-xl-end {\n align-content: flex-end !important;\n }\n .align-content-xl-center {\n align-content: center !important;\n }\n .align-content-xl-between {\n align-content: space-between !important;\n }\n .align-content-xl-around {\n align-content: space-around !important;\n }\n .align-content-xl-stretch {\n align-content: stretch !important;\n }\n .align-self-xl-auto {\n align-self: auto !important;\n }\n .align-self-xl-start {\n align-self: flex-start !important;\n }\n .align-self-xl-end {\n align-self: flex-end !important;\n }\n .align-self-xl-center {\n align-self: center !important;\n }\n .align-self-xl-baseline {\n align-self: baseline !important;\n }\n .align-self-xl-stretch {\n align-self: stretch !important;\n }\n .order-xl-first {\n order: -1 !important;\n }\n .order-xl-0 {\n order: 0 !important;\n }\n .order-xl-1 {\n order: 1 !important;\n }\n .order-xl-2 {\n order: 2 !important;\n }\n .order-xl-3 {\n order: 3 !important;\n }\n .order-xl-4 {\n order: 4 !important;\n }\n .order-xl-5 {\n order: 5 !important;\n }\n .order-xl-last {\n order: 6 !important;\n }\n .m-xl-0 {\n margin: 0 !important;\n }\n .m-xl-1 {\n margin: 0.25rem !important;\n }\n .m-xl-2 {\n margin: 0.5rem !important;\n }\n .m-xl-3 {\n margin: 1rem !important;\n }\n .m-xl-4 {\n margin: 1.5rem !important;\n }\n .m-xl-5 {\n margin: 3rem !important;\n }\n .m-xl-auto {\n margin: auto !important;\n }\n .mx-xl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xl-0 {\n margin-top: 0 !important;\n }\n .mt-xl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xl-3 {\n margin-top: 1rem !important;\n }\n .mt-xl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xl-5 {\n margin-top: 3rem !important;\n }\n .mt-xl-auto {\n margin-top: auto !important;\n }\n .me-xl-0 {\n margin-right: 0 !important;\n }\n .me-xl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xl-3 {\n margin-right: 1rem !important;\n }\n .me-xl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xl-5 {\n margin-right: 3rem !important;\n }\n .me-xl-auto {\n margin-right: auto !important;\n }\n .mb-xl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xl-auto {\n margin-bottom: auto !important;\n }\n .ms-xl-0 {\n margin-left: 0 !important;\n }\n .ms-xl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xl-3 {\n margin-left: 1rem !important;\n }\n .ms-xl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xl-5 {\n margin-left: 3rem !important;\n }\n .ms-xl-auto {\n margin-left: auto !important;\n }\n .p-xl-0 {\n padding: 0 !important;\n }\n .p-xl-1 {\n padding: 0.25rem !important;\n }\n .p-xl-2 {\n padding: 0.5rem !important;\n }\n .p-xl-3 {\n padding: 1rem !important;\n }\n .p-xl-4 {\n padding: 1.5rem !important;\n }\n .p-xl-5 {\n padding: 3rem !important;\n }\n .px-xl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xl-0 {\n padding-top: 0 !important;\n }\n .pt-xl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xl-3 {\n padding-top: 1rem !important;\n }\n .pt-xl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xl-5 {\n padding-top: 3rem !important;\n }\n .pe-xl-0 {\n padding-right: 0 !important;\n }\n .pe-xl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xl-3 {\n padding-right: 1rem !important;\n }\n .pe-xl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xl-5 {\n padding-right: 3rem !important;\n }\n .pb-xl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xl-0 {\n padding-left: 0 !important;\n }\n .ps-xl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xl-3 {\n padding-left: 1rem !important;\n }\n .ps-xl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xl-5 {\n padding-left: 3rem !important;\n }\n .gap-xl-0 {\n gap: 0 !important;\n }\n .gap-xl-1 {\n gap: 0.25rem !important;\n }\n .gap-xl-2 {\n gap: 0.5rem !important;\n }\n .gap-xl-3 {\n gap: 1rem !important;\n }\n .gap-xl-4 {\n gap: 1.5rem !important;\n }\n .gap-xl-5 {\n gap: 3rem !important;\n }\n .row-gap-xl-0 {\n row-gap: 0 !important;\n }\n .row-gap-xl-1 {\n row-gap: 0.25rem !important;\n }\n .row-gap-xl-2 {\n row-gap: 0.5rem !important;\n }\n .row-gap-xl-3 {\n row-gap: 1rem !important;\n }\n .row-gap-xl-4 {\n row-gap: 1.5rem !important;\n }\n .row-gap-xl-5 {\n row-gap: 3rem !important;\n }\n .column-gap-xl-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n }\n .column-gap-xl-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n }\n .column-gap-xl-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n }\n .column-gap-xl-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n }\n .column-gap-xl-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n }\n .column-gap-xl-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n }\n .text-xl-start {\n text-align: left !important;\n }\n .text-xl-end {\n text-align: right !important;\n }\n .text-xl-center {\n text-align: center !important;\n }\n}\n@media (min-width: 1400px) {\n .float-xxl-start {\n float: left !important;\n }\n .float-xxl-end {\n float: right !important;\n }\n .float-xxl-none {\n float: none !important;\n }\n .object-fit-xxl-contain {\n -o-object-fit: contain !important;\n object-fit: contain !important;\n }\n .object-fit-xxl-cover {\n -o-object-fit: cover !important;\n object-fit: cover !important;\n }\n .object-fit-xxl-fill {\n -o-object-fit: fill !important;\n object-fit: fill !important;\n }\n .object-fit-xxl-scale {\n -o-object-fit: scale-down !important;\n object-fit: scale-down !important;\n }\n .object-fit-xxl-none {\n -o-object-fit: none !important;\n object-fit: none !important;\n }\n .d-xxl-inline {\n display: inline !important;\n }\n .d-xxl-inline-block {\n display: inline-block !important;\n }\n .d-xxl-block {\n display: block !important;\n }\n .d-xxl-grid {\n display: grid !important;\n }\n .d-xxl-inline-grid {\n display: inline-grid !important;\n }\n .d-xxl-table {\n display: table !important;\n }\n .d-xxl-table-row {\n display: table-row !important;\n }\n .d-xxl-table-cell {\n display: table-cell !important;\n }\n .d-xxl-flex {\n display: flex !important;\n }\n .d-xxl-inline-flex {\n display: inline-flex !important;\n }\n .d-xxl-none {\n display: none !important;\n }\n .flex-xxl-fill {\n flex: 1 1 auto !important;\n }\n .flex-xxl-row {\n flex-direction: row !important;\n }\n .flex-xxl-column {\n flex-direction: column !important;\n }\n .flex-xxl-row-reverse {\n flex-direction: row-reverse !important;\n }\n .flex-xxl-column-reverse {\n flex-direction: column-reverse !important;\n }\n .flex-xxl-grow-0 {\n flex-grow: 0 !important;\n }\n .flex-xxl-grow-1 {\n flex-grow: 1 !important;\n }\n .flex-xxl-shrink-0 {\n flex-shrink: 0 !important;\n }\n .flex-xxl-shrink-1 {\n flex-shrink: 1 !important;\n }\n .flex-xxl-wrap {\n flex-wrap: wrap !important;\n }\n .flex-xxl-nowrap {\n flex-wrap: nowrap !important;\n }\n .flex-xxl-wrap-reverse {\n flex-wrap: wrap-reverse !important;\n }\n .justify-content-xxl-start {\n justify-content: flex-start !important;\n }\n .justify-content-xxl-end {\n justify-content: flex-end !important;\n }\n .justify-content-xxl-center {\n justify-content: center !important;\n }\n .justify-content-xxl-between {\n justify-content: space-between !important;\n }\n .justify-content-xxl-around {\n justify-content: space-around !important;\n }\n .justify-content-xxl-evenly {\n justify-content: space-evenly !important;\n }\n .align-items-xxl-start {\n align-items: flex-start !important;\n }\n .align-items-xxl-end {\n align-items: flex-end !important;\n }\n .align-items-xxl-center {\n align-items: center !important;\n }\n .align-items-xxl-baseline {\n align-items: baseline !important;\n }\n .align-items-xxl-stretch {\n align-items: stretch !important;\n }\n .align-content-xxl-start {\n align-content: flex-start !important;\n }\n .align-content-xxl-end {\n align-content: flex-end !important;\n }\n .align-content-xxl-center {\n align-content: center !important;\n }\n .align-content-xxl-between {\n align-content: space-between !important;\n }\n .align-content-xxl-around {\n align-content: space-around !important;\n }\n .align-content-xxl-stretch {\n align-content: stretch !important;\n }\n .align-self-xxl-auto {\n align-self: auto !important;\n }\n .align-self-xxl-start {\n align-self: flex-start !important;\n }\n .align-self-xxl-end {\n align-self: flex-end !important;\n }\n .align-self-xxl-center {\n align-self: center !important;\n }\n .align-self-xxl-baseline {\n align-self: baseline !important;\n }\n .align-self-xxl-stretch {\n align-self: stretch !important;\n }\n .order-xxl-first {\n order: -1 !important;\n }\n .order-xxl-0 {\n order: 0 !important;\n }\n .order-xxl-1 {\n order: 1 !important;\n }\n .order-xxl-2 {\n order: 2 !important;\n }\n .order-xxl-3 {\n order: 3 !important;\n }\n .order-xxl-4 {\n order: 4 !important;\n }\n .order-xxl-5 {\n order: 5 !important;\n }\n .order-xxl-last {\n order: 6 !important;\n }\n .m-xxl-0 {\n margin: 0 !important;\n }\n .m-xxl-1 {\n margin: 0.25rem !important;\n }\n .m-xxl-2 {\n margin: 0.5rem !important;\n }\n .m-xxl-3 {\n margin: 1rem !important;\n }\n .m-xxl-4 {\n margin: 1.5rem !important;\n }\n .m-xxl-5 {\n margin: 3rem !important;\n }\n .m-xxl-auto {\n margin: auto !important;\n }\n .mx-xxl-0 {\n margin-right: 0 !important;\n margin-left: 0 !important;\n }\n .mx-xxl-1 {\n margin-right: 0.25rem !important;\n margin-left: 0.25rem !important;\n }\n .mx-xxl-2 {\n margin-right: 0.5rem !important;\n margin-left: 0.5rem !important;\n }\n .mx-xxl-3 {\n margin-right: 1rem !important;\n margin-left: 1rem !important;\n }\n .mx-xxl-4 {\n margin-right: 1.5rem !important;\n margin-left: 1.5rem !important;\n }\n .mx-xxl-5 {\n margin-right: 3rem !important;\n margin-left: 3rem !important;\n }\n .mx-xxl-auto {\n margin-right: auto !important;\n margin-left: auto !important;\n }\n .my-xxl-0 {\n margin-top: 0 !important;\n margin-bottom: 0 !important;\n }\n .my-xxl-1 {\n margin-top: 0.25rem !important;\n margin-bottom: 0.25rem !important;\n }\n .my-xxl-2 {\n margin-top: 0.5rem !important;\n margin-bottom: 0.5rem !important;\n }\n .my-xxl-3 {\n margin-top: 1rem !important;\n margin-bottom: 1rem !important;\n }\n .my-xxl-4 {\n margin-top: 1.5rem !important;\n margin-bottom: 1.5rem !important;\n }\n .my-xxl-5 {\n margin-top: 3rem !important;\n margin-bottom: 3rem !important;\n }\n .my-xxl-auto {\n margin-top: auto !important;\n margin-bottom: auto !important;\n }\n .mt-xxl-0 {\n margin-top: 0 !important;\n }\n .mt-xxl-1 {\n margin-top: 0.25rem !important;\n }\n .mt-xxl-2 {\n margin-top: 0.5rem !important;\n }\n .mt-xxl-3 {\n margin-top: 1rem !important;\n }\n .mt-xxl-4 {\n margin-top: 1.5rem !important;\n }\n .mt-xxl-5 {\n margin-top: 3rem !important;\n }\n .mt-xxl-auto {\n margin-top: auto !important;\n }\n .me-xxl-0 {\n margin-right: 0 !important;\n }\n .me-xxl-1 {\n margin-right: 0.25rem !important;\n }\n .me-xxl-2 {\n margin-right: 0.5rem !important;\n }\n .me-xxl-3 {\n margin-right: 1rem !important;\n }\n .me-xxl-4 {\n margin-right: 1.5rem !important;\n }\n .me-xxl-5 {\n margin-right: 3rem !important;\n }\n .me-xxl-auto {\n margin-right: auto !important;\n }\n .mb-xxl-0 {\n margin-bottom: 0 !important;\n }\n .mb-xxl-1 {\n margin-bottom: 0.25rem !important;\n }\n .mb-xxl-2 {\n margin-bottom: 0.5rem !important;\n }\n .mb-xxl-3 {\n margin-bottom: 1rem !important;\n }\n .mb-xxl-4 {\n margin-bottom: 1.5rem !important;\n }\n .mb-xxl-5 {\n margin-bottom: 3rem !important;\n }\n .mb-xxl-auto {\n margin-bottom: auto !important;\n }\n .ms-xxl-0 {\n margin-left: 0 !important;\n }\n .ms-xxl-1 {\n margin-left: 0.25rem !important;\n }\n .ms-xxl-2 {\n margin-left: 0.5rem !important;\n }\n .ms-xxl-3 {\n margin-left: 1rem !important;\n }\n .ms-xxl-4 {\n margin-left: 1.5rem !important;\n }\n .ms-xxl-5 {\n margin-left: 3rem !important;\n }\n .ms-xxl-auto {\n margin-left: auto !important;\n }\n .p-xxl-0 {\n padding: 0 !important;\n }\n .p-xxl-1 {\n padding: 0.25rem !important;\n }\n .p-xxl-2 {\n padding: 0.5rem !important;\n }\n .p-xxl-3 {\n padding: 1rem !important;\n }\n .p-xxl-4 {\n padding: 1.5rem !important;\n }\n .p-xxl-5 {\n padding: 3rem !important;\n }\n .px-xxl-0 {\n padding-right: 0 !important;\n padding-left: 0 !important;\n }\n .px-xxl-1 {\n padding-right: 0.25rem !important;\n padding-left: 0.25rem !important;\n }\n .px-xxl-2 {\n padding-right: 0.5rem !important;\n padding-left: 0.5rem !important;\n }\n .px-xxl-3 {\n padding-right: 1rem !important;\n padding-left: 1rem !important;\n }\n .px-xxl-4 {\n padding-right: 1.5rem !important;\n padding-left: 1.5rem !important;\n }\n .px-xxl-5 {\n padding-right: 3rem !important;\n padding-left: 3rem !important;\n }\n .py-xxl-0 {\n padding-top: 0 !important;\n padding-bottom: 0 !important;\n }\n .py-xxl-1 {\n padding-top: 0.25rem !important;\n padding-bottom: 0.25rem !important;\n }\n .py-xxl-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n }\n .py-xxl-3 {\n padding-top: 1rem !important;\n padding-bottom: 1rem !important;\n }\n .py-xxl-4 {\n padding-top: 1.5rem !important;\n padding-bottom: 1.5rem !important;\n }\n .py-xxl-5 {\n padding-top: 3rem !important;\n padding-bottom: 3rem !important;\n }\n .pt-xxl-0 {\n padding-top: 0 !important;\n }\n .pt-xxl-1 {\n padding-top: 0.25rem !important;\n }\n .pt-xxl-2 {\n padding-top: 0.5rem !important;\n }\n .pt-xxl-3 {\n padding-top: 1rem !important;\n }\n .pt-xxl-4 {\n padding-top: 1.5rem !important;\n }\n .pt-xxl-5 {\n padding-top: 3rem !important;\n }\n .pe-xxl-0 {\n padding-right: 0 !important;\n }\n .pe-xxl-1 {\n padding-right: 0.25rem !important;\n }\n .pe-xxl-2 {\n padding-right: 0.5rem !important;\n }\n .pe-xxl-3 {\n padding-right: 1rem !important;\n }\n .pe-xxl-4 {\n padding-right: 1.5rem !important;\n }\n .pe-xxl-5 {\n padding-right: 3rem !important;\n }\n .pb-xxl-0 {\n padding-bottom: 0 !important;\n }\n .pb-xxl-1 {\n padding-bottom: 0.25rem !important;\n }\n .pb-xxl-2 {\n padding-bottom: 0.5rem !important;\n }\n .pb-xxl-3 {\n padding-bottom: 1rem !important;\n }\n .pb-xxl-4 {\n padding-bottom: 1.5rem !important;\n }\n .pb-xxl-5 {\n padding-bottom: 3rem !important;\n }\n .ps-xxl-0 {\n padding-left: 0 !important;\n }\n .ps-xxl-1 {\n padding-left: 0.25rem !important;\n }\n .ps-xxl-2 {\n padding-left: 0.5rem !important;\n }\n .ps-xxl-3 {\n padding-left: 1rem !important;\n }\n .ps-xxl-4 {\n padding-left: 1.5rem !important;\n }\n .ps-xxl-5 {\n padding-left: 3rem !important;\n }\n .gap-xxl-0 {\n gap: 0 !important;\n }\n .gap-xxl-1 {\n gap: 0.25rem !important;\n }\n .gap-xxl-2 {\n gap: 0.5rem !important;\n }\n .gap-xxl-3 {\n gap: 1rem !important;\n }\n .gap-xxl-4 {\n gap: 1.5rem !important;\n }\n .gap-xxl-5 {\n gap: 3rem !important;\n }\n .row-gap-xxl-0 {\n row-gap: 0 !important;\n }\n .row-gap-xxl-1 {\n row-gap: 0.25rem !important;\n }\n .row-gap-xxl-2 {\n row-gap: 0.5rem !important;\n }\n .row-gap-xxl-3 {\n row-gap: 1rem !important;\n }\n .row-gap-xxl-4 {\n row-gap: 1.5rem !important;\n }\n .row-gap-xxl-5 {\n row-gap: 3rem !important;\n }\n .column-gap-xxl-0 {\n -moz-column-gap: 0 !important;\n column-gap: 0 !important;\n }\n .column-gap-xxl-1 {\n -moz-column-gap: 0.25rem !important;\n column-gap: 0.25rem !important;\n }\n .column-gap-xxl-2 {\n -moz-column-gap: 0.5rem !important;\n column-gap: 0.5rem !important;\n }\n .column-gap-xxl-3 {\n -moz-column-gap: 1rem !important;\n column-gap: 1rem !important;\n }\n .column-gap-xxl-4 {\n -moz-column-gap: 1.5rem !important;\n column-gap: 1.5rem !important;\n }\n .column-gap-xxl-5 {\n -moz-column-gap: 3rem !important;\n column-gap: 3rem !important;\n }\n .text-xxl-start {\n text-align: left !important;\n }\n .text-xxl-end {\n text-align: right !important;\n }\n .text-xxl-center {\n text-align: center !important;\n }\n}\n@media (min-width: 1200px) {\n .fs-1 {\n font-size: 2.5rem !important;\n }\n .fs-2 {\n font-size: 2rem !important;\n }\n .fs-3 {\n font-size: 1.75rem !important;\n }\n .fs-4 {\n font-size: 1.5rem !important;\n }\n}\n@media print {\n .d-print-inline {\n display: inline !important;\n }\n .d-print-inline-block {\n display: inline-block !important;\n }\n .d-print-block {\n display: block !important;\n }\n .d-print-grid {\n display: grid !important;\n }\n .d-print-inline-grid {\n display: inline-grid !important;\n }\n .d-print-table {\n display: table !important;\n }\n .d-print-table-row {\n display: table-row !important;\n }\n .d-print-table-cell {\n display: table-cell !important;\n }\n .d-print-flex {\n display: flex !important;\n }\n .d-print-inline-flex {\n display: inline-flex !important;\n }\n .d-print-none {\n display: none !important;\n }\n}\n\n/*# sourceMappingURL=bootstrap.css.map */","// stylelint-disable scss/dimension-no-non-numeric-values\n\n// SCSS RFS mixin\n//\n// Automated responsive values for font sizes, paddings, margins and much more\n//\n// Licensed under MIT (https://github.com/twbs/rfs/blob/main/LICENSE)\n\n// Configuration\n\n// Base value\n$rfs-base-value: 1.25rem !default;\n$rfs-unit: rem !default;\n\n@if $rfs-unit != rem and $rfs-unit != px {\n @error \"`#{$rfs-unit}` is not a valid unit for $rfs-unit. Use `px` or `rem`.\";\n}\n\n// Breakpoint at where values start decreasing if screen width is smaller\n$rfs-breakpoint: 1200px !default;\n$rfs-breakpoint-unit: px !default;\n\n@if $rfs-breakpoint-unit != px and $rfs-breakpoint-unit != em and $rfs-breakpoint-unit != rem {\n @error \"`#{$rfs-breakpoint-unit}` is not a valid unit for $rfs-breakpoint-unit. Use `px`, `em` or `rem`.\";\n}\n\n// Resize values based on screen height and width\n$rfs-two-dimensional: false !default;\n\n// Factor of decrease\n$rfs-factor: 10 !default;\n\n@if type-of($rfs-factor) != number or $rfs-factor <= 1 {\n @error \"`#{$rfs-factor}` is not a valid $rfs-factor, it must be greater than 1.\";\n}\n\n// Mode. Possibilities: \"min-media-query\", \"max-media-query\"\n$rfs-mode: min-media-query !default;\n\n// Generate enable or disable classes. Possibilities: false, \"enable\" or \"disable\"\n$rfs-class: false !default;\n\n// 1 rem = $rfs-rem-value px\n$rfs-rem-value: 16 !default;\n\n// Safari iframe resize bug: https://github.com/twbs/rfs/issues/14\n$rfs-safari-iframe-resize-bug-fix: false !default;\n\n// Disable RFS by setting $enable-rfs to false\n$enable-rfs: true !default;\n\n// Cache $rfs-base-value unit\n$rfs-base-value-unit: unit($rfs-base-value);\n\n@function divide($dividend, $divisor, $precision: 10) {\n $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);\n $dividend: abs($dividend);\n $divisor: abs($divisor);\n @if $dividend == 0 {\n @return 0;\n }\n @if $divisor == 0 {\n @error \"Cannot divide by 0\";\n }\n $remainder: $dividend;\n $result: 0;\n $factor: 10;\n @while ($remainder > 0 and $precision >= 0) {\n $quotient: 0;\n @while ($remainder >= $divisor) {\n $remainder: $remainder - $divisor;\n $quotient: $quotient + 1;\n }\n $result: $result * 10 + $quotient;\n $factor: $factor * .1;\n $remainder: $remainder * 10;\n $precision: $precision - 1;\n @if ($precision < 0 and $remainder >= $divisor * 5) {\n $result: $result + 1;\n }\n }\n $result: $result * $factor * $sign;\n $dividend-unit: unit($dividend);\n $divisor-unit: unit($divisor);\n $unit-map: (\n \"px\": 1px,\n \"rem\": 1rem,\n \"em\": 1em,\n \"%\": 1%\n );\n @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {\n $result: $result * map-get($unit-map, $dividend-unit);\n }\n @return $result;\n}\n\n// Remove px-unit from $rfs-base-value for calculations\n@if $rfs-base-value-unit == px {\n $rfs-base-value: divide($rfs-base-value, $rfs-base-value * 0 + 1);\n}\n@else if $rfs-base-value-unit == rem {\n $rfs-base-value: divide($rfs-base-value, divide($rfs-base-value * 0 + 1, $rfs-rem-value));\n}\n\n// Cache $rfs-breakpoint unit to prevent multiple calls\n$rfs-breakpoint-unit-cache: unit($rfs-breakpoint);\n\n// Remove unit from $rfs-breakpoint for calculations\n@if $rfs-breakpoint-unit-cache == px {\n $rfs-breakpoint: divide($rfs-breakpoint, $rfs-breakpoint * 0 + 1);\n}\n@else if $rfs-breakpoint-unit-cache == rem or $rfs-breakpoint-unit-cache == \"em\" {\n $rfs-breakpoint: divide($rfs-breakpoint, divide($rfs-breakpoint * 0 + 1, $rfs-rem-value));\n}\n\n// Calculate the media query value\n$rfs-mq-value: if($rfs-breakpoint-unit == px, #{$rfs-breakpoint}px, #{divide($rfs-breakpoint, $rfs-rem-value)}#{$rfs-breakpoint-unit});\n$rfs-mq-property-width: if($rfs-mode == max-media-query, max-width, min-width);\n$rfs-mq-property-height: if($rfs-mode == max-media-query, max-height, min-height);\n\n// Internal mixin used to determine which media query needs to be used\n@mixin _rfs-media-query {\n @if $rfs-two-dimensional {\n @if $rfs-mode == max-media-query {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}), (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) and (#{$rfs-mq-property-height}: #{$rfs-mq-value}) {\n @content;\n }\n }\n }\n @else {\n @media (#{$rfs-mq-property-width}: #{$rfs-mq-value}) {\n @content;\n }\n }\n}\n\n// Internal mixin that adds disable classes to the selector if needed.\n@mixin _rfs-rule {\n @if $rfs-class == disable and $rfs-mode == max-media-query {\n // Adding an extra class increases specificity, which prevents the media query to override the property\n &,\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @else if $rfs-class == enable and $rfs-mode == min-media-query {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n } @else {\n @content;\n }\n}\n\n// Internal mixin that adds enable classes to the selector if needed.\n@mixin _rfs-media-query-rule {\n\n @if $rfs-class == enable {\n @if $rfs-mode == min-media-query {\n @content;\n }\n\n @include _rfs-media-query () {\n .enable-rfs &,\n &.enable-rfs {\n @content;\n }\n }\n }\n @else {\n @if $rfs-class == disable and $rfs-mode == min-media-query {\n .disable-rfs &,\n &.disable-rfs {\n @content;\n }\n }\n @include _rfs-media-query () {\n @content;\n }\n }\n}\n\n// Helper function to get the formatted non-responsive value\n@function rfs-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n }\n @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n @if $unit == px {\n // Convert to rem if needed\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $value * 0 + $rfs-rem-value)}rem, $value);\n }\n @else if $unit == rem {\n // Convert to px if needed\n $val: $val + \" \" + if($rfs-unit == px, #{divide($value, $value * 0 + 1) * $rfs-rem-value}px, $value);\n } @else {\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n $val: $val + \" \" + $value;\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// Helper function to get the responsive value calculated by RFS\n@function rfs-fluid-value($values) {\n // Convert to list\n $values: if(type-of($values) != list, ($values,), $values);\n\n $val: \"\";\n\n // Loop over each value and calculate value\n @each $value in $values {\n @if $value == 0 {\n $val: $val + \" 0\";\n } @else {\n // Cache $value unit\n $unit: if(type-of($value) == \"number\", unit($value), false);\n\n // If $value isn't a number (like inherit) or $value has a unit (not px or rem, like 1.5em) or $ is 0, just print the value\n @if not $unit or $unit != px and $unit != rem {\n $val: $val + \" \" + $value;\n } @else {\n // Remove unit from $value for calculations\n $value: divide($value, $value * 0 + if($unit == px, 1, divide(1, $rfs-rem-value)));\n\n // Only add the media query if the value is greater than the minimum value\n @if abs($value) <= $rfs-base-value or not $enable-rfs {\n $val: $val + \" \" + if($rfs-unit == rem, #{divide($value, $rfs-rem-value)}rem, #{$value}px);\n }\n @else {\n // Calculate the minimum value\n $value-min: $rfs-base-value + divide(abs($value) - $rfs-base-value, $rfs-factor);\n\n // Calculate difference between $value and the minimum value\n $value-diff: abs($value) - $value-min;\n\n // Base value formatting\n $min-width: if($rfs-unit == rem, #{divide($value-min, $rfs-rem-value)}rem, #{$value-min}px);\n\n // Use negative value if needed\n $min-width: if($value < 0, -$min-width, $min-width);\n\n // Use `vmin` if two-dimensional is enabled\n $variable-unit: if($rfs-two-dimensional, vmin, vw);\n\n // Calculate the variable width between 0 and $rfs-breakpoint\n $variable-width: #{divide($value-diff * 100, $rfs-breakpoint)}#{$variable-unit};\n\n // Return the calculated value\n $val: $val + \" calc(\" + $min-width + if($value < 0, \" - \", \" + \") + $variable-width + \")\";\n }\n }\n }\n }\n\n // Remove first space\n @return unquote(str-slice($val, 2));\n}\n\n// RFS mixin\n@mixin rfs($values, $property: font-size) {\n @if $values != null {\n $val: rfs-value($values);\n $fluid-val: rfs-fluid-value($values);\n\n // Do not print the media query if responsive & non-responsive values are the same\n @if $val == $fluid-val {\n #{$property}: $val;\n }\n @else {\n @include _rfs-rule () {\n #{$property}: if($rfs-mode == max-media-query, $val, $fluid-val);\n\n // Include safari iframe resize fix if needed\n min-width: if($rfs-safari-iframe-resize-bug-fix, (0 * 1vw), null);\n }\n\n @include _rfs-media-query-rule () {\n #{$property}: if($rfs-mode == max-media-query, $fluid-val, $val);\n }\n }\n }\n}\n\n// Shorthand helper mixins\n@mixin font-size($value) {\n @include rfs($value);\n}\n\n@mixin padding($value) {\n @include rfs($value, padding);\n}\n\n@mixin padding-top($value) {\n @include rfs($value, padding-top);\n}\n\n@mixin padding-right($value) {\n @include rfs($value, padding-right);\n}\n\n@mixin padding-bottom($value) {\n @include rfs($value, padding-bottom);\n}\n\n@mixin padding-left($value) {\n @include rfs($value, padding-left);\n}\n\n@mixin margin($value) {\n @include rfs($value, margin);\n}\n\n@mixin margin-top($value) {\n @include rfs($value, margin-top);\n}\n\n@mixin margin-right($value) {\n @include rfs($value, margin-right);\n}\n\n@mixin margin-bottom($value) {\n @include rfs($value, margin-bottom);\n}\n\n@mixin margin-left($value) {\n @include rfs($value, margin-left);\n}\n","// scss-docs-start color-mode-mixin\n@mixin color-mode($mode: light, $root: false) {\n @if $color-mode-type == \"media-query\" {\n @if $root == true {\n @media (prefers-color-scheme: $mode) {\n :root {\n @content;\n }\n }\n } @else {\n @media (prefers-color-scheme: $mode) {\n @content;\n }\n }\n } @else {\n [data-bs-theme=\"#{$mode}\"] {\n @content;\n }\n }\n}\n// scss-docs-end color-mode-mixin\n","// stylelint-disable declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\n\n// Root\n//\n// Ability to the value of the root font sizes, affecting the value of `rem`.\n// null by default, thus nothing is generated.\n\n:root {\n @if $font-size-root != null {\n @include font-size(var(--#{$prefix}root-font-size));\n }\n\n @if $enable-smooth-scroll {\n @media (prefers-reduced-motion: no-preference) {\n scroll-behavior: smooth;\n }\n }\n}\n\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Prevent adjustments of font size after orientation changes in iOS.\n// 4. Change the default tap highlight to be completely transparent in iOS.\n\n// scss-docs-start reboot-body-rules\nbody {\n margin: 0; // 1\n font-family: var(--#{$prefix}body-font-family);\n @include font-size(var(--#{$prefix}body-font-size));\n font-weight: var(--#{$prefix}body-font-weight);\n line-height: var(--#{$prefix}body-line-height);\n color: var(--#{$prefix}body-color);\n text-align: var(--#{$prefix}body-text-align);\n background-color: var(--#{$prefix}body-bg); // 2\n -webkit-text-size-adjust: 100%; // 3\n -webkit-tap-highlight-color: rgba($black, 0); // 4\n}\n// scss-docs-end reboot-body-rules\n\n\n// Content grouping\n//\n// 1. Reset Firefox's gray color\n\nhr {\n margin: $hr-margin-y 0;\n color: $hr-color; // 1\n border: 0;\n border-top: $hr-border-width solid $hr-border-color;\n opacity: $hr-opacity;\n}\n\n\n// Typography\n//\n// 1. Remove top margins from headings\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n\n%heading {\n margin-top: 0; // 1\n margin-bottom: $headings-margin-bottom;\n font-family: $headings-font-family;\n font-style: $headings-font-style;\n font-weight: $headings-font-weight;\n line-height: $headings-line-height;\n color: var(--#{$prefix}heading-color);\n}\n\nh1 {\n @extend %heading;\n @include font-size($h1-font-size);\n}\n\nh2 {\n @extend %heading;\n @include font-size($h2-font-size);\n}\n\nh3 {\n @extend %heading;\n @include font-size($h3-font-size);\n}\n\nh4 {\n @extend %heading;\n @include font-size($h4-font-size);\n}\n\nh5 {\n @extend %heading;\n @include font-size($h5-font-size);\n}\n\nh6 {\n @extend %heading;\n @include font-size($h6-font-size);\n}\n\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\n\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n\n// Abbreviations\n//\n// 1. Add the correct text decoration in Chrome, Edge, Opera, and Safari.\n// 2. Add explicit cursor to indicate changed behavior.\n// 3. Prevent the text-decoration to be skipped.\n\nabbr[title] {\n text-decoration: underline dotted; // 1\n cursor: help; // 2\n text-decoration-skip-ink: none; // 3\n}\n\n\n// Address\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\n\n// Lists\n\nol,\nul {\n padding-left: 2rem;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\n// 1. Undo browser default\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // 1\n}\n\n\n// Blockquote\n\nblockquote {\n margin: 0 0 1rem;\n}\n\n\n// Strong\n//\n// Add the correct font weight in Chrome, Edge, and Safari\n\nb,\nstrong {\n font-weight: $font-weight-bolder;\n}\n\n\n// Small\n//\n// Add the correct font size in all browsers\n\nsmall {\n @include font-size($small-font-size);\n}\n\n\n// Mark\n\nmark {\n padding: $mark-padding;\n background-color: var(--#{$prefix}highlight-bg);\n}\n\n\n// Sub and Sup\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n\nsub,\nsup {\n position: relative;\n @include font-size($sub-sup-font-size);\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n// Links\n\na {\n color: rgba(var(--#{$prefix}link-color-rgb), var(--#{$prefix}link-opacity, 1));\n text-decoration: $link-decoration;\n\n &:hover {\n --#{$prefix}link-color-rgb: var(--#{$prefix}link-hover-color-rgb);\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([class]) {\n &,\n &:hover {\n color: inherit;\n text-decoration: none;\n }\n}\n\n\n// Code\n\npre,\ncode,\nkbd,\nsamp {\n font-family: $font-family-code;\n @include font-size(1em); // Correct the odd `em` font sizing in all browsers.\n}\n\n// 1. Remove browser default top margin\n// 2. Reset browser default of `1em` to use `rem`s\n// 3. Don't allow content to break outside\n\npre {\n display: block;\n margin-top: 0; // 1\n margin-bottom: 1rem; // 2\n overflow: auto; // 3\n @include font-size($code-font-size);\n color: $pre-color;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n @include font-size(inherit);\n color: inherit;\n word-break: normal;\n }\n}\n\ncode {\n @include font-size($code-font-size);\n color: var(--#{$prefix}code-color);\n word-wrap: break-word;\n\n // Streamline the style when inside anchors to avoid broken underline and more\n a > & {\n color: inherit;\n }\n}\n\nkbd {\n padding: $kbd-padding-y $kbd-padding-x;\n @include font-size($kbd-font-size);\n color: $kbd-color;\n background-color: $kbd-bg;\n @include border-radius($border-radius-sm);\n\n kbd {\n padding: 0;\n @include font-size(1em);\n font-weight: $nested-kbd-font-weight;\n }\n}\n\n\n// Figures\n//\n// Apply a consistent margin strategy (matches our type styles).\n\nfigure {\n margin: 0 0 1rem;\n}\n\n\n// Images and content\n\nimg,\nsvg {\n vertical-align: middle;\n}\n\n\n// Tables\n//\n// Prevent double borders\n\ntable {\n caption-side: bottom;\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: $table-cell-padding-y;\n padding-bottom: $table-cell-padding-y;\n color: $table-caption-color;\n text-align: left;\n}\n\n// 1. Removes font-weight bold by inheriting\n// 2. Matches default `` alignment by inheriting `text-align`.\n// 3. Fix alignment for Safari\n\nth {\n font-weight: $table-th-font-weight; // 1\n text-align: inherit; // 2\n text-align: -webkit-match-parent; // 3\n}\n\nthead,\ntbody,\ntfoot,\ntr,\ntd,\nth {\n border-color: inherit;\n border-style: solid;\n border-width: 0;\n}\n\n\n// Forms\n//\n// 1. Allow labels to use `margin` for spacing.\n\nlabel {\n display: inline-block; // 1\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n// See https://github.com/twbs/bootstrap/issues/24093\n\nbutton {\n // stylelint-disable-next-line property-disallowed-list\n border-radius: 0;\n}\n\n// Explicitly remove focus outline in Chromium when it shouldn't be\n// visible (e.g. as result of mouse click or touch tap). It already\n// should be doing this automatically, but seems to currently be\n// confused and applies its very visible two-tone outline anyway.\n\nbutton:focus:not(:focus-visible) {\n outline: 0;\n}\n\n// 1. Remove the margin in Firefox and Safari\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // 1\n font-family: inherit;\n @include font-size(inherit);\n line-height: inherit;\n}\n\n// Remove the inheritance of text transform in Firefox\nbutton,\nselect {\n text-transform: none;\n}\n// Set the cursor for non-`