From c04be9ab371f6973b56b5b7ecb053223d06a6263 Mon Sep 17 00:00:00 2001 From: SoftFever Date: Fri, 1 May 2026 18:01:29 +0800 Subject: [PATCH] Introducing Orca Cloud: https://cloud.orcaslicer.com (#13414) * Add OrcaCloud sync platform and preset bundle sharing system Introduce OrcaCloud, a cloud sync platform for user presets, alongside a preset bundle system that enables sharing printer/filament/process profiles as local exportable bundles or subscribed cloud bundles. OrcaCloud platform: - Auth to Orca Cloud - Encrypted token storage (file-based or system keychain) - User preset sync with - Profile migration from default/bambu folders on first login - Homepage integration with entrance to cloud.orcaslicer.com Preset bundles: - Local bundle import/export with bundle_structure.json metadata - Subscribed cloud bundles with version-based update checking - Thread-safe concurrent bundle access with read-write mutex - Canonical bundle preset naming (_local//... and _subscribed//...) - Bundle presets are read-only; grouped under subheaders in combo boxes - PresetBundleDialog with auto-sync toggle, refresh, update notifications - Hyperlinked bundle names to cloud bundle pages Co-authored-by: Sabriel Koh Co-authored-by: Derrick Co-authored-by: Mykola Nahirnyi Co-authored-by: Ian Chua Co-authored-by: Draginraptor Co-authored-by: ExPikaPaka <112851715+ExPikaPaka@users.noreply.github.com> Co-authored-by: Ian Bassi Co-authored-by: Ocraftyone Co-authored-by: yw4z Co-authored-by: peterm-m <101202951+peterm-m@users.noreply.github.com> * Fixed an issue on Windows it failed to login Orca Cloud with Google account --- .clang-format | 2 +- AGENTS.md | 59 +- CLAUDE.md | 235 +-- build_linux.sh | 11 +- resources/web/data/text.js | 17 +- .../web/dialog/ExportPresetDialog/index.html | 75 + .../web/dialog/ExportPresetDialog/index.js | 374 +++++ .../web/dialog/ExportPresetDialog/styles.css | 191 +++ .../web/dialog/PresetBundleDialog/index.html | 71 + .../web/dialog/PresetBundleDialog/index.js | 375 +++++ .../web/dialog/PresetBundleDialog/styles.css | 394 +++++ resources/web/dialog/css/common.css | 173 +++ resources/web/dialog/css/dark.css | 100 ++ resources/web/dialog/css/home.css | 35 + resources/web/dialog/css/test.css | 58 + resources/web/dialog/js/common.js | 21 + .../web/{login => dialog}/js/globalapi.js | 59 + resources/web/dialog/js/home.js | 12 + resources/web/dialog/js/jquery-2.1.1.min.js | 4 + .../{login => dialog}/js/jquery-3.6.0.min.js | 0 resources/web/{login => dialog}/js/json2.js | 0 resources/web/homepage/css/dark.css | 7 +- resources/web/homepage/css/home.css | 195 ++- resources/web/homepage/index.html | 74 +- resources/web/homepage/js/home.js | 134 +- resources/web/login/css/login.css | 50 - resources/web/login/disconnect.png | Bin 14342 -> 0 bytes resources/web/login/disconnect2.png | Bin 8976 -> 0 bytes resources/web/login/disconnect3.png | Bin 9101 -> 0 bytes resources/web/login/error.html | 35 - resources/web/login/js/login.js | 157 -- resources/web/login/orca_login.html | 927 ----------- scripts/test_moonraker_lane_data.py | 0 .../OrcaSlicer_profile_validator.cpp | 2 +- src/libslic3r/AppConfig.cpp | 78 + src/libslic3r/AppConfig.hpp | 8 + src/libslic3r/Preset.cpp | 323 +++- src/libslic3r/Preset.hpp | 55 +- src/libslic3r/PresetBundle.cpp | 850 ++++++++++- src/libslic3r/PresetBundle.hpp | 142 +- src/libslic3r/Utils.hpp | 14 +- src/libslic3r/utils.cpp | 79 +- src/slic3r/CMakeLists.txt | 4 + src/slic3r/GUI/BindDialog.cpp | 18 +- src/slic3r/GUI/CalibrationPanel.cpp | 9 +- .../GUI/CalibrationWizardPresetPage.cpp | 4 +- src/slic3r/GUI/CreatePresetsDialog.cpp | 9 +- src/slic3r/GUI/DeviceCore/DevFilaSystem.h | 85 ++ src/slic3r/GUI/DeviceCore/DevManager.cpp | 45 +- src/slic3r/GUI/DeviceCore/DevManager.h | 10 +- src/slic3r/GUI/DeviceManager.cpp | 2 +- src/slic3r/GUI/ExportPresetBundleDialog.cpp | 553 +++++++ src/slic3r/GUI/ExportPresetBundleDialog.hpp | 86 ++ src/slic3r/GUI/GUI.cpp | 10 +- src/slic3r/GUI/GUI.hpp | 2 - src/slic3r/GUI/GUI_App.cpp | 1351 +++++++++++++---- src/slic3r/GUI/GUI_App.hpp | 84 +- src/slic3r/GUI/HttpServer.cpp | 68 +- src/slic3r/GUI/HttpServer.hpp | 2 + src/slic3r/GUI/Jobs/BindJob.cpp | 2 +- src/slic3r/GUI/MainFrame.cpp | 29 +- src/slic3r/GUI/Monitor.cpp | 2 +- src/slic3r/GUI/NotificationManager.cpp | 132 ++ src/slic3r/GUI/NotificationManager.hpp | 28 + src/slic3r/GUI/Plater.cpp | 39 +- src/slic3r/GUI/Preferences.cpp | 42 + src/slic3r/GUI/PresetBundleDialog.cpp | 472 ++++++ src/slic3r/GUI/PresetBundleDialog.hpp | 102 ++ src/slic3r/GUI/PresetComboBoxes.cpp | 127 +- src/slic3r/GUI/SavePresetDialog.cpp | 8 +- src/slic3r/GUI/SelectMachine.cpp | 11 +- src/slic3r/GUI/SelectMachinePop.cpp | 13 +- src/slic3r/GUI/SendToPrinter.cpp | 14 +- src/slic3r/GUI/SyncAmsInfoDialog.cpp | 14 +- src/slic3r/GUI/Tab.cpp | 27 +- src/slic3r/GUI/Tab.hpp | 1 + src/slic3r/GUI/UnsavedChangesDialog.cpp | 4 +- src/slic3r/GUI/UserManager.cpp | 4 +- src/slic3r/GUI/WebGuideDialog.cpp | 111 +- src/slic3r/GUI/WebUserLoginDialog.cpp | 123 +- src/slic3r/GUI/WebUserLoginDialog.hpp | 7 +- src/slic3r/GUI/WebViewDialog.cpp | 31 +- src/slic3r/GUI/WebViewDialog.hpp | 1 + src/slic3r/GUI/Widgets/ComboBox.cpp | 24 +- src/slic3r/GUI/Widgets/ComboBox.hpp | 6 + src/slic3r/GUI/Widgets/DropDown.cpp | 54 +- src/slic3r/GUI/Widgets/DropDown.hpp | 3 +- src/slic3r/Utils/BBLCloudServiceAgent.cpp | 139 +- src/slic3r/Utils/BBLCloudServiceAgent.hpp | 17 +- src/slic3r/Utils/BBLNetworkPlugin.cpp | 4 - src/slic3r/Utils/BBLNetworkPlugin.hpp | 6 - src/slic3r/Utils/BBLPrinterAgent.cpp | 48 + src/slic3r/Utils/BBLPrinterAgent.hpp | 6 + src/slic3r/Utils/CalibUtils.cpp | 2 +- src/slic3r/Utils/Http.cpp | 10 + src/slic3r/Utils/Http.hpp | 4 + src/slic3r/Utils/ICloudServiceAgent.hpp | 34 +- src/slic3r/Utils/IPrinterAgent.hpp | 24 +- src/slic3r/Utils/NetworkAgent.cpp | 1321 ++++++++-------- src/slic3r/Utils/NetworkAgent.hpp | 175 +-- src/slic3r/Utils/NetworkAgentFactory.cpp | 31 +- src/slic3r/Utils/NetworkAgentFactory.hpp | 26 +- src/slic3r/Utils/OrcaCloudServiceAgent.cpp | 881 ++++++----- src/slic3r/Utils/OrcaCloudServiceAgent.hpp | 46 +- src/slic3r/Utils/PresetUpdater.cpp | 31 +- src/slic3r/Utils/bambu_networking.hpp | 2 - tests/CMakeLists.txt | 29 + tests/fff_print/CMakeLists.txt | 10 +- tests/libnest2d/CMakeLists.txt | 10 +- tests/libslic3r/CMakeLists.txt | 11 +- .../libslic3r/test_preset_bundle_loading.cpp | 102 ++ tests/sla_print/CMakeLists.txt | 10 +- tests/slic3rutils/CMakeLists.txt | 10 +- 113 files changed, 8691 insertions(+), 3467 deletions(-) create mode 100644 resources/web/dialog/ExportPresetDialog/index.html create mode 100644 resources/web/dialog/ExportPresetDialog/index.js create mode 100644 resources/web/dialog/ExportPresetDialog/styles.css create mode 100644 resources/web/dialog/PresetBundleDialog/index.html create mode 100644 resources/web/dialog/PresetBundleDialog/index.js create mode 100644 resources/web/dialog/PresetBundleDialog/styles.css create mode 100644 resources/web/dialog/css/common.css create mode 100644 resources/web/dialog/css/dark.css create mode 100644 resources/web/dialog/css/home.css create mode 100644 resources/web/dialog/css/test.css create mode 100644 resources/web/dialog/js/common.js rename resources/web/{login => dialog}/js/globalapi.js (83%) create mode 100644 resources/web/dialog/js/home.js create mode 100644 resources/web/dialog/js/jquery-2.1.1.min.js rename resources/web/{login => dialog}/js/jquery-3.6.0.min.js (100%) rename resources/web/{login => dialog}/js/json2.js (100%) delete mode 100644 resources/web/login/css/login.css delete mode 100644 resources/web/login/disconnect.png delete mode 100644 resources/web/login/disconnect2.png delete mode 100644 resources/web/login/disconnect3.png delete mode 100644 resources/web/login/error.html delete mode 100644 resources/web/login/js/login.js delete mode 100644 resources/web/login/orca_login.html mode change 100755 => 100644 scripts/test_moonraker_lane_data.py create mode 100644 src/slic3r/GUI/ExportPresetBundleDialog.cpp create mode 100644 src/slic3r/GUI/ExportPresetBundleDialog.hpp create mode 100644 src/slic3r/GUI/PresetBundleDialog.cpp create mode 100644 src/slic3r/GUI/PresetBundleDialog.hpp create mode 100644 tests/libslic3r/test_preset_bundle_loading.cpp diff --git a/.clang-format b/.clang-format index 6376be4d75..dea9ac29cd 100644 --- a/.clang-format +++ b/.clang-format @@ -5,7 +5,7 @@ Language: Cpp AccessModifierOffset: -4 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: true -AlignConsecutiveDeclarations: true +AlignConsecutiveDeclarations: false AlignEscapedNewlines: DontAlign AlignOperands: true AlignTrailingComments: true diff --git a/AGENTS.md b/AGENTS.md index 5446ab270e..e1a230c3e3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,23 +1,48 @@ -# Repository Guidelines +# CLAUDE.md -## Project Structure & Module Organization -OrcaSlicer’s C++17 sources live in `src/`, split by feature modules and platform adapters. User assets, icons, and printer presets are in `resources/`; translations stay in `localization/`. Tests sit in `tests/`, grouped by domain (`libslic3r/`, `sla_print/`, etc.) with fixtures under `tests/data/`. CMake helpers reside in `cmake/`, and longer references in `doc/` and `SoftFever_doc/`. Automation scripts belong in `scripts/` and `tools/`. Treat everything in `deps/` and `deps_src/` as vendored snapshots—do not modify without mirroring upstream tags. +OrcaSlicer — open-source C++17 3D slicer. wxWidgets GUI, CMake build system. -## Build, Test, and Development Commands -Use out-of-source builds: -- `cmake -S . -B build -DCMAKE_BUILD_TYPE=Release` configures dependencies and generates build files. -- `cmake --build build --target OrcaSlicer --config Release` compiles the app; add `--parallel` to speed up. -- `cmake --build build --target tests` then `ctest --test-dir build --output-on-failure` runs automated suites. -Platform helpers such as `build_linux.sh`, `build_release_macos.sh`, and `build_release_vs2022.bat` wrap the same flow with toolchain flags. Use `build_release_macos.sh -sx` when reproducing macOS build issues, and `scripts/DockerBuild.sh` for reproducible container builds. +## Build Commands -## Coding Style & Naming Conventions -`.clang-format` enforces 4-space indents, a 140-column limit, aligned initializers, and brace wrapping for classes and functions. Run `clang-format -i ` before committing; the CMake `clang-format` target is available when LLVM tools are on your PATH. Prefer `CamelCase` for classes, `snake_case` for functions and locals, and `SCREAMING_CASE` for constants, matching conventions in `src/`. Keep headers self-contained and align include order with the IWYU pragmas. +```bash +# macOS +cmake --build build/arm64 --config RelWithDebInfo --target all -- -## Testing Guidelines -Unit tests rely on Catch2 (`tests/catch2/`). Name specs after the component under test—for example `tests/libslic3r/TestPlanarHole.cpp`—and tag long-running cases so `ctest -L fast` remains useful. Cover new algorithms with deterministic fixtures or sample G-code stored in `tests/data/`. Document manual printer validation or regression slicer checks in your PR when automated coverage is insufficient. +# Linux +cmake --build build --config RelWithDebInfo --target all -- -## Commit & Pull Request Guidelines -The history favors concise, sentence-style subject lines with optional issue references, e.g., `Fix grid lines origin for multiple plates (#10724)`. Squash fixups locally before opening a PR. Complete `.github/pull_request_template.md`, include reproduction steps or screenshots for UI changes, and mention impacted presets or translations. Link issues via `Closes #NNNN` when applicable, and call out dependency bumps or profile migrations for maintainer review. +# Windows (replace %build_type% with Debug/Release/RelWithDebInfo) +cmake --build . --config %build_type% --target ALL_BUILD -- -m +``` -## Security & Configuration Tips -Follow `SECURITY.md` for vulnerability reporting. Keep API tokens and printer credentials out of tracked configs; use `sandboxes/` for experimental settings. When touching third-party code in `deps_src/`, record the upstream commit or release in your PR description and run the relevant platform build script to confirm integration. +## Testing + +Catch2 framework. Tests in `tests/` directory. + +```bash +cd build && ctest --output-on-failure # all tests +ctest --test-dir ./tests/libslic3r # individual suite +ctest --test-dir ./tests/fff_print +``` + +## Code Style + +- C++17, selective C++20. PascalCase classes, snake_case functions/variables +- `#pragma once` for headers. Smart pointers and RAII preferred +- Parallelization via TBB — be mindful of shared state + +## Key Entry Points + +- App startup: `src/OrcaSlicer.cpp` +- Slicing pipeline: `src/libslic3r/Print.cpp` +- All print/printer/material settings: `src/libslic3r/PrintConfig.cpp` +- GUI: `src/slic3r/GUI/` +- Core algorithms: `src/libslic3r/` (GCode/, Fill/, Support/, Geometry/, Format/, Arachne/) +- Printer profiles: `resources/profiles/[manufacturer].json` + +## Critical Constraints + +- **Backward compatibility required** for .3mf project files and printer profiles +- **Cross-platform** — all changes must work on Windows, macOS, and Linux +- Profile/format changes need version migration handling +- Dependencies built separately in `deps/build/`, then linked to main app diff --git a/CLAUDE.md b/CLAUDE.md index 25aa516a56..eef4bd20cf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,234 +1 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Overview - -OrcaSlicer is an open-source 3D slicer application forked from Bambu Studio, built using C++ with wxWidgets for the GUI and CMake as the build system. The project uses a modular architecture with separate libraries for core slicing functionality, GUI components, and platform-specific code. - -## Build Commands - -### Building on Windows -**Always use this command to build the project when testing build issues on Windows.** -```bash -cmake --build . --config %build_type% --target ALL_BUILD -- -m -``` - -### Building on macOS -**Always use this command to build the project when testing build issues on macOS.** -```bash -cmake --build build/arm64 --config RelWithDebInfo --target all -- -``` - -### Building on Linux - **Always use this command to build the project when testing build issues on Linux.** -```bash -cmake --build build/arm64 --config RelWithDebInfo --target all -- - -``` -### Build test: - -**Always use this command to build the project when testing build issues on Windows.** -```bash -cmake --build . --config %build_type% --target ALL_BUILD -- -m -``` - -### Building on macOS -**Always use this command to build the project when testing build issues on macOS.** -```bash -cmake --build build/arm64 --config RelWithDebInfo --target all -- -``` - -### Building on Linux - **Always use this command to build the project when testing build issues on Linux.** -```bash -cmake --build build --config RelWithDebInfo --target all -- - -``` - - -### Build System -- Uses CMake with minimum version 3.13 (maximum 3.31.x on Windows) -- Primary build directory: `build/` -- Dependencies are built in `deps/build/` -- The build process is split into dependency building and main application building -- Windows builds use Visual Studio generators -- macOS builds use Xcode by default, Ninja with -x flag -- Linux builds use Ninja generator - -### Testing -Tests are located in the `tests/` directory and use the Catch2 testing framework. Test structure: -- `tests/libslic3r/` - Core library tests (21 test files) - - Geometry processing, algorithms, file formats (STL, 3MF, AMF) - - Polygon operations, clipper utilities, Voronoi diagrams -- `tests/fff_print/` - Fused Filament Fabrication tests (12 test files) - - Slicing algorithms, G-code generation, print mechanics - - Fill patterns, extrusion, support material -- `tests/sla_print/` - Stereolithography tests (4 test files) - - SLA-specific printing algorithms, support generation -- `tests/libnest2d/` - 2D nesting algorithm tests -- `tests/slic3rutils/` - Utility function tests -- `tests/sandboxes/` - Experimental/sandbox test code - -Run all tests after building: -```bash -cd build && ctest -``` - -Run tests with verbose output: -```bash -cd build && ctest --output-on-failure -``` - -Run individual test suites: -```bash -# From build directory -ctest --test-dir ./tests/libslic3r/libslic3r_tests -ctest --test-dir ./tests/fff_print/fff_print_tests -ctest --test-dir ./tests/sla_print/sla_print_tests -# and so on -``` - -## Architecture - -### Core Libraries -- **libslic3r/**: Core slicing engine and algorithms (platform-independent) - - Main slicing logic, geometry processing, G-code generation - - Key classes: Print, PrintObject, Layer, GCode, Config - - Modular design with specialized subdirectories: - - `GCode/` - G-code generation, cooling, pressure equalization, thumbnails - - `Fill/` - Infill pattern implementations (gyroid, honeycomb, lightning, etc.) - - `Support/` - Tree supports and traditional support generation - - `Geometry/` - Advanced geometry operations, Voronoi diagrams, medial axis - - `Format/` - File I/O for 3MF, AMF, STL, OBJ, STEP formats - - `SLA/` - SLA-specific print processing and support generation - - `Arachne/` - Advanced wall generation using skeletal trapezoidation - -- **src/slic3r/**: Main application framework and GUI - - GUI application built with wxWidgets - - Integration between libslic3r core and user interface - - Located in `src/slic3r/GUI/` (not shown in this directory but exists) - -### Key Algorithmic Components -- **Arachne Wall Generation**: Variable-width perimeter generation using skeletal trapezoidation -- **Tree Supports**: Organic support generation algorithm -- **Lightning Infill**: Sparse infill optimization for internal structures -- **Adaptive Slicing**: Variable layer height based on geometry -- **Multi-material**: Multi-extruder and soluble support processing -- **G-code Post-processing**: Cooling, fan control, pressure advance, conflict checking - -### File Format Support -- **3MF/BBS_3MF**: Native format with extensions for multi-material and metadata -- **STL**: Standard tessellation language for 3D models -- **AMF**: Additive Manufacturing Format with color/material support -- **OBJ**: Wavefront OBJ with material definitions -- **STEP**: CAD format support for precise geometry -- **G-code**: Output format with extensive post-processing capabilities - -### External Dependencies -- **Clipper2**: Advanced 2D polygon clipping and offsetting -- **libigl**: Computational geometry library for mesh operations -- **TBB**: Intel Threading Building Blocks for parallelization -- **wxWidgets**: Cross-platform GUI framework -- **OpenGL**: 3D graphics rendering and visualization -- **CGAL**: Computational Geometry Algorithms Library (selective use) -- **OpenVDB**: Volumetric data structures for advanced operations -- **Eigen**: Linear algebra library for mathematical operations - -## File Organization - -### Resources and Configuration -- `resources/profiles/` - Printer and material profiles organized by manufacturer -- `resources/printers/` - Printer-specific configurations and G-code templates -- `resources/images/` - UI icons, logos, calibration images -- `resources/calib/` - Calibration test patterns and data -- `resources/handy_models/` - Built-in test models (benchy, calibration cubes) - -### Internationalization and Localization -- `localization/i18n/` - Source translation files (.pot, .po) -- `resources/i18n/` - Runtime language resources -- Translation managed via `scripts/run_gettext.sh` / `scripts/run_gettext.bat` - -### Platform-Specific Code -- `src/libslic3r/Platform.cpp` - Platform abstractions and utilities -- `src/libslic3r/MacUtils.mm` - macOS-specific utilities (Objective-C++) -- Windows-specific build scripts and configurations -- Linux distribution support scripts in `scripts/linux.d/` - -### Build and Development Tools -- `cmake/modules/` - Custom CMake find modules and utilities -- `scripts/` - Python utilities for profile generation and validation -- `tools/` - Windows build tools (gettext utilities) -- `deps/` - External dependency build configurations - -## Development Workflow - -### Code Style and Standards -- **C++17 standard** with selective C++20 features -- **Naming conventions**: PascalCase for classes, snake_case for functions/variables -- **Header guards**: Use `#pragma once` -- **Memory management**: Prefer smart pointers, RAII patterns -- **Thread safety**: Use TBB for parallelization, be mindful of shared state - -### Common Development Tasks - -#### Adding New Print Settings -1. Define setting in `PrintConfig.cpp` with proper bounds and defaults -2. Add UI controls in appropriate GUI components -3. Update serialization in config save/load -4. Add tooltips and help text for user guidance -5. Test with different printer profiles - -#### Modifying Slicing Algorithms -1. Core algorithms live in `libslic3r/` subdirectories -2. Performance-critical code should be profiled and optimized -3. Consider multi-threading implications (TBB integration) -4. Validate changes don't break existing profiles -5. Add regression tests where appropriate - -#### GUI Development -1. GUI code resides in `src/slic3r/GUI/` (not visible in current tree) -2. Use existing wxWidgets patterns and custom controls -3. Support both light and dark themes -4. Consider DPI scaling on high-resolution displays -5. Maintain cross-platform compatibility - -#### Adding Printer Support -1. Create JSON profile in `resources/profiles/[manufacturer].json` -2. Add printer-specific start/end G-code templates -3. Configure build volume, capabilities, and material compatibility -4. Test thoroughly with actual hardware when possible -5. Follow existing profile structure and naming conventions - -### Dependencies and Build System -- **CMake-based** with separate dependency building phase -- **Dependencies** built once in `deps/build/`, then linked to main application -- **Cross-platform** considerations important for all changes -- **Resource files** embedded at build time, platform-specific handling - -### Performance Considerations -- **Slicing algorithms** are CPU-intensive, profile before optimizing -- **Memory usage** can be substantial with complex models -- **Multi-threading** extensively used via TBB -- **File I/O** optimized for large 3MF files with embedded textures -- **Real-time preview** requires efficient mesh processing - -## Important Development Notes - -### Codebase Navigation -- Use search tools extensively - codebase has 500k+ lines -- Key entry points: `src/OrcaSlicer.cpp` for application startup -- Core slicing: `libslic3r/Print.cpp` orchestrates the slicing pipeline -- Configuration: `PrintConfig.cpp` defines all print/printer/material settings - -### Compatibility and Stability -- **Backward compatibility** maintained for project files and profiles -- **Cross-platform** support essential (Windows/macOS/Linux) -- **File format** changes require careful version handling -- **Profile migrations** needed when settings change significantly - -### Quality and Testing -- **Regression testing** important due to algorithm complexity -- **Performance benchmarks** help catch performance regressions -- **Memory leak** detection important for long-running GUI application -- **Cross-platform** testing required before releases +@AGENTS.md \ No newline at end of file diff --git a/build_linux.sh b/build_linux.sh index b23998b185..98201958f4 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -504,6 +504,15 @@ if [[ -n "${USE_LLD}" ]] ; then fi fi +# Auto-detect ccache for faster rebuilds +export CMAKE_CCACHE_ARGS=() +if command -v ccache >/dev/null 2>&1 ; then + echo "ccache found at $(command -v ccache), enabling compiler caching..." + export CMAKE_CCACHE_ARGS=(-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache) +else + echo "Note: ccache not found. Install ccache for faster rebuilds." +fi + if [[ -n "${BUILD_DEPS}" ]] ; then echo "Configuring dependencies..." read -r -a BUILD_ARGS <<< "${DEPS_EXTRA_BUILD_ARGS}" @@ -536,7 +545,7 @@ if [[ -n "${BUILD_ORCA}" ]] || [[ -n "${BUILD_TESTS}" ]] ; then BUILD_ARGS+=(-DORCA_UPDATER_SIG_KEY="${ORCA_UPDATER_SIG_KEY}") fi - print_and_run cmake -S . -B $BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" -G "Ninja Multi-Config" \ + print_and_run cmake -S . -B $BUILD_DIR "${CMAKE_C_CXX_COMPILER_CLANG[@]}" "${CMAKE_LLD_LINKER_ARGS[@]}" "${CMAKE_CCACHE_ARGS[@]}" -G "Ninja Multi-Config" \ -DSLIC3R_PCH=${SLIC3R_PRECOMPILED_HEADERS} \ -DORCA_TOOLS=ON \ "${COLORED_OUTPUT}" \ diff --git a/resources/web/data/text.js b/resources/web/data/text.js index e5d31d252c..77062dc00a 100644 --- a/resources/web/data/text.js +++ b/resources/web/data/text.js @@ -111,6 +111,7 @@ var LangText = { orca3: "Stealth Mode", orca4: "This stops the transmission of data to Bambu's cloud services. Users who don't use BBL machines or use LAN mode only can safely turn on this function.", orca5: "Enable Stealth Mode.", + orca6: "Bambu Cloud", }, ca_ES: { t1: "Benvingut a Orca Slicer", @@ -220,6 +221,7 @@ var LangText = { t113: "Pots canviar la teva elecció en les preferències en qualsevol moment.", orca1: "Editar Informació del Projecte", orca2: "no hi ha informació del model", + orca6: "Bambu Cloud", }, es_ES: { t1: "Bienvenido a Orca Slicer", @@ -333,6 +335,7 @@ var LangText = { orca3: "Modo sigiloso", orca4: "Esta función detiene la transmisión de datos a los servicios en la nube de Bambu. Los usuarios que no utilicen máquinas BBL o que solo usen el modo LAN pueden activar esta función con seguridad.", orca5: "Activar modo sigiloso.", + orca6: "Bambu Cloud", }, it_IT: { t1: "Benvenuti in OrcaSlicer", @@ -445,6 +448,7 @@ var LangText = { orca3: "Modalità invisibile", orca4: "Con questa modalità, la trasmissione dei dati ai servizi cloud di Bambu sarà interrotta. Gli utenti che non utilizzano macchine BBL o che usano solo la modalità LAN possono attivare questa funzione in modo sicuro.", orca5: "Abilita la modalità invisibile.", + orca6: "Bambu Cloud", }, de_DE: { t1: "Willkommen im Orca Slicer", @@ -548,6 +552,7 @@ var LangText = { t126: "Laden……", orca1: "Edit Project Info", orca2: "no model information", + orca6: "Bambu Cloud", }, cs_CZ: { t1: "Vítejte v Orca Slicer", @@ -651,6 +656,7 @@ var LangText = { t126: "Načtení probíhá……", orca1: "Edit Project Info", orca2: "no model information", + orca6: "Bambu Cloud", }, fr_FR: { t1: "Bienvenue sur Orca Slicer", @@ -773,6 +779,7 @@ var LangText = { wk14: "Par rapport au format STL, le format STEP apporte des informations plus efficaces. Grâce à la grande précision de ce format, de nombreuses trajectoires d'extrusion peuvent être générées sous forme d'arcs. Il inclut également la relation d'assemblage de chaque pièce d'un modèle, qui peut être utilisée pour restaurer la vue d'assemblage après la coupe d'un modèle.", wk15: "Texte 3D", wk16: "Avec l'outil Texte 3D, les utilisateurs peuvent facilement créer diverses formes de texte 3D dans le projet, ce qui rend le modèle plus personnalisé. Orca Slicer fournit des dizaines de polices et prend en charge les styles gras et italique pour donner au texte une plus grande flexibilité.", + orca6: "Bambu Cloud", }, zh_CN: { t1: "欢迎使用Orca Slicer", @@ -899,6 +906,7 @@ var LangText = { wk16: "使用3D文本工具,用户可以轻松地在项目中创建各种3D文本形状,使模型更加个性化。Orca Slicer提供了数十种字体,并支持粗体和斜体样式,使文本具有更大的灵活性。", orca1: "编辑项目信息", orca2: "该模型没有相关信息", + orca6: "Bambu Cloud", }, zh_TW: { t1: "歡迎使用 Orca Slicer", @@ -1004,6 +1012,7 @@ var LangText = { wk16: "使用3D文字工具,使用者可以輕鬆地在項目中建立各種3D文字形狀,使模型更加個性化。Orca Slicer 提供了數十種字體,並支援粗體和斜體樣式,使文字具有更大的靈活性。", orca1: "編輯專案資訊", orca2: "沒有模型相關資訊", + orca6: "Bambu Cloud", }, ru_RU: { t1: "Приветствуем в Orca Slicer!", @@ -1116,7 +1125,8 @@ var LangText = { orca2: "Информация отсутствует", orca3: "Режим конфиденциальности", orca4: "Это остановит передачу данных в облачные сервисы Bambu. Помешает только владельцам Bambu Lab, не использующим режим «Только LAN».", - orca5: "Включить режим конфиденциальности" + orca5: "Включить режим конфиденциальности", + orca6: "Bambu Cloud", }, ko_KR: { t1: "Orca Slicer에 오신 것을 환영합니다", @@ -1209,6 +1219,7 @@ var LangText = { t126: "로딩 중……", orca1: "Edit Project Info", orca2: "no model information", + orca6: "Bambu Cloud", }, tr_TR: { t1: "Orca Slicer'a hoş geldiniz", @@ -1322,6 +1333,7 @@ var LangText = { orca3: "Gizli Mod", orca4: "Bu, Bambu'nun bulut hizmetlerine veri iletimini durdurur. BBL makinelerini kullanmayan veya yalnızca LAN modunu kullanan kullanıcılar bu işlevi güvenle açabilir.", orca5: "Gizli Modu etkinleştirin.", + orca6: "Bambu Cloud", }, pl_PL: { t1: "Witamy w Orca Slicer", @@ -1435,6 +1447,7 @@ var LangText = { orca3: "Tryb «Niewidzialny»", orca4: "To wyłączy przesyłanie danych do usług chmurowych Bambu. Użytkownicy, którzy nie korzystają z maszyn BBL lub używają tylko trybu LAN, mogą bez obaw włączyć tę opcję.", orca5: "Włącz tryb «Niewidzialny»", + orca6: "Bambu Cloud", }, pt_BR: { t1: "Bem-vindo ao Orca Slicer", @@ -1548,6 +1561,7 @@ var LangText = { orca3: "Modo Furtivo", orca4: "Isso interrompe a transmissão de dados para os serviços de nuvem da Bambu. Usuários que não usam máquinas BBL ou usam somente o modo LAN podem ativar essa função com segurança.", orca5: "Habilita Modo Furtivo.", + orca6: "Bambu Cloud", }, lt_LT: { t1: "Pasisveikinkite su Orca Slicer", @@ -1660,6 +1674,7 @@ var LangText = { orca3: "Slaptas režimas", orca4: "Tai sustabdo duomenų perdavimą į Bambu debesijos paslaugas. Vartotojai, kurie nenaudoja BBL mašinų arba naudoja tik LAN režimą, gali drąsiai įjungti šią funkciją.", orca5: "Įjungti slaptą režimą.", + orca6: "Bambu Cloud", }, }; diff --git a/resources/web/dialog/ExportPresetDialog/index.html b/resources/web/dialog/ExportPresetDialog/index.html new file mode 100644 index 0000000000..e46147f236 --- /dev/null +++ b/resources/web/dialog/ExportPresetDialog/index.html @@ -0,0 +1,75 @@ + + + + + +Export Presets + + + + + + + + + + + + + + +
+
+
+
+ + printer +
+
+
+
+ +
+
No items
+
+
+ +
+
+
+ + filament +
+
+
+
+ +
+
No items
+
+
+ +
+
+
+ + presets +
+
+
+
+ +
+
No items
+
+
+
+ +
+
Export to OrcaCloud
+
Export to folder
+
Close
+
+ + + diff --git a/resources/web/dialog/ExportPresetDialog/index.js b/resources/web/dialog/ExportPresetDialog/index.js new file mode 100644 index 0000000000..e5c172e351 --- /dev/null +++ b/resources/web/dialog/ExportPresetDialog/index.js @@ -0,0 +1,374 @@ +var g_profile = { + machines: [], + filaments: [], + presets: [] +}; + +var g_search = { + machine: "", + filament: "", + preset: "" +}; + +function OnInit() +{ + if (typeof TranslatePage === "function") + TranslatePage(); + + InstallInputSafeKeydown(); + BindSearchInputs(); + BindClearIcons(); + BindBottomButtons(); + + // Always load demo data first so the page works without C++ backend. + // LoadDemoProfile(); + RequestProfile(); +} + +function InstallInputSafeKeydown() +{ + // common.js blocks all key events globally; allow typing in text inputs. + document.onkeydown = function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + var target = e && e.target ? e.target : null; + var tag = target && target.tagName ? String(target.tagName).toUpperCase() : ""; + var type = target && target.type ? String(target.type).toLowerCase() : ""; + + var editable = + !!(target && target.isContentEditable) || + tag === "TEXTAREA" || + (tag === "INPUT" && type !== "checkbox" && type !== "radio" && type !== "button" && type !== "submit"); + + if (editable) + return true; + + if (e && e.keyCode === 27 && typeof ClosePage === "function") + ClosePage(); + + if (window.event) { + try { e.keyCode = 0; } catch (err) { } + e.returnValue = false; + } + + if (e && typeof e.preventDefault === "function") + e.preventDefault(); + + return false; + }; +} + +function RequestProfile() +{ + SendMessage("request_export_preset_profile", {}); +} + +function HandleStudio(pVal) +{ + var payload = (typeof pVal === "string") ? SafeJsonParse(pVal) : pVal; + if (!payload || typeof payload !== "object") + return; + + var cmd = String(payload.command || ""); + if (cmd === "response_export_preset_profile" ) { + ApplyProfile(payload.data); + } +} + +function ApplyProfile(profile) +{ + + g_profile.machines = BuildNameRows(profile.printers); + g_profile.filaments = BuildNameRows(profile.filaments); + g_profile.presets = BuildNameRows(profile.process); + + RenderColumn("MachineList", g_profile.machines, "mode", "MachineClick"); + RenderColumn("FilatypeList", g_profile.filaments, "filatype", "FilaClick"); + RenderColumn("PresetList", g_profile.presets, "preset", "PresetClick"); + + ApplyColumnSearch("MachineList", g_search.machine); + ApplyColumnSearch("FilatypeList", g_search.filament); + ApplyColumnSearch("PresetList", g_search.preset); +} + +function BuildNameRows(names) +{ + var src = Array.isArray(names) ? names : []; + var out = []; + + for (var n = 0; n < src.length; n++) { + var row = src[n]; + if (row === undefined || row === null) + continue; + + var name = String(row); + out.push({ id: name, label: name, checked: false }); + } + + return out; +} + +function RenderColumn(listId, items, attrName, onChangeFn) +{ + var root = $("#" + listId + " .CValues"); + if (!root.length) + return; + + root.find("label:gt(0)").remove(); + + var html = ""; + for (var n = 0; n < items.length; n++) { + var one = items[n]; + html += ''; + } + + root.append(html); + SyncMasterCheckbox(listId); + ToggleNoItems(listId, items.length === 0); +} + +function ChooseAllMachine() +{ + var checked = !!$("#MachineList .CValues input:first").prop("checked"); + $("#MachineList .CValues input:gt(0)").prop("checked", checked); + SyncListFromDom("MachineList", g_profile.machines); +} + +function MachineClick() +{ + SyncMasterCheckbox("MachineList"); + SyncListFromDom("MachineList", g_profile.machines); +} + +function ChooseAllFilament() +{ + var checked = !!$("#FilatypeList .CValues input:first").prop("checked"); + $("#FilatypeList .CValues input:gt(0)").prop("checked", checked); + SyncListFromDom("FilatypeList", g_profile.filaments); +} + +function FilaClick() +{ + SyncMasterCheckbox("FilatypeList"); + SyncListFromDom("FilatypeList", g_profile.filaments); +} + +function ChooseAllPreset() +{ + var checked = !!$("#PresetList .CValues input:first").prop("checked"); + $("#PresetList .CValues input:gt(0)").prop("checked", checked); + SyncListFromDom("PresetList", g_profile.presets); +} + +function PresetClick() +{ + SyncMasterCheckbox("PresetList"); + SyncListFromDom("PresetList", g_profile.presets); +} + +function SyncMasterCheckbox(listId) +{ + var all = $("#" + listId + " .CValues input:gt(0)"); + var master = $("#" + listId + " .CValues input:first"); + + if (!all.length) { + master.prop("checked", false); + return; + } + + master.prop("checked", all.length === all.filter(":checked").length); +} + +function SyncListFromDom(listId, store) +{ + var map = {}; + for (var n = 0; n < store.length; n++) + map[store[n].id] = store[n]; + + $("#" + listId + " .CValues input:gt(0)").each(function () { + var id = String($(this).attr("data-key") || ""); + if (map[id]) + map[id].checked = !!$(this).prop("checked"); + }); +} + +function BindSearchInputs() +{ + var inputs = document.querySelectorAll(".cbr-search-bar"); + + if (inputs.length > 0) { + inputs[0].addEventListener("input", function () { + g_search.machine = String(this.value || "").toLowerCase(); + ApplyColumnSearch("MachineList", g_search.machine); + }); + } + + if (inputs.length > 1) { + inputs[1].addEventListener("input", function () { + g_search.filament = String(this.value || "").toLowerCase(); + ApplyColumnSearch("FilatypeList", g_search.filament); + }); + } + + if (inputs.length > 2) { + inputs[2].addEventListener("input", function () { + g_search.preset = String(this.value || "").toLowerCase(); + ApplyColumnSearch("PresetList", g_search.preset); + }); + } +} + +function ApplyColumnSearch(listId, query) +{ + var rows = $("#" + listId + " .CValues label:gt(0)"); + var visibleCount = 0; + + rows.each(function () { + var row = $(this); + var text = String(row.text() || "").toLowerCase(); + var key = String(row.find("input").attr("data-key") || "").toLowerCase(); + + if (!query || text.indexOf(query) >= 0 || key.indexOf(query) >= 0) { + row.show(); + visibleCount++; + } + else { + row.hide(); + } + }); + + ToggleNoItems(listId, visibleCount === 0); +} + +function ToggleNoItems(listId, show) +{ + var node = $("#" + listId + " .cbr-no-items"); + if (!node.length) + return; + + if (show) + node.addClass("show"); + else + node.removeClass("show"); +} + +function BindClearIcons() +{ + var icons = document.querySelectorAll(".clear-icon"); + + for (var n = 0; n < icons.length; n++) { + icons[n].addEventListener("click", function () { + var parent = this.parentElement; + if (!parent) + return; + + var input = parent.querySelector("input[type='text']"); + if (!input) + return; + + input.value = ""; + input.dispatchEvent(new Event("input", { bubbles: true })); + input.focus(); + }); + } +} + +function BindBottomButtons() +{ + var backBtn = document.getElementById("back_btn"); + var exportCloud = document.getElementById("export_cloud_btn") + var exportLocal = document.getElementById("export_local_btn"); + var closeBtn = document.getElementById("close_btn"); + + backBtn?.addEventListener("click", function () { + SendMessage("navigate_back", {}); + }); + + + exportLocal?.addEventListener("click", function () { + SendMessage("export_local", BuildResultPayload()); + }); + + + closeBtn?.addEventListener("click", () => { + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "close_page" + }; + SendWXMessage(JSON.stringify(tSend)); + }); +} + +function BuildResultPayload() +{ + return { + machines: g_profile.machines.filter(function (x) { return x.checked; }).map(function (x) { return x.id; }), + filaments: g_profile.filaments.filter(function (x) { return x.checked; }).map(function (x) { return x.id; }), + presets: g_profile.presets.filter(function (x) { return x.checked; }).map(function (x) { return x.id; }) + }; +} + +function LoadDemoProfile() +{ + ApplyProfile({ + machines: [ + { id: "printer_x1c_04", name: "X1 Carbon 0.4 nozzle", selected: 1 }, + { id: "printer_p1s_04", name: "P1S 0.4 nozzle", selected: 1 }, + { id: "printer_a1_04", name: "A1 0.4 nozzle", selected: 0 }, + { id: "printer_prusa_mk4_04", name: "Prusa MK4 0.4 nozzle", selected: 1 } + ], + filaments: [ + { id: "filament_generic_pla", name: "Generic PLA", selected: 1 }, + { id: "filament_generic_petg", name: "Generic PETG", selected: 1 }, + { id: "filament_bambu_abs", name: "Bambu ABS", selected: 0 }, + { id: "filament_esun_pla_plus", name: "eSUN PLA+", selected: 1 } + ], + presets: [ + { id: "preset_quality_020", name: "Quality 0.20mm", selected: 1 }, + { id: "preset_quality_012", name: "Quality 0.12mm", selected: 0 }, + { id: "preset_speed_024", name: "Speed 0.24mm", selected: 1 }, + { id: "preset_draft_028", name: "Draft 0.28mm", selected: 0 } + ] + }); +} + +function SendMessage(command, data) +{ + var msg = {}; + msg.sequence_id = Math.round(new Date() / 1000); + msg.command = command; + if (data && typeof data === "object") + msg.data = data; + + if (typeof SendWXMessage === "function") + SendWXMessage(JSON.stringify(msg)); +} + +function SafeJsonParse(str) +{ + try { + return JSON.parse(str); + } + catch (err) { + return null; + } +} + +function EscapeHtml(str) +{ + return String(str) + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/\"/g, """) + .replace(/'/g, "'"); +} + +function EscapeAttr(str) +{ + return EscapeHtml(str); +} diff --git a/resources/web/dialog/ExportPresetDialog/styles.css b/resources/web/dialog/ExportPresetDialog/styles.css new file mode 100644 index 0000000000..fd4d14946b --- /dev/null +++ b/resources/web/dialog/ExportPresetDialog/styles.css @@ -0,0 +1,191 @@ +:root { + --cbr-border-color: #d2d2d7; + --cbr-header-bg: #f6f7f9; + --cbr-panel-bg: #ffffff; + --cbr-input-bg: #ffffff; + --cbr-input-focus-bg: #f2f8f7; + --cbr-label-color: #7b7b84; + --cbr-icon-color: #75757f; +} + +@media (prefers-color-scheme: dark) { + :root { + --cbr-border-color: #4a4a51; + --cbr-header-bg: #2f2f34; + --cbr-panel-bg: #2d2d31; + --cbr-input-bg: #2d2d31; + --cbr-input-focus-bg: #3b3b41; + --cbr-label-color: #b9b9bc; + --cbr-icon-color: #b9b9bc; + } +} + +.cbr-browser-container { + flex: 1 1 auto; + min-height: 0; + margin: 10px 15px 0; + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + grid-template-rows: minmax(0, 1fr); + border: 1px solid var(--cbr-border-color); + background: var(--cbr-panel-bg); + box-sizing: border-box; +} + +.cbr-column { + min-width: 0; + min-height: 0; + display: flex; + flex-direction: column; + overflow: hidden; +} + +.cbr-column:not(:last-child) { + border-right: 1px solid var(--cbr-border-color); +} + +.cbr-column-title-container { + position: relative; + display: flex; + align-items: center; + min-height: 36px; + padding: 3px 6px; + background: var(--cbr-header-bg); + border-bottom: 1px solid var(--cbr-border-color); +} + +.cbr-search-bar { + width: 100%; + min-width: 0; + box-sizing: border-box; + font-size: 14px; + line-height: 22px; + padding: 2px 26px 2px 26px; + border: 1px solid transparent; + border-radius: 4px; + background: var(--cbr-input-bg); +} + +.cbr-search-bar:hover, +.cbr-search-bar:focus { + border-color: var(--main-color); + outline: none; +} + +.cbr-search-bar:focus { + background: var(--cbr-input-focus-bg); +} + +.cbr-search-placeholder { + position: absolute; + left: 33px; + top: 50%; + transform: translateY(-50%); + font-size: 14px; + line-height: 20px; + color: var(--cbr-label-color); + pointer-events: none; +} + +.cbr-search-bar:not(:placeholder-shown) + .cbr-search-placeholder { + opacity: 0; +} + +.search-icon, +.clear-icon { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 16px; + height: 16px; + display: flex; + align-items: center; + justify-content: center; + color: var(--cbr-icon-color); + line-height: 1; +} + +.search-icon { + left: 11px; + pointer-events: none; +} + +.search-icon::before { + content: ""; + width: 9px; + height: 9px; + box-sizing: border-box; + border: 1.8px solid currentColor; + border-radius: 50%; +} + +.search-icon::after { + content: ""; + position: absolute; + width: 5px; + height: 1.8px; + background: currentColor; + transform: rotate(45deg); + right: 0; + bottom: 2px; +} + +.clear-icon { + right: 11px; + cursor: pointer; + display: none; +} + +.clear-icon::before { + content: ""; + position: absolute; + width: 10px; + height: 1.8px; + background: currentColor; + transform: rotate(45deg); +} + +.clear-icon::after { + content: ""; + position: absolute; + width: 10px; + height: 1.8px; + background: currentColor; + transform: rotate(-45deg); +} + +.cbr-search-bar:not(:placeholder-shown) ~ .clear-icon { + display: flex; +} + +.cbr-content { + min-height: 0; + overflow-y: auto; + padding: 4px 8px; +} + +.cbr-column .CValues { + display: grid; +} + +.CValues label { + margin: 0 !important; + padding: 1px 0; +} + +.cbr-content .cbr-no-items { + display: none; + color: var(--cbr-label-color); + font-size: 12px; + padding-top: 6px; +} + +.cbr-content .cbr-no-items.show { + display: block; +} + +#AcceptArea { + border-top: 1px solid var(--cbr-border-color); +} + + diff --git a/resources/web/dialog/PresetBundleDialog/index.html b/resources/web/dialog/PresetBundleDialog/index.html new file mode 100644 index 0000000000..db0b45eeb1 --- /dev/null +++ b/resources/web/dialog/PresetBundleDialog/index.html @@ -0,0 +1,71 @@ + + + + + + Preset Bundle + + + + + + + + + + + + + + +
+
+
+ + + +
+ +
+
+ Name + Type + Version + Update +
+
+
+ +
+
+ Name + Type +
+
+
+
+
+ + +
+ +
Close
+
+ + + + + + + diff --git a/resources/web/dialog/PresetBundleDialog/index.js b/resources/web/dialog/PresetBundleDialog/index.js new file mode 100644 index 0000000000..b370fe8018 --- /dev/null +++ b/resources/web/dialog/PresetBundleDialog/index.js @@ -0,0 +1,375 @@ +// ========= Data Stores ========= +const bundlesById = new Map(); // bundleId -> bundle object +const printersByBundle = new Map(); // bundleId -> Map(index -> printerName) +const filamentsByBundle = new Map(); // bundleId -> Map(index -> filamentName) +const presetsByBundle = new Map(); // bundleId -> Map(index -> presetName) +const UPDATE_TOOLTIP = "Update available"; +const UNAUTHORIZED_TOOLTIP = "Unauthorized bundle"; + +// ========= DOM ========= +let topList = null; +let bottomList = null; + +let ctxMenu = null; +let contextRow = null; +let ctxMenuSubscribed = null; + +let ctxMenuDelete = null; + +let selectedBundleId = null; + +// ========= Init ========= +function OnInit() { + + topList = document.getElementById("topList"); + bottomList = document.getElementById("bottomList"); + ctxMenu = document.getElementById("ctxMenu"); + ctxMenuSubscribed = document.getElementById("unsubscribe_btn"); + ctxMenuDelete = document.getElementById("delete_btn"); + const closeBtn = document.getElementById("close_btn"); + const exportbtn = document.getElementById("export_btn"); + const refreshBtn = document.getElementById("refresh_btn"); + const autoUpdateToggle = document.getElementById("auto_update_toggle"); + + if (!topList || !bottomList) return; + TranslatePage(); + + // If wx side needs to request bundles after page load: + RequestBundles(); + + + refreshBtn?.addEventListener("click", () => { + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "refresh_bundles" + }; + SendWXMessage(JSON.stringify(tSend)); + }); + + autoUpdateToggle?.addEventListener("change", () => { + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "set_auto_update", + enabled: !!autoUpdateToggle.checked + }; + SendWXMessage(JSON.stringify(tSend)); + }); + // Hook selection on top list + topList.addEventListener("click", (e) => { + const cloudLink = e.target.closest(".bundle-cloud-link"); + if (cloudLink) { + e.preventDefault(); + e.stopPropagation(); + + const row = cloudLink.closest(".row"); + if (!row) return; + + selectTopRow(row); + selectedBundleId = String(row.dataset.id || ""); + renderBottomForBundle(selectedBundleId); + sendOpenBundleOnCloud(selectedBundleId); + return; + } + + const updateBtn = e.target.closest(".bundle-update-btn"); + if (updateBtn) { + e.stopPropagation(); + if (updateBtn.disabled) return; + + const row = updateBtn.closest(".row"); + if (!row) return; + + selectTopRow(row); + selectedBundleId = String(row.dataset.id || ""); + renderBottomForBundle(selectedBundleId); + sendUpdateBundleCommand(selectedBundleId); + return; + } + + const row = e.target.closest(".row"); + if (!row) return; + + selectTopRow(row); + selectedBundleId = String(row.dataset.id || ""); + renderBottomForBundle(selectedBundleId); + }); + + // for top list rows if right click open context menu + topList.addEventListener("contextmenu", (e) => { + const row = e.target.closest(".row"); + if (!row) return; // top rows only + + const bundleType = String(row.dataset.bundleType || "").toLowerCase(); + if (bundleType !== "subscribed") return; + + e.preventDefault(); + selectTopRow(row); + contextRow = row; + showSubscribedMenu(e.clientX, e.clientY); + }); + + // for top list rows except subscribed if right click open regular context menu + topList.addEventListener("contextmenu", (e) => { + const row = e.target.closest(".row"); + if (!row) return; // top rows only + const bundleType = String(row.dataset.bundleType || "").toLowerCase(); + if (bundleType === "subscribed") return; + + e.preventDefault(); + + selectTopRow(row); + contextRow = row; + showMenu(e.clientX, e.clientY); + }); + + ctxMenu?.addEventListener("click", (e) => { + const btn = e.target.closest("[data-action]"); + if (!btn || !contextRow) return; + + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "top_row_menu_action", + action: String(btn.dataset.action || ""), + bundle_id: String(contextRow.dataset.id || "") + }; + SendWXMessage(JSON.stringify(tSend)); + hideMenu(); + }); + + closeBtn?.addEventListener("click", () => { + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "close_page" + }; + SendWXMessage(JSON.stringify(tSend)); + }); + + exportbtn?.addEventListener("click", () => { + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "export_page" + }; + SendWXMessage(JSON.stringify(tSend)); + }); + + document.addEventListener("click", (e) => { + if (!e.target.closest(".ctx")) hideMenu(); + }); + document.addEventListener("keydown", (e) => { + if (e.key === "Escape") hideMenu(); + }); +} +// ========= wx bridge requests ========= + +function RequestBundles() { + var tSend={}; + tSend['sequence_id']=Math.round(new Date() / 1000); + tSend['command']="request_bundles"; + + SendWXMessage(JSON.stringify(tSend)); +} + +function HandleStudio(pVal) { + + const msg = (typeof pVal === "string") ? safeJsonParse(pVal) : pVal; + if (!msg || typeof msg !== "object") return; + + const strCmd = msg.command; + if (strCmd === "list_bundles") { + unpackPayload(msg); + renderTop(); + // auto-select first bundle if none selected + autoSelectFirstBundle(); + + const autoUpdateToggle = document.getElementById("auto_update_toggle"); + if (autoUpdateToggle) { + autoUpdateToggle.checked = !!msg.auto_update_enabled; + } + } +} + +// ========= Parse / store ========= +function unpackPayload(payload) { + bundlesById.clear(); + printersByBundle.clear(); + filamentsByBundle.clear(); + presetsByBundle.clear(); + + const list = payload?.data || []; + for (const bundle of list) { + const id = String(bundle.id ?? ""); + if (!id) continue; + + bundlesById.set(id, { + id, + name: bundle.name ?? "", + type: bundle.type ?? "", + version: bundle.version ?? "", + path: bundle.path ?? "", + update_available: Boolean(bundle.update_available) , + unauthorized: Boolean(bundle.unauthorized) + }); + + printersByBundle.set(id, new Map((bundle.printers || []).map((name, i) => [i, name]))); + filamentsByBundle.set(id, new Map((bundle.filaments || []).map((name, i) => [i, name]))); + presetsByBundle.set(id, new Map((bundle.presets || []).map((name, i) => [i, name]))); + } +} + +// ========= Render: top ========= +function renderTop() { + const bundles = Array.from(bundlesById.values()); + + topList.innerHTML = bundles.map(b => ` +
+
+ ${b.unauthorized + ? `!` + : b.update_available + ? `` + : ``} + ${ + b.type === "Subscribed" ? + `${escapeHtml(b.name)}` + : `${escapeHtml(b.name)}` + } +
+ ${escapeHtml(b.type)} + ${escapeHtml(b.version)} +
+ +
+
+ `).join(""); + } + +function sendOpenBundleOnCloud(bundleId) { + const bundle = bundlesById.get(String(bundleId || "")); + if (!bundle) return; + + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "open_bundle_on_cloud", + bundle_id: String(bundle.id || "") + }; + SendWXMessage(JSON.stringify(tSend)); +} + +function sendUpdateBundleCommand(bundleId) { + const bundle = bundlesById.get(String(bundleId || "")); + if (!bundle || bundle.unauthorized || !bundle.update_available) return; + + const tSend = { + sequence_id: Math.round(Date.now() / 1000), + command: "update_bundle", + bundle_id: String(bundle.id || "") + }; + SendWXMessage(JSON.stringify(tSend)); + } + +// ========= Render: bottom (for a selected bundle) ========= +function renderBottomForBundle(bundleId) { + const key = String(bundleId || ""); + const printers = printersByBundle.get(key) || new Map(); + const filaments = filamentsByBundle.get(key) || new Map(); + const presets = presetsByBundle.get(key) || new Map(); + + // Convert to a flat list of rows { typeLabel, name } + const rows = []; + + for (const [, name] of printers) rows.push({ type: "Printer", name }); + for (const [, name] of filaments) rows.push({ type: "Filament", name }); + for (const [, name] of presets) rows.push({ type: "Preset", name }); + + bottomList.innerHTML = rows.map((r, idx) => ` +
+ ${escapeHtml(r.name)} + ${escapeHtml(r.type)} +
+ `).join(""); +} + +// ========= Selection helpers ========= +function clearSelection() { + document.querySelectorAll(".row.selected").forEach(r => r.classList.remove("selected")); +} + +function selectTopRow(rowEl) { + // only clear selection in top list, not bottom + topList.querySelectorAll(".row.selected").forEach(r => r.classList.remove("selected")); + rowEl.classList.add("selected"); +} + +function autoSelectFirstBundle() { + if (selectedBundleId && bundlesById.has(selectedBundleId)) { + // reselect existing + const el = topList.querySelector(`.row[data-id="${cssEscape(selectedBundleId)}"]`); + if (el) selectTopRow(el); + renderBottomForBundle(selectedBundleId); + return; + } + + const first = topList.querySelector(".row"); + if (!first) { + bottomList.innerHTML = ""; + selectedBundleId = null; + return; + } + + selectTopRow(first); + selectedBundleId = first.dataset.id; + renderBottomForBundle(selectedBundleId); +} + +function showSubscribedMenu(x, y) { + if (!ctxMenu) return; + ctxMenu.style.left = `${x}px`; + ctxMenu.style.top = `${y}px`; + ctxMenu.hidden = false; + ctxMenuDelete.hidden = true; + ctxMenuSubscribed.hidden = false; +} + +function showMenu(x, y) { + if (!ctxMenu) return; + ctxMenu.style.left = `${x}px`; + ctxMenu.style.top = `${y}px`; + ctxMenu.hidden = false; + ctxMenuDelete.hidden = false; + ctxMenuSubscribed.hidden = true; +} + +function hideMenu() { + if (!ctxMenu) return; + ctxMenu.hidden = true; + ctxMenuSubscribed.hidden = true; + contextRow = null; +} +// ========= Utilities ========= +function safeJsonParse(s) { + try { return JSON.parse(s); } catch { return null; } +} + +function escapeHtml(str) { + return String(str) + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """) + .replaceAll("'", "'"); +} + +function escapeAttr(str) { + // minimal attribute escaping + return escapeHtml(str); +} + +function cssEscape(str) { + // basic css escape for attribute selectors + return String(str).replaceAll('"', '\\"'); +} diff --git a/resources/web/dialog/PresetBundleDialog/styles.css b/resources/web/dialog/PresetBundleDialog/styles.css new file mode 100644 index 0000000000..aa6ad9138b --- /dev/null +++ b/resources/web/dialog/PresetBundleDialog/styles.css @@ -0,0 +1,394 @@ +:root { + --bg: #ffffff; + --panel: #ffffff; + --border: #d8d8d8; + --border-strong: #e6e6e6; + --border-soft: #f0f0f0; + --col-sep: #e1e1e1; + + --text: #1f2328; + --row-hover: #f7f9fb; + --row-selected: #eaf2ff; + --row-selected-outline: #b7d0ff; + + --footer-bg: #fafafa; + --btn-bg: #ffffff; + --btn-border: #cccccc; + --btn-hover: #f0f0f0; + + --ctx-bg: #ffffff; + --ctx-border: #cccccc; + --ctx-hover: #efefef; +} + +html, body { + height: 100%; + margin: 0; + font-family: sans-serif; + background: var(--bg); + color: var(--text); + overflow: hidden; +} + +body { + display: flex; + flex-direction: column; +} + +/* App layout: split content + footer */ +.app { + flex: 1 1 auto; + min-height: 0; + overflow: hidden; +} + +/* Split panes */ +.split { + height: 100%; + display: grid; + grid-template-rows: auto minmax(0, 1.25fr) minmax(140px, 0.75fr); + gap: 8px; + padding: 8px; + box-sizing: border-box; + min-height: 0; + overflow: hidden; +} + +.top-toolbar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + padding: 0 2px; + } + + .toolbar-btn { + min-width: 92px; + } + + .auto-update-switch { + display: inline-flex; + align-items: center; + gap: 10px; + font-size: 13px; + font-weight: 600; + color: var(--text); + user-select: none; + cursor: pointer; + position: relative; + } + + .auto-update-switch input { + position: absolute; + opacity: 0; + pointer-events: none; + } + + .auto-update-label { + white-space: nowrap; + } + + .auto-update-slider { + position: relative; + width: 52px; + height: 24px; + flex: 0 0 52px; + border-radius: 999px; + background: #b9b9b9; + transition: background 0.2s ease; + box-sizing: border-box; + overflow: hidden; + } + + .auto-update-slider::before { + content: ""; + position: absolute; + top: 2px; + left: 2px; + width: 20px; + height: 20px; + border-radius: 50%; + background: #ffffff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28); + transition: transform 0.2s ease; + z-index: 2; + } + + .auto-update-text { + position: absolute; + top: 50%; + transform: translateY(-50%); + font-size: 9px; + font-weight: 700; + line-height: 1; + letter-spacing: 0.3px; + z-index: 1; + pointer-events: none; + } + + .auto-update-text-off { + right: 7px; + color: #ffffff; + } + + .auto-update-text-on { + left: 7px; + color: #ffffff; + opacity: 0.55; + } + + .auto-update-switch input:checked + .auto-update-slider { + background: var(--main-color); + } + + .auto-update-switch input:checked + .auto-update-slider::before { + transform: translateX(28px); + } + + .auto-update-switch input:checked + .auto-update-slider .auto-update-text-on { + opacity: 1; + } + + .auto-update-switch input:checked + .auto-update-slider .auto-update-text-off { + opacity: 0.55; + } + + .auto-update-switch input:not(:checked) + .auto-update-slider .auto-update-text-on { + opacity: 0.55; + } + + .auto-update-switch input:not(:checked) + .auto-update-slider .auto-update-text-off { + opacity: 1; + } + + .auto-update-switch input:focus-visible + .auto-update-slider { + outline: 2px solid var(--main-color); + outline-offset: 2px; + } + + .auto-update-switch input:disabled + .auto-update-slider { + opacity: 0.5; + } + +.pane { + min-height: 0; + border: 1px solid var(--border); + border-radius: 8px; + background: var(--panel); + display: grid; + grid-template-rows: auto 1fr; +} + +.hdr { + font-weight: 600; + font-size: 12px; + border-bottom: 1px solid var(--border-strong); + padding: 8px 10px; + display: grid; + gap: 10px; +} + +.top-cols { grid-template-columns: minmax(0, 2fr) 1fr 1fr 88px; } + .bot-cols { grid-template-columns: 2fr 1fr; } + + .top .row { grid-template-columns: minmax(0, 2fr) 1fr 1fr 88px; } + .bottom .row { grid-template-columns: 2fr 1fr; } + +.body { + min-height: 0; + overflow: hidden; +} + +.hdr > *, + .row > * { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + padding-right: 8px; + border-right: 1px solid var(--col-sep); + box-sizing: border-box; + } + + .hdr > *:last-child, + .row > *:last-child { + border-right: none; + padding-right: 0; + } + + .bundle-name-cell { + display: flex; + align-items: center; + gap: 8px; + } + + .bundle-name-text { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .bundle-cloud-link { + color: inherit; + cursor: pointer; + text-decoration: none; + text-underline-offset: 2px; + } + + .bundle-cloud-link:hover, + .bundle-cloud-link:focus-visible { + color: inherit; + text-decoration: underline; + } + + .bundle-status-icon, + .bundle-status-icon-spacer { + flex: 0 0 14px; + width: 14px; + height: 14px; + } + + .bundle-status-icon { + display: inline-flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background: #f59e0b; + color: #fff; + font-size: 10px; + font-weight: 700; + line-height: 14px; + } + + .bundle-status-icon-unauthorized { + background: #dc2626; + } + + .bundle-status-icon-update { + background: var(--main-color); + font-size: 12px; + } + + .bundle-update-cell { + display: flex; + align-items: center; + justify-content: flex-start; + } + + .bundle-update-btn { + box-sizing: border-box; + min-width: 64px; + height: 20px; + line-height: 18px; + padding: 0 8px; + border-radius: 4px; + font-size: 11px; + cursor: pointer; + border: 1px solid transparent; + } + + .bundle-update-btn.is-enabled { + background: var(--main-color); + color: var(--button-fg-light); + } + + .bundle-update-btn.is-enabled:hover { + background: var(--main-color-hover); + } + + .bundle-update-btn.is-disabled { + background: var(--button-bg-disabled); + color: var(--button-fg-disabled); + cursor: not-allowed; + } + + +#topList, +#bottomList { + min-height: 0; + overflow-y: auto; + overflow-x: hidden; +} + +/* Column separators + clipping */ + +.row { + padding: 8px 10px; + border-bottom: 1px solid var(--border-soft); + display: grid; + gap: 10px; + font-size: 13px; + white-space: nowrap; + cursor: pointer; +} + + +.row:hover { background: var(--row-hover); } + +.row.selected { + background: var(--row-selected); + outline: 1px solid var(--row-selected-outline); +} + +/* Footer styling +.footer { + border-top: 1px solid var(--border); + padding: 10px 16px; + background: var(--footer-bg); + display: flex; + justify-content: flex-end; + gap: 12px; +} + +.footer-btn { + padding: 8px 16px; + border-radius: 6px; + border: 1px solid var(--btn-border); + background: var(--btn-bg); + color: var(--text); + cursor: pointer; + font-size: 13px; +} + +.footer-btn:hover { background: var(--btn-hover); } */ + +/* Context menu */ +.ctx { + position: fixed; + min-width: 180px; + background: var(--ctx-bg); + border: 1px solid var(--ctx-border); + border-radius: 6px; + box-shadow: 0 8px 20px rgba(0,0,0,.18); + padding: 4px; + z-index: 9999; +} + +.ctx-item, +.ctx-item-subscribed, .ctx-item-delete { + display: block; + width: 100%; + text-align: left; + border: 0; + background: transparent; + color: var(--text); + padding: 8px 10px; + cursor: pointer; + border-radius: 4px; +} + +.ctx-item:hover, +.ctx-item-subscribed:hover , +.ctx-item-delete:hover +{ background: var(--ctx-hover); } + +.ctx-item[hidden], +.ctx-item-subscribed[hidden] , +.ctx-item-delete[hidden]{ + display: none; +} + +#AcceptArea { + flex: 0 0 auto; +} diff --git a/resources/web/dialog/css/common.css b/resources/web/dialog/css/common.css new file mode 100644 index 0000000000..b8bee5dc42 --- /dev/null +++ b/resources/web/dialog/css/common.css @@ -0,0 +1,173 @@ +* +{ + padding: 0; + border: 0; + margin: 0; + font-family: "system-ui", "Segoe UI", Roboto, Oxygen, Ubuntu, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-sans; + user-select: none; +} + +html +{ + height:100%; + background-color: #626262; +} + +body +{ + height:100%; + max-height: 660px; + max-width: 820px; + padding: 0; + border: 0; + margin: 0; + overflow: hidden; + background-color: #fff; + font-size: 14px; + line-height: 22px; +} + +.TextPoint +{ + font-size:1px; +} + +.ZScrol::-webkit-scrollbar {/*滚动条整体样式*/ + width: 12px; /*高宽分别对应横竖滚动条的尺寸*/ + height: 12px; + padding: 2px; +} + +.ZScrol::-webkit-scrollbar-thumb {/*滚动条里面小方块*/ + border-radius: 6px; + -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); + box-shadow: inset 0 0 5px rgba(0,0,0,0.2); + background-color: #AAAAAA; +} + +.ZScrol::-webkit-scrollbar-track {/*滚动条里面轨道*/ + -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2); + box-shadow: inset 0 0 5px rgba(0,0,0,0.2); + border-radius: 10px; + background: #EDEDED; +} + +/*----Three Part----*/ +body +{ + display:flex; + flex-direction: column; +} + + +#Title +{ + height: 12%; + display: flex; + text-align: center; + flex-direction:column; + justify-content: center; +} + +#Title div +{ + font-size:28px; + line-height: 28px; + color: #009688; + padding: 0px 10mm; +} + + +#Content +{ + height: 76%; + padding: 20px 40px; + overflow-x: hidden; + overflow-y: auto; + text-align: left; + font-size: 14px; + line-height: 22px; + color: #464646; + position: relative; + display:flex; + flex-direction: column; +} + +#Content div +{ + +} + + +#AcceptArea +{ + height:var(--dialog-button-sizer-height); /*----ORCA Use fixed size to prevent position change----*/ + max-height:var(--dialog-button-sizer-height); + min-height:var(--dialog-button-sizer-height); + padding: 0 var(--dialog-button-gap); + text-align: left; + display: flex; + justify-content:flex-end; + align-items: center; +} + +/*---HyperLink---*/ +.HyperLink +{ + color: #009688; + text-decoration: underline; + font-weight: 700; + cursor: pointer; +} + +/*---Checkboxes ORCA ---*/ +label:has(input[type="checkbox"]){ + margin:0; + padding: 0; + margin-right: 20px; +} + +label:has(input[type="checkbox"])>span{ + vertical-align: middle; + margin:0; +} + +input[type="checkbox"] { + -webkit-appearance: none; + appearance: none; + background-color:#FFFFFF; + margin:0; + margin-right: 6px; + width: 1em; + height: 1em; + border: 0.1em solid #DBDBDB; + border-radius: 0.15em; + display: inline-flex; + place-content: center; + background-color:#FFFFFF; +} + +input[type="checkbox"]::before { + content: ""; + width: 0.8em; + height: 0.8em; + transform: scale(0); + box-shadow: inset 1em 1em #FFFFFF; + clip-path: polygon(7% 37%, 0 45%, 33% 78%, 100% 30%, 95% 21%, 33% 64%); +} + +input[type="checkbox"]:checked { + border-color:#009688; + background-color:#009688; +} + +input[type="checkbox"]:checked::before { + transform: scale(1); +} + +/*----------------Light Mode-------------------*/ + + + + + diff --git a/resources/web/dialog/css/dark.css b/resources/web/dialog/css/dark.css new file mode 100644 index 0000000000..de55d6cba7 --- /dev/null +++ b/resources/web/dialog/css/dark.css @@ -0,0 +1,100 @@ +:root { + --bg: #1b1f24; + --panel: #242a31; + --border: #3a424d; + --border-strong: #3a424d; + --border-soft: #313843; + --col-sep: #3a424d; + + --text: #e6ebf0; + --row-hover: #2b3340; + --row-selected: #244945; + --row-selected-outline: #00bfa5; + + --footer-bg: #20262d; + --btn-bg: #2a313a; + --btn-border: #4b5664; + --btn-hover: #333c47; + + --ctx-bg: #2a313a; + --ctx-border: #4b5664; + --ctx-hover: #3a4451; +} + +* +{ + color: #efeff0; + border-color: #B9B9BC; +} + +body +{ + background-color:#2D2D31; /* ORCA match background color */ + color: #efeff0; +} + +.ZScrol::-webkit-scrollbar-thumb {/*滚动条里面小方块*/ + background-color: #939594; +} + +.ZScrol::-webkit-scrollbar-track {/*滚动条里面轨道*/ + background: #161817; +} + +#Title div +{ + color: #009688; +} + +.search>input[type=text]{ + background-color:#2D2D31; +} + +/*---Checkboxes ORCA---*/ +input[type=checkbox]{ + background-color:#2D2D31; + border-color:#4A4A51; +} + +input[type=checkbox]:checked{ + background-color:#009688; +} + +/*-------Text------*/ + +.TextS1 +{ + +} + +.TextS2 +{ + color:#B9B9BC; +} + +/*---Policy---*/ +.TextArea1 +{ + background-color: #4A4A51; + color: #BEBEC0; +} + +/*----Region---*/ +.RegionItem:hover +{ + background-color:#4C4C55; +} + +.RegionSelected:hover +{ + background-color:#009688; + color: #fff; +} + +/*----Menu----*/ +#Title div.TitleUnselected +{ + color: #BEBEC0; +} + + diff --git a/resources/web/dialog/css/home.css b/resources/web/dialog/css/home.css new file mode 100644 index 0000000000..c086b41a84 --- /dev/null +++ b/resources/web/dialog/css/home.css @@ -0,0 +1,35 @@ +#FullArea +{ + height:100%; +} + + +#LoadProgress +{ + position:fixed; + top: 0px; + left: 0px; + width: 100%; + height: 3mm; + display: none; +} + +#PercentTip +{ + width:70%; + height: 100%; + background-color: #335DFC; +} + + +#PageArea +{ + width:100%; + height: 100%; +} + +#IEPage +{ + height:100%; + width: 100%; +} diff --git a/resources/web/dialog/css/test.css b/resources/web/dialog/css/test.css new file mode 100644 index 0000000000..f37ded3189 --- /dev/null +++ b/resources/web/dialog/css/test.css @@ -0,0 +1,58 @@ +* +{ + padding: 0; + border: 0; + margin: 0; +} + + +html,body +{ + height:100%; + padding: 0; + border: 0; + margin: 0; + overflow: hidden; + background-color: #fff; +} + +#PageArea +{ + height:100%; + width: 100%; +} + +.swiper { + height: 100%; + top: 0px; + left: 0px; + bottom: 35px; +} + +.swiper-slide { + font-size: 18px; + height: 100%; + width: 100%; + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.swiper-slide iframe +{ + width:100%; + height: 100%; + overflow-y: hidden; +} + +.CBtn +{ + padding: 3mm 100m; + background-color: #77EFF9; + display: inline-block; + height: 30px; + width: 150px; + text-align: center; + z-index: 99; + position: absolute; + top:30px; +} \ No newline at end of file diff --git a/resources/web/dialog/js/common.js b/resources/web/dialog/js/common.js new file mode 100644 index 0000000000..b0aafeaf37 --- /dev/null +++ b/resources/web/dialog/js/common.js @@ -0,0 +1,21 @@ +function ClosePage() { + var tSend = {}; + tSend['sequence_id'] = Math.round(new Date() / 1000); + tSend['command'] = "close_page"; + SendWXMessage(JSON.stringify(tSend)); +} + +document.onkeydown = function (event) { + var e = event || window.event || arguments.callee.caller.arguments[0]; + + if (window.event) { + try { e.keyCode = 0; } catch (e) { } + e.returnValue = false; + } +}; + +window.addEventListener('wheel', function (event) { + if (event.ctrlKey === true || event.metaKey) { + event.preventDefault(); + } +}, { passive: false }); diff --git a/resources/web/login/js/globalapi.js b/resources/web/dialog/js/globalapi.js similarity index 83% rename from resources/web/login/js/globalapi.js rename to resources/web/dialog/js/globalapi.js index 3d56015018..2463dbe537 100644 --- a/resources/web/login/js/globalapi.js +++ b/resources/web/dialog/js/globalapi.js @@ -277,4 +277,63 @@ function SendWXMessage( strMsg ) } } +/*------CSS Link Control----*/ +function RemoveCssLink( LinkPath ) +{ + let pNow=$("head link[href='"+LinkPath+"']"); + + let nTotal=pNow.length; + for( let n=0;n0) + RemoveCssLink(DarkCssPath); + } + else + { + if(nNow==0) + AddCssLink(DarkCssPath); + } +} + +SwitchDarkMode( "../css/dark.css" ); \ No newline at end of file diff --git a/resources/web/dialog/js/home.js b/resources/web/dialog/js/home.js new file mode 100644 index 0000000000..78b1b96b7b --- /dev/null +++ b/resources/web/dialog/js/home.js @@ -0,0 +1,12 @@ + + + +function NextSlide() +{ + $('.swiper-button-next').click(); +} + +function PreSlide() +{ + $('.swiper-button-prev').click(); +} \ No newline at end of file diff --git a/resources/web/dialog/js/jquery-2.1.1.min.js b/resources/web/dialog/js/jquery-2.1.1.min.js new file mode 100644 index 0000000000..e150866a71 --- /dev/null +++ b/resources/web/dialog/js/jquery-2.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b) +},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("