@363045841yyt/klinechart 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- .kline-tooltip[data-v-d0fe85e6]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:200px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.kline-tooltip__title[data-v-d0fe85e6]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.kline-tooltip__grid[data-v-d0fe85e6]{grid-template-columns:1fr;gap:2px;display:grid}.kline-tooltip__grid .row[data-v-d0fe85e6]{justify-content:space-between;gap:10px;display:flex}.kline-tooltip__grid .row span[data-v-d0fe85e6]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.kline-tooltip.use-anchor[data-v-d0fe85e6]{position-anchor:--kline-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.kline-tooltip.use-anchor.anchor-right-bottom[data-v-d0fe85e6]{transform:translate(14px,14px)}.kline-tooltip.use-anchor.anchor-left-bottom[data-v-d0fe85e6]{transform:translate(calc(-100% - 14px),14px)}}.marker-tooltip[data-v-5574cc25]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:180px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.marker-tooltip__title[data-v-5574cc25]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.marker-tooltip__content[data-v-5574cc25]{grid-template-columns:1fr;gap:2px;display:grid}.marker-tooltip__content .row[data-v-5574cc25]{justify-content:space-between;gap:10px;display:flex}.marker-tooltip__content .row span[data-v-5574cc25]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.marker-tooltip.use-anchor[data-v-5574cc25]{position-anchor:--marker-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.marker-tooltip.use-anchor.anchor-right-bottom[data-v-5574cc25]{transform:translate(12px,12px)}.marker-tooltip.use-anchor.anchor-left-bottom[data-v-5574cc25]{transform:translate(calc(-100% - 12px),12px)}}.params-overlay[data-v-bb1d1eb3]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.indicator-params[data-v-bb1d1eb3]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.params-header[data-v-bb1d1eb3]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-bb1d1eb3]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-bb1d1eb3]{align-items:center;gap:8px;display:flex}.params-title[data-v-bb1d1eb3]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-bb1d1eb3]{color:#999;font-size:11px}.toggle-desc-btn[data-v-bb1d1eb3]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:all .2s;display:flex}.toggle-desc-btn[data-v-bb1d1eb3]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-bb1d1eb3]{width:14px;height:14px}.params-close[data-v-bb1d1eb3]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.params-close[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-bb1d1eb3]{width:14px;height:14px}.indicator-description[data-v-bb1d1eb3]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-bb1d1eb3]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-bb1d1eb3]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-bb1d1eb3]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-bb1d1eb3]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-bb1d1eb3]{padding:10px 14px 8px}.param-header[data-v-bb1d1eb3]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-bb1d1eb3]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-bb1d1eb3]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-bb1d1eb3]{color:#999;font-size:11px}.param-description[data-v-bb1d1eb3]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-bb1d1eb3]{background:#fff;border:1px solid #d0d0d0;border-radius:7px;align-items:stretch;height:32px;transition:border-color .2s;display:flex;overflow:hidden}.input-wrapper[data-v-bb1d1eb3]:focus-within{border-color:#999}.stepper-btn[data-v-bb1d1eb3]{cursor:pointer;color:#666;background:#f0f0f0;border:none;flex-shrink:0;justify-content:center;align-items:center;width:28px;font-size:15px;font-weight:400;line-height:1;transition:background .15s,color .15s;display:flex}.stepper-btn[data-v-bb1d1eb3]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-bb1d1eb3]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-bb1d1eb3]{text-align:center;color:#1a1a1a;appearance:textfield;background:0 0;border:none;border-left:1px solid #e8e8e8;border-right:1px solid #e8e8e8;width:60px;font-size:13px;font-weight:600}.param-input[data-v-bb1d1eb3]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]:focus{outline:none}.params-footer[data-v-bb1d1eb3]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-bb1d1eb3]{gap:8px;display:flex}.params-btn[data-v-bb1d1eb3]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.params-btn svg[data-v-bb1d1eb3]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-bb1d1eb3]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-bb1d1eb3]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-bb1d1eb3]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-bb1d1eb3],.overlay-leave-active[data-v-bb1d1eb3]{transition:opacity .2s}.overlay-enter-from[data-v-bb1d1eb3],.overlay-leave-to[data-v-bb1d1eb3]{opacity:0}.modal-enter-active[data-v-bb1d1eb3]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-bb1d1eb3]{transition:all .16s ease-in}.modal-enter-from[data-v-bb1d1eb3]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-bb1d1eb3]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-bb1d1eb3],.slide-leave-active[data-v-bb1d1eb3]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-bb1d1eb3],.slide-leave-to[data-v-bb1d1eb3]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-0f3a76b5]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-0f3a76b5]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-0f3a76b5]::-webkit-scrollbar{display:none}.indicator-list[data-v-0f3a76b5]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-0f3a76b5]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-0f3a76b5]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-0f3a76b5],.indicator-item.draggable .indicator-btn[data-v-0f3a76b5],.indicator-item.draggable[data-v-0f3a76b5]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-0f3a76b5]{cursor:move}.indicator-item.is-dragging[data-v-0f3a76b5]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-0f3a76b5]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-0f3a76b5]{position:relative}.indicator-btn[data-v-0f3a76b5]{color:#666;cursor:pointer;white-space:nowrap;background:#fff;border:1px solid #e0e0e0;border-radius:16px;flex-shrink:0;justify-content:center;align-items:center;gap:4px;padding:6px 16px;font-size:13px;font-weight:500;transition:all .3s;display:flex;position:relative;overflow:hidden}.indicator-btn[data-v-0f3a76b5]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-0f3a76b5]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-0f3a76b5]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-0f3a76b5]{z-index:1;position:relative}.param-hint[data-v-0f3a76b5]{opacity:.85;font-size:11px}.hover-overlay[data-v-0f3a76b5]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2;background:#ffffffd9;border-radius:16px;justify-content:center;align-items:center;gap:4px;display:flex;position:absolute;inset:0}.action-btn[data-v-0f3a76b5]{color:#666;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:all .2s;display:flex}.action-btn[data-v-0f3a76b5]:hover{color:#333;background:#0000000f}.settings-btn[data-v-0f3a76b5]:hover{color:#1a1a1a}.remove-btn[data-v-0f3a76b5]:hover{color:#ff4d4f}.divider[data-v-0f3a76b5]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-0f3a76b5]{anchor-name:--indicator-add-btn;color:#999;cursor:pointer;background:0 0;border:1px dashed #d9d9d9;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;padding:0;transition:all .3s;display:flex}.add-btn[data-v-0f3a76b5]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-0f3a76b5]{white-space:nowrap;z-index:9999;background:#fff;border-radius:8px;padding:8px 0;position:fixed;transform:translate(-50%);box-shadow:0 6px 16px #00000014,0 3px 6px -4px #0000001f,0 9px 28px 8px #0000000d}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.add-menu.use-anchor[data-v-0f3a76b5]{position-anchor:--indicator-add-btn;left:anchor(center);top:anchor(top);max-width:calc(100vw - 16px);position:fixed;transform:translate(-50%,calc(-100% - 8px))}}.menu-section[data-v-0f3a76b5]{padding:4px 0}.menu-section[data-v-0f3a76b5]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-0f3a76b5]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-0f3a76b5]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-0f3a76b5]{text-align:left;color:#333;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:8px 16px;font-size:13px;transition:background .2s;display:flex}.menu-item[data-v-0f3a76b5]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-0f3a76b5]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-0f3a76b5]{color:#999;font-size:11px}.active-tag[data-v-0f3a76b5]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-0f3a76b5],.fade-leave-active[data-v-0f3a76b5]{transition:opacity .2s}.fade-enter-from[data-v-0f3a76b5],.fade-leave-to[data-v-0f3a76b5]{opacity:0}.slide-enter-active[data-v-0f3a76b5],.slide-leave-active[data-v-0f3a76b5]{transition:all .2s}.slide-enter-from[data-v-0f3a76b5],.slide-leave-to[data-v-0f3a76b5]{opacity:0;transform:translate(-50%)translateY(8px)}.drawing-style-toolbar[data-v-92699cb2]{-webkit-backdrop-filter:blur(8px);z-index:100;-webkit-user-select:none;user-select:none;pointer-events:auto;background:#fafbfce0;border:1px solid #e5e7eb;border-radius:6px;align-items:center;gap:6px;height:32px;padding:4px 8px;display:flex;position:absolute;top:8px;left:50%;transform:translate(-50%);box-shadow:0 1px 3px #0000000f}.toolbar-item[data-v-92699cb2]{justify-content:center;align-items:center;display:inline-flex}.color-item[data-v-92699cb2]{width:24px;height:24px;position:relative}.color-swatch[data-v-92699cb2]{cursor:pointer;border:1px solid #d1d5db;border-radius:4px;width:100%;height:100%;display:block}.color-input[data-v-92699cb2]{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.toolbar-select[data-v-92699cb2]{color:#374151;cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:4px;outline:none;height:24px;padding:0 4px;font-size:12px}.toolbar-select[data-v-92699cb2]:hover{border-color:#9ca3af}.toolbar-btn[data-v-92699cb2]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex}.toolbar-btn[data-v-92699cb2]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.delete-btn[data-v-92699cb2]:hover{color:#dc2626;background:#fef2f2;border-color:#fca5a5}.delete-icon[data-v-92699cb2]{width:14px;height:14px}.left-toolbar[data-v-43b6f5f6]{box-sizing:border-box;-webkit-user-select:none;user-select:none;background:#fafbfc;border:1px solid #e5e7eb;border-radius:6px;flex-direction:column;flex:0 0 40px;align-items:center;gap:6px;padding:8px 5px;display:flex;box-shadow:0 1px 3px #0000000f}.left-toolbar__group[data-v-43b6f5f6]{flex-direction:column;gap:4px;display:flex}.left-toolbar__divider[data-v-43b6f5f6]{background:#e5e7eb;width:18px;height:1px}.left-toolbar__button[data-v-43b6f5f6]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex;position:relative}.left-toolbar__button[data-v-43b6f5f6]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.left-toolbar__button.active[data-v-43b6f5f6]{color:#1f2937;background:#e5e7eb;border-color:#9ca3af}.left-toolbar__button[data-v-43b6f5f6]:focus-visible{border-color:#6b7280;outline:none}.tool-icon[data-v-43b6f5f6]{width:16px;height:16px}.corner-indicator[data-v-43b6f5f6]{cursor:pointer;width:8px;height:8px;position:absolute;bottom:0;right:0;overflow:hidden}.corner-indicator[data-v-43b6f5f6]:after{content:"";opacity:.45;border-bottom:5px solid;border-left:5px solid #0000;width:0;height:0;transition:opacity .15s;position:absolute;bottom:0;right:0}.left-toolbar__button:hover .corner-indicator[data-v-43b6f5f6]:after,.left-toolbar__button.active .corner-indicator[data-v-43b6f5f6]:after{opacity:.7}.corner-indicator.open[data-v-43b6f5f6]:after{opacity:.8}.tool-dropdown[data-v-43b6f5f6]{-webkit-backdrop-filter:blur(8px);box-sizing:border-box;z-index:100;background:#fafbfcd1;border:1px solid #e5e7eb;border-radius:6px;flex-direction:row;align-items:center;gap:4px;height:40px;padding:0 5px;display:flex;position:absolute;top:50%;left:calc(100% + 13px);transform:translateY(-50%);box-shadow:0 1px 3px #0000000f}.tool-item[data-v-43b6f5f6]{position:relative}.dropdown-enter-active[data-v-43b6f5f6],.dropdown-leave-active[data-v-43b6f5f6]{transition:opacity .15s,transform .15s}.dropdown-enter-from[data-v-43b6f5f6],.dropdown-leave-to[data-v-43b6f5f6]{opacity:0;transform:translateY(-50%)translate(-6px)}@media (width<=768px),(height<=640px){.left-toolbar[data-v-43b6f5f6]{border-radius:5px;flex-basis:36px;gap:5px;padding:6px 4px}.left-toolbar__group[data-v-43b6f5f6]{gap:3px}.left-toolbar__button[data-v-43b6f5f6]{border-radius:3px;width:26px;height:26px}.left-toolbar__divider[data-v-43b6f5f6]{width:16px}.corner-indicator[data-v-43b6f5f6]{width:7px;height:7px}.corner-indicator[data-v-43b6f5f6]:after{border-bottom-width:4px;border-left-width:4px}.tool-dropdown[data-v-43b6f5f6]{height:36px}}.settings-overlay[data-v-43b6f5f6]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.settings-modal[data-v-43b6f5f6]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.settings-header[data-v-43b6f5f6]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-43b6f5f6]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-43b6f5f6]{align-items:center;gap:8px;display:flex}.settings-title[data-v-43b6f5f6]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.settings-subtitle[data-v-43b6f5f6]{color:#999;font-size:11px}.settings-close[data-v-43b6f5f6]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.settings-close[data-v-43b6f5f6]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.settings-close svg[data-v-43b6f5f6]{width:14px;height:14px}.settings-body[data-v-43b6f5f6]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.settings-item[data-v-43b6f5f6]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:8px 12px}.settings-label[data-v-43b6f5f6]{color:#333;cursor:pointer;justify-content:space-between;align-items:center;font-size:13px;display:flex}.settings-checkbox[data-v-43b6f5f6]{cursor:pointer;accent-color:#1a1a1a;width:16px;height:16px}.settings-section-divider[data-v-43b6f5f6]{align-items:center;gap:8px;margin-top:4px;display:flex}.settings-section-divider[data-v-43b6f5f6]:before,.settings-section-divider[data-v-43b6f5f6]:after{content:"";border-top:1px solid #e0e0e0;flex:1}.settings-section-label[data-v-43b6f5f6]{color:#999;white-space:nowrap;font-size:11px}.settings-item.experimental[data-v-43b6f5f6]{background:#fdf8f3;border-color:#f0e0d0}.settings-footer[data-v-43b6f5f6]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-43b6f5f6]{gap:8px;display:flex}.settings-btn[data-v-43b6f5f6]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.settings-btn svg[data-v-43b6f5f6]{flex-shrink:0;width:12px;height:12px}.settings-btn.reset[data-v-43b6f5f6]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.reset[data-v-43b6f5f6]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.settings-btn.cancel[data-v-43b6f5f6]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.cancel[data-v-43b6f5f6]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.settings-btn.confirm[data-v-43b6f5f6]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.settings-btn.confirm[data-v-43b6f5f6]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.settings-btn.confirm[data-v-43b6f5f6]:active{box-shadow:none;transform:translateY(0)}.chart-wrapper[data-v-59c0bc54]{--kmap-height:var(--kmap-chart-height,100%);--kmap-width:var(--kmap-chart-width,100%);width:var(--kmap-width);height:var(--kmap-height);flex-direction:column;justify-content:center;align-items:center;min-height:300px;display:flex}.chart-stage[data-v-59c0bc54]{align-items:stretch;gap:8px;width:95%;height:85%;min-height:255px;display:flex}.chart-main[data-v-59c0bc54]{flex:auto;align-items:stretch;gap:0;min-width:0;height:100%;display:flex;position:relative}.pane-separator-layer[data-v-59c0bc54]{pointer-events:none;z-index:20;position:absolute;inset:0}.pane-separator-line[data-v-59c0bc54]{opacity:1;box-sizing:border-box;border-top:1px solid #e5e7eb;height:0;transition:border-top-color .12s,border-top-width .12s,margin-top .12s,opacity .12s;position:absolute;left:0;right:0}.pane-separator-line.is-active[data-v-59c0bc54]{border-top-width:2px;border-top-color:#3b82f6;margin-top:-1px}.chart-stage.is-resizing-pane[data-v-59c0bc54],.chart-stage.is-hovering-pane-separator[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-hovering-kline[data-v-59c0bc54]{cursor:pointer}.chart-stage.is-hovering-right-axis[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-dragging[data-v-59c0bc54]{cursor:grabbing}.chart-container[data-v-59c0bc54]{height:100%;min-height:inherit;scrollbar-width:none;-ms-overflow-style:none;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;background:#fff;border:1px solid #e5e7eb;border-right:0;border-radius:6px 0 0 6px;flex:auto;position:relative;overflow:auto hidden}.chart-container[data-v-59c0bc54]::-webkit-scrollbar{display:none}.chart-container[data-v-59c0bc54]:hover{cursor:crosshair}.chart-stage.is-resizing-pane .chart-container[data-v-59c0bc54],.chart-stage.is-hovering-pane-separator .chart-container[data-v-59c0bc54]{cursor:ns-resize}.chart-stage.is-hovering-kline .chart-container[data-v-59c0bc54]{cursor:pointer}.chart-stage.is-dragging .chart-container[data-v-59c0bc54]{cursor:grabbing}.right-axis-host[data-v-59c0bc54]{height:100%;min-height:inherit;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;background:#fff;border:1px solid #e5e7eb;border-top-right-radius:6px;border-bottom-right-radius:6px;flex:none;position:relative;overflow:visible}.scroll-content[data-v-59c0bc54]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-59c0bc54]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-layer[data-v-59c0bc54]{pointer-events:none;z-index:30;position:absolute;inset:0}.tooltip-anchor[data-v-59c0bc54]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-59c0bc54]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-59c0bc54]{anchor-name:--marker-tooltip-anchor}@media (width<=768px),(height<=640px){.chart-stage[data-v-59c0bc54]{gap:6px}}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;left:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}.right-axis{z-index:15}
1
+ .kline-tooltip[data-v-d0fe85e6]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:200px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.kline-tooltip__title[data-v-d0fe85e6]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.kline-tooltip__grid[data-v-d0fe85e6]{grid-template-columns:1fr;gap:2px;display:grid}.kline-tooltip__grid .row[data-v-d0fe85e6]{justify-content:space-between;gap:10px;display:flex}.kline-tooltip__grid .row span[data-v-d0fe85e6]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.kline-tooltip.use-anchor[data-v-d0fe85e6]{position-anchor:--kline-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.kline-tooltip.use-anchor.anchor-right-bottom[data-v-d0fe85e6]{transform:translate(14px,14px)}.kline-tooltip.use-anchor.anchor-left-bottom[data-v-d0fe85e6]{transform:translate(calc(-100% - 14px),14px)}}.marker-tooltip[data-v-5574cc25]{z-index:10;color:#000000c7;pointer-events:none;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);background:#ffffffeb;border:1px solid #0000001f;border-radius:8px;min-width:180px;max-width:260px;padding:10px 12px;font-size:12px;line-height:1.4;position:absolute;box-shadow:0 6px 18px #0000001f}.marker-tooltip__title[data-v-5574cc25]{justify-content:space-between;gap:10px;margin-bottom:6px;font-weight:600;display:flex}.marker-tooltip__content[data-v-5574cc25]{grid-template-columns:1fr;gap:2px;display:grid}.marker-tooltip__content .row[data-v-5574cc25]{justify-content:space-between;gap:10px;display:flex}.marker-tooltip__content .row span[data-v-5574cc25]:first-child{color:#0000008f}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.marker-tooltip.use-anchor[data-v-5574cc25]{position-anchor:--marker-tooltip-anchor;left:anchor(left);top:anchor(top);position:absolute}.marker-tooltip.use-anchor.anchor-right-bottom[data-v-5574cc25]{transform:translate(12px,12px)}.marker-tooltip.use-anchor.anchor-left-bottom[data-v-5574cc25]{transform:translate(calc(-100% - 12px),12px)}}.params-overlay[data-v-bb1d1eb3]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.indicator-params[data-v-bb1d1eb3]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.params-header[data-v-bb1d1eb3]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-bb1d1eb3]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-bb1d1eb3]{align-items:center;gap:8px;display:flex}.params-title[data-v-bb1d1eb3]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.params-subtitle[data-v-bb1d1eb3]{color:#999;font-size:11px}.toggle-desc-btn[data-v-bb1d1eb3]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:all .2s;display:flex}.toggle-desc-btn[data-v-bb1d1eb3]:hover{color:#555;background:#f0f0f0;border-color:#ccc}.toggle-desc-btn.active[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.toggle-desc-btn svg[data-v-bb1d1eb3]{width:14px;height:14px}.params-close[data-v-bb1d1eb3]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.params-close[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.params-close svg[data-v-bb1d1eb3]{width:14px;height:14px}.indicator-description[data-v-bb1d1eb3]{background:#f0f7ff;border-bottom:1px solid #d6e8f5;padding:12px 20px}.indicator-description p[data-v-bb1d1eb3]{color:#2c5282;margin:0;font-size:12px;line-height:1.6}.params-body[data-v-bb1d1eb3]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.param-item[data-v-bb1d1eb3]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:10px 14px;transition:border-color .2s}.param-item[data-v-bb1d1eb3]:has(.param-input:focus){border-color:#bbb}.param-item.has-desc[data-v-bb1d1eb3]{padding:10px 14px 8px}.param-header[data-v-bb1d1eb3]{justify-content:space-between;align-items:center;gap:16px;display:flex}.param-label[data-v-bb1d1eb3]{flex-direction:column;gap:3px;display:flex}.param-label-text[data-v-bb1d1eb3]{color:#333;font-size:13px;font-weight:500}.param-range[data-v-bb1d1eb3]{color:#999;font-size:11px}.param-description[data-v-bb1d1eb3]{color:#666;border-top:1px dashed #e0e0e0;margin-top:8px;padding-top:8px;font-size:11px;line-height:1.5}.input-wrapper[data-v-bb1d1eb3]{background:#fff;border:1px solid #d0d0d0;border-radius:7px;align-items:stretch;height:32px;transition:border-color .2s;display:flex;overflow:hidden}.input-wrapper[data-v-bb1d1eb3]:focus-within{border-color:#999}.stepper-btn[data-v-bb1d1eb3]{cursor:pointer;color:#666;background:#f0f0f0;border:none;flex-shrink:0;justify-content:center;align-items:center;width:28px;font-size:15px;font-weight:400;line-height:1;transition:background .15s,color .15s;display:flex}.stepper-btn[data-v-bb1d1eb3]:hover:not(:disabled){color:#333;background:#e0e0e0}.stepper-btn[data-v-bb1d1eb3]:disabled{color:#ccc;cursor:not-allowed}.param-input[data-v-bb1d1eb3]{text-align:center;color:#1a1a1a;appearance:textfield;background:0 0;border:none;border-left:1px solid #e8e8e8;border-right:1px solid #e8e8e8;width:60px;font-size:13px;font-weight:600}.param-input[data-v-bb1d1eb3]::-webkit-inner-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]::-webkit-outer-spin-button{-webkit-appearance:none}.param-input[data-v-bb1d1eb3]:focus{outline:none}.params-footer[data-v-bb1d1eb3]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-bb1d1eb3]{gap:8px;display:flex}.params-btn[data-v-bb1d1eb3]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.params-btn svg[data-v-bb1d1eb3]{flex-shrink:0;width:12px;height:12px}.params-btn.reset[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.reset[data-v-bb1d1eb3]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.params-btn.cancel[data-v-bb1d1eb3]{color:#666;background:0 0;border-color:#d0d0d0}.params-btn.cancel[data-v-bb1d1eb3]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.params-btn.confirm[data-v-bb1d1eb3]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.params-btn.confirm[data-v-bb1d1eb3]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.params-btn.confirm[data-v-bb1d1eb3]:active{box-shadow:none;transform:translateY(0)}.overlay-enter-active[data-v-bb1d1eb3],.overlay-leave-active[data-v-bb1d1eb3]{transition:opacity .2s}.overlay-enter-from[data-v-bb1d1eb3],.overlay-leave-to[data-v-bb1d1eb3]{opacity:0}.modal-enter-active[data-v-bb1d1eb3]{transition:all .22s cubic-bezier(.34,1.56,.64,1)}.modal-leave-active[data-v-bb1d1eb3]{transition:all .16s ease-in}.modal-enter-from[data-v-bb1d1eb3]{opacity:0;transform:scale(.88)translateY(-16px)}.modal-leave-to[data-v-bb1d1eb3]{opacity:0;transform:scale(.94)translateY(8px)}.slide-enter-active[data-v-bb1d1eb3],.slide-leave-active[data-v-bb1d1eb3]{transition:all .2s;overflow:hidden}.slide-enter-from[data-v-bb1d1eb3],.slide-leave-to[data-v-bb1d1eb3]{opacity:0;max-height:0;margin-top:0;padding-top:0;padding-bottom:0}.indicator-selector[data-v-f3fbebbd]{width:80%;margin:20px;position:relative}.indicator-scroll-container[data-v-f3fbebbd]{scrollbar-width:none;-webkit-overflow-scrolling:touch;text-align:center;width:100%;overflow:auto hidden}.indicator-scroll-container[data-v-f3fbebbd]::-webkit-scrollbar{display:none}.indicator-list[data-v-f3fbebbd]{gap:8px;margin:0 auto;padding:2px;display:inline-flex}.indicator-divider[data-v-f3fbebbd]{background:#d9d9d9;align-self:center;width:1px;height:20px}.indicator-item[data-v-f3fbebbd]{align-items:center;gap:4px;display:flex}.indicator-item.draggable[data-v-f3fbebbd],.indicator-item.draggable .indicator-btn[data-v-f3fbebbd],.indicator-item.draggable[data-v-f3fbebbd]:hover,.indicator-item.draggable:hover .indicator-btn[data-v-f3fbebbd]{cursor:move}.indicator-item.is-dragging[data-v-f3fbebbd]{opacity:.6}.indicator-item.drag-over .indicator-btn[data-v-f3fbebbd]{border-color:#1a1a1a;box-shadow:0 0 0 2px #1a1a1a1f}.indicator-btn-wrapper[data-v-f3fbebbd]{position:relative}.indicator-btn[data-v-f3fbebbd]{color:#666;cursor:pointer;white-space:nowrap;background:#fff;border:1px solid #e0e0e0;border-radius:16px;flex-shrink:0;justify-content:center;align-items:center;gap:4px;padding:6px 16px;font-size:13px;font-weight:500;transition:all .3s;display:flex;position:relative;overflow:hidden}.indicator-btn[data-v-f3fbebbd]:hover:not(.hovering){color:#333;background:#f8f8f8;border-color:#ccc}.indicator-btn.active[data-v-f3fbebbd]{color:#1a1a1a;background:#f8f8f8;border-color:#1a1a1a}.indicator-btn.active[data-v-f3fbebbd]:hover:not(.hovering){background:#f0f0f0;border-color:#333}.btn-content[data-v-f3fbebbd]{z-index:1;position:relative}.param-hint[data-v-f3fbebbd]{opacity:.85;font-size:11px}.hover-overlay[data-v-f3fbebbd]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:2;background:#ffffffd9;border-radius:16px;justify-content:center;align-items:center;gap:4px;display:flex;position:absolute;inset:0}.action-btn[data-v-f3fbebbd]{color:#666;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:all .2s;display:flex}.action-btn[data-v-f3fbebbd]:hover{color:#333;background:#0000000f}.settings-btn[data-v-f3fbebbd]:hover{color:#1a1a1a}.remove-btn[data-v-f3fbebbd]:hover{color:#ff4d4f}.divider[data-v-f3fbebbd]{background:#e0e0e0;width:1px;height:14px}.add-btn[data-v-f3fbebbd]{anchor-name:--indicator-add-btn;color:#999;cursor:pointer;background:0 0;border:1px dashed #d9d9d9;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;padding:0;transition:all .3s;display:flex}.add-btn[data-v-f3fbebbd]:hover{color:#1a1a1a;background:#1a1a1a0a;border-color:#1a1a1a}.add-menu[data-v-f3fbebbd]{white-space:nowrap;z-index:9999;background:#fff;border-radius:8px;padding:8px 0;position:fixed;transform:translate(-50%);box-shadow:0 6px 16px #00000014,0 3px 6px -4px #0000001f,0 9px 28px 8px #0000000d}@supports (anchor-name:--kmap-anchor) and (position-anchor:--kmap-anchor){.add-menu.use-anchor[data-v-f3fbebbd]{position-anchor:--indicator-add-btn;left:anchor(center);top:anchor(top);max-width:calc(100vw - 16px);position:fixed;transform:translate(-50%,calc(-100% - 8px))}}.menu-section[data-v-f3fbebbd]{padding:4px 0}.menu-section[data-v-f3fbebbd]:not(:last-child){border-bottom:1px solid #f0f0f0}.menu-title[data-v-f3fbebbd]{color:#999;padding:4px 16px;font-size:12px;font-weight:500}.menu-items[data-v-f3fbebbd]{flex-direction:column;gap:2px;display:flex}.menu-item[data-v-f3fbebbd]{text-align:left;color:#333;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;width:100%;padding:8px 16px;font-size:13px;transition:background .2s;display:flex}.menu-item[data-v-f3fbebbd]:hover:not(.disabled){background:#f5f5f5}.menu-item.disabled[data-v-f3fbebbd]{color:#999;cursor:not-allowed}.menu-item .param-hint[data-v-f3fbebbd]{color:#999;font-size:11px}.active-tag[data-v-f3fbebbd]{color:#1a1a1a;align-items:center;margin-left:auto;display:flex}.fade-enter-active[data-v-f3fbebbd],.fade-leave-active[data-v-f3fbebbd]{transition:opacity .2s}.fade-enter-from[data-v-f3fbebbd],.fade-leave-to[data-v-f3fbebbd]{opacity:0}.slide-enter-active[data-v-f3fbebbd],.slide-leave-active[data-v-f3fbebbd]{transition:all .2s}.slide-enter-from[data-v-f3fbebbd],.slide-leave-to[data-v-f3fbebbd]{opacity:0;transform:translate(-50%)translateY(8px)}.drawing-style-toolbar[data-v-92699cb2]{-webkit-backdrop-filter:blur(8px);z-index:100;-webkit-user-select:none;user-select:none;pointer-events:auto;background:#fafbfce0;border:1px solid #e5e7eb;border-radius:6px;align-items:center;gap:6px;height:32px;padding:4px 8px;display:flex;position:absolute;top:8px;left:50%;transform:translate(-50%);box-shadow:0 1px 3px #0000000f}.toolbar-item[data-v-92699cb2]{justify-content:center;align-items:center;display:inline-flex}.color-item[data-v-92699cb2]{width:24px;height:24px;position:relative}.color-swatch[data-v-92699cb2]{cursor:pointer;border:1px solid #d1d5db;border-radius:4px;width:100%;height:100%;display:block}.color-input[data-v-92699cb2]{opacity:0;cursor:pointer;width:100%;height:100%;position:absolute;inset:0}.toolbar-select[data-v-92699cb2]{color:#374151;cursor:pointer;background:#fff;border:1px solid #d1d5db;border-radius:4px;outline:none;height:24px;padding:0 4px;font-size:12px}.toolbar-select[data-v-92699cb2]:hover{border-color:#9ca3af}.toolbar-btn[data-v-92699cb2]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:24px;height:24px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex}.toolbar-btn[data-v-92699cb2]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.delete-btn[data-v-92699cb2]:hover{color:#dc2626;background:#fef2f2;border-color:#fca5a5}.delete-icon[data-v-92699cb2]{width:14px;height:14px}.left-toolbar[data-v-f47a57b0]{box-sizing:border-box;-webkit-user-select:none;user-select:none;background:#fafbfc;border:1px solid #e5e7eb;border-radius:6px;flex-direction:column;flex:0 0 40px;align-items:center;gap:6px;padding:8px 5px;display:flex;box-shadow:0 1px 3px #0000000f}.left-toolbar__group[data-v-f47a57b0]{flex-direction:column;gap:4px;display:flex}.left-toolbar__divider[data-v-f47a57b0]{background:#e5e7eb;width:18px;height:1px}.left-toolbar__button[data-v-f47a57b0]{color:#6b7280;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:4px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:border-color .15s,background .15s,color .15s;display:inline-flex;position:relative}.left-toolbar__button[data-v-f47a57b0]:hover{color:#374151;background:#f3f4f6;border-color:#d1d5db}.left-toolbar__button.active[data-v-f47a57b0]{color:#1f2937;background:#e5e7eb;border-color:#9ca3af}.left-toolbar__button[data-v-f47a57b0]:focus-visible{border-color:#6b7280;outline:none}.tool-icon[data-v-f47a57b0]{width:16px;height:16px}.corner-indicator[data-v-f47a57b0]{cursor:pointer;width:8px;height:8px;position:absolute;bottom:0;right:0;overflow:hidden}.corner-indicator[data-v-f47a57b0]:after{content:"";opacity:.45;border-bottom:5px solid;border-left:5px solid #0000;width:0;height:0;transition:opacity .15s;position:absolute;bottom:0;right:0}.left-toolbar__button:hover .corner-indicator[data-v-f47a57b0]:after,.left-toolbar__button.active .corner-indicator[data-v-f47a57b0]:after{opacity:.7}.corner-indicator.open[data-v-f47a57b0]:after{opacity:.8}.tool-dropdown[data-v-f47a57b0]{-webkit-backdrop-filter:blur(8px);box-sizing:border-box;z-index:100;background:#fafbfcd1;border:1px solid #e5e7eb;border-radius:6px;flex-direction:row;align-items:center;gap:4px;height:40px;padding:0 5px;display:flex;position:absolute;top:50%;left:calc(100% + 13px);transform:translateY(-50%);box-shadow:0 1px 3px #0000000f}.tool-item[data-v-f47a57b0]{position:relative}.dropdown-enter-active[data-v-f47a57b0],.dropdown-leave-active[data-v-f47a57b0]{transition:opacity .15s,transform .15s}.dropdown-enter-from[data-v-f47a57b0],.dropdown-leave-to[data-v-f47a57b0]{opacity:0;transform:translateY(-50%)translate(-6px)}@media (width<=768px),(height<=640px){.left-toolbar[data-v-f47a57b0]{border-radius:5px;flex-basis:36px;gap:5px;padding:6px 4px}.left-toolbar__group[data-v-f47a57b0]{gap:3px}.left-toolbar__button[data-v-f47a57b0]{border-radius:3px;width:26px;height:26px}.left-toolbar__divider[data-v-f47a57b0]{width:16px}.corner-indicator[data-v-f47a57b0]{width:7px;height:7px}.corner-indicator[data-v-f47a57b0]:after{border-bottom-width:4px;border-left-width:4px}.tool-dropdown[data-v-f47a57b0]{height:36px}}.settings-overlay[data-v-f47a57b0]{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;background:#0000004d;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.settings-modal[data-v-f47a57b0]{background:#fff;border:1px solid #e0e0e0;border-radius:12px;width:90vw;min-width:340px;max-width:420px;overflow:hidden;box-shadow:0 8px 40px #00000026}.settings-header[data-v-f47a57b0]{background:#f8f8f8;border-bottom:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:16px 20px;display:flex}.header-left[data-v-f47a57b0]{align-items:baseline;gap:8px;display:flex}.header-right[data-v-f47a57b0]{align-items:center;gap:8px;display:flex}.settings-title[data-v-f47a57b0]{color:#1a1a1a;letter-spacing:.2px;font-size:14px;font-weight:600}.settings-subtitle[data-v-f47a57b0]{color:#999;font-size:11px}.settings-close[data-v-f47a57b0]{cursor:pointer;color:#888;background:#fff;border:1px solid #e0e0e0;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;transition:background .15s,color .15s,border-color .15s;display:flex}.settings-close[data-v-f47a57b0]:hover{color:#333;background:#f0f0f0;border-color:#ccc}.settings-close svg[data-v-f47a57b0]{width:14px;height:14px}.settings-body[data-v-f47a57b0]{flex-direction:column;gap:10px;padding:16px 20px;display:flex}.settings-item[data-v-f47a57b0]{background:#f8f8f8;border:1px solid #e8e8e8;border-radius:8px;padding:8px 12px}.settings-label[data-v-f47a57b0]{color:#333;cursor:pointer;justify-content:space-between;align-items:center;font-size:13px;display:flex}.settings-checkbox[data-v-f47a57b0]{cursor:pointer;accent-color:#1a1a1a;width:16px;height:16px}.settings-section-divider[data-v-f47a57b0]{align-items:center;gap:8px;margin-top:4px;display:flex}.settings-section-divider[data-v-f47a57b0]:before,.settings-section-divider[data-v-f47a57b0]:after{content:"";border-top:1px solid #e0e0e0;flex:1}.settings-section-label[data-v-f47a57b0]{color:#999;white-space:nowrap;font-size:11px}.settings-item.experimental[data-v-f47a57b0]{background:#fdf8f3;border-color:#f0e0d0}.settings-footer[data-v-f47a57b0]{background:#f8f8f8;border-top:1px solid #e8e8e8;justify-content:space-between;align-items:center;padding:12px 20px;display:flex}.footer-right[data-v-f47a57b0]{gap:8px;display:flex}.settings-btn[data-v-f47a57b0]{cursor:pointer;border:1px solid #0000;border-radius:7px;align-items:center;gap:5px;padding:6px 14px;font-size:13px;font-weight:500;line-height:1.4;transition:all .15s;display:flex}.settings-btn svg[data-v-f47a57b0]{flex-shrink:0;width:12px;height:12px}.settings-btn.reset[data-v-f47a57b0]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.reset[data-v-f47a57b0]:hover{color:#e74c3c;background:#e74c3c14;border-color:#c0392b}.settings-btn.cancel[data-v-f47a57b0]{color:#666;background:0 0;border-color:#d0d0d0}.settings-btn.cancel[data-v-f47a57b0]:hover{color:#333;background:#f0f0f0;border-color:#bbb}.settings-btn.confirm[data-v-f47a57b0]{color:#fff;background:#1a1a1a;border-color:#1a1a1a}.settings-btn.confirm[data-v-f47a57b0]:hover{background:#333;border-color:#333;transform:translateY(-1px);box-shadow:0 2px 10px #00000026}.settings-btn.confirm[data-v-f47a57b0]:active{box-shadow:none;transform:translateY(0)}.chart-wrapper[data-v-b9893341]{--kmap-height:var(--kmap-chart-height,100%);--kmap-width:var(--kmap-chart-width,100%);width:var(--kmap-width);height:var(--kmap-height);flex-direction:column;justify-content:center;align-items:center;min-height:300px;display:flex}.chart-stage[data-v-b9893341]{align-items:stretch;gap:8px;width:95%;height:85%;min-height:255px;display:flex}.chart-main[data-v-b9893341]{flex:auto;align-items:stretch;gap:0;min-width:0;height:100%;display:flex;position:relative}.pane-separator-layer[data-v-b9893341]{pointer-events:none;z-index:20;position:absolute;inset:0}.pane-separator-line[data-v-b9893341]{opacity:1;box-sizing:border-box;border-top:1px solid #e5e7eb;height:0;transition:border-top-color .12s,border-top-width .12s,margin-top .12s,opacity .12s;position:absolute;left:0;right:0}.pane-separator-line.is-active[data-v-b9893341]{border-top-width:2px;border-top-color:#3b82f6;margin-top:-1px}.chart-stage.is-resizing-pane[data-v-b9893341],.chart-stage.is-hovering-pane-separator[data-v-b9893341]{cursor:ns-resize}.chart-stage.is-hovering-kline[data-v-b9893341]{cursor:pointer}.chart-stage.is-hovering-right-axis[data-v-b9893341]{cursor:ns-resize}.chart-stage.is-dragging[data-v-b9893341]{cursor:grabbing}.chart-container[data-v-b9893341]{height:100%;min-height:inherit;scrollbar-width:none;-ms-overflow-style:none;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;background:#fff;border:1px solid #e5e7eb;border-right:0;border-radius:6px 0 0 6px;flex:auto;position:relative;overflow:auto hidden}.chart-container[data-v-b9893341]::-webkit-scrollbar{display:none}.chart-container[data-v-b9893341]:hover{cursor:crosshair}.chart-stage.is-resizing-pane .chart-container[data-v-b9893341],.chart-stage.is-hovering-pane-separator .chart-container[data-v-b9893341]{cursor:ns-resize}.chart-stage.is-hovering-kline .chart-container[data-v-b9893341]{cursor:pointer}.chart-stage.is-dragging .chart-container[data-v-b9893341]{cursor:grabbing}.right-axis-host[data-v-b9893341]{height:100%;min-height:inherit;box-sizing:border-box;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none;background:#fff;border:1px solid #e5e7eb;border-top-right-radius:6px;border-bottom-right-radius:6px;flex:none;position:relative;overflow:visible}.scroll-content[data-v-b9893341]{height:100%;min-height:inherit;position:relative}.canvas-layer[data-v-b9893341]{pointer-events:none;position:sticky;top:0;left:0}.tooltip-layer[data-v-b9893341]{pointer-events:none;z-index:30;position:absolute;inset:0}.tooltip-anchor[data-v-b9893341]{pointer-events:none;width:1px;height:1px;position:absolute}.tooltip-anchor.kline-tooltip-anchor.use-anchor[data-v-b9893341]{anchor-name:--kline-tooltip-anchor}.tooltip-anchor.marker-tooltip-anchor.use-anchor[data-v-b9893341]{anchor-name:--marker-tooltip-anchor}@media (width<=768px),(height<=640px){.chart-stage[data-v-b9893341]{gap:6px}}.plot-canvas{display:block;position:absolute;top:0;left:0}.right-axis{display:block;position:absolute;left:0}.x-axis-canvas{z-index:10;display:block;position:absolute;bottom:0;left:0}.right-axis{z-index:15}
2
2
  /*$vite$:1*/
@@ -1,5 +1,5 @@
1
1
  import { KLineData } from '../types/price';
2
- import { VisibleRange } from './layout/pane';
2
+ import { VisibleRange, UpdateLevel } from './layout/pane';
3
3
  import { InteractionController } from './controller/interaction';
4
4
  import { PaneRenderer } from './paneRenderer';
5
5
  import { MarkerManager, CustomMarkerEntity } from './marker/registry';
@@ -40,7 +40,8 @@ export type PaneSpec = {
40
40
  capabilities?: Partial<PaneCapabilities>;
41
41
  };
42
42
  export type PaneRendererDom = {
43
- plotCanvas: HTMLCanvasElement;
43
+ mainCanvas: HTMLCanvasElement;
44
+ overlayCanvas: HTMLCanvasElement;
44
45
  yAxisCanvas: HTMLCanvasElement;
45
46
  };
46
47
  export type ChartOptions = {
@@ -91,6 +92,7 @@ export declare class Chart {
91
92
  private opt;
92
93
  private data;
93
94
  private raf;
95
+ private pendingUpdateLevel;
94
96
  private viewport;
95
97
  private paneRenderers;
96
98
  private markerManager;
@@ -126,6 +128,70 @@ export declare class Chart {
126
128
  private indicatorScheduler;
127
129
  /** 上次可见范围(用于检测视口变化) */
128
130
  private lastVisibleRange;
131
+ /** 当前激活的主图指标列表(如 ['boll', 'ma']) */
132
+ private activeMainIndicators;
133
+ /** 主图指标参数配置 */
134
+ private mainIndicatorParams;
135
+ /**
136
+ * 启用主图指标
137
+ * @param indicatorId 指标ID: 'MA' | 'BOLL' | 'EXPMA' | 'ENE'
138
+ * @param params 可选的指标参数
139
+ * @returns 是否成功启用
140
+ */
141
+ enableMainIndicator(indicatorId: string, params?: Record<string, number | boolean>): boolean;
142
+ /**
143
+ * 禁用主图指标
144
+ * @param indicatorId 指标ID
145
+ * @returns 是否成功禁用
146
+ */
147
+ disableMainIndicator(indicatorId: string): boolean;
148
+ /**
149
+ * 切换主图指标启用状态
150
+ * @param indicatorId 指标ID
151
+ * @param enabled 是否启用
152
+ */
153
+ toggleMainIndicator(indicatorId: string, enabled: boolean): void;
154
+ /**
155
+ * 获取当前激活的主图指标列表
156
+ * @returns 激活的指标ID数组
157
+ */
158
+ getActiveMainIndicators(): string[];
159
+ /**
160
+ * 检查主图指标是否激活
161
+ * @param indicatorId 指标ID
162
+ */
163
+ isMainIndicatorActive(indicatorId: string): boolean;
164
+ /**
165
+ * 更新主图指标参数
166
+ * @param indicatorId 指标ID
167
+ * @param params 参数对象
168
+ */
169
+ updateMainIndicatorParams(indicatorId: string, params: Record<string, number | boolean>): void;
170
+ /**
171
+ * 获取主图指标参数
172
+ * @param indicatorId 指标ID
173
+ */
174
+ getMainIndicatorParams(indicatorId: string): Record<string, number | boolean> | null;
175
+ /**
176
+ * 清除所有主图指标
177
+ */
178
+ clearMainIndicators(): void;
179
+ /**
180
+ * 启用主图指标渲染器(内部方法)
181
+ */
182
+ private enableMainIndicatorRenderer;
183
+ /**
184
+ * 禁用主图指标渲染器(内部方法)
185
+ */
186
+ private disableMainIndicatorRenderer;
187
+ /**
188
+ * 更新调度器配置(内部方法)
189
+ */
190
+ private updateIndicatorSchedulerConfig;
191
+ /**
192
+ * @deprecated 使用 enableMainIndicator/disableMainIndicator 替代
193
+ */
194
+ setActiveMainIndicators(indicators: string[]): void;
129
195
  /**
130
196
  * 创建图表实例
131
197
  * @param dom 由 Vue 组件传入的 DOM 句柄
@@ -153,8 +219,11 @@ export declare class Chart {
153
219
  getAllRenderers(): RendererPlugin[];
154
220
  /** 更新用户设置(触发重绘) */
155
221
  updateSettings(settings: Record<string, boolean>): void;
156
- /** 绘制一帧 */
157
- draw(): void;
222
+ /**
223
+ * 绘制一帧
224
+ * @param level 更新级别,决定渲染哪些层
225
+ */
226
+ draw(level?: UpdateLevel): void;
158
227
  /**
159
228
  * 应用渲染状态(由 Vue/Store 层在状态更新后调用)
160
229
  * Chart 不拥有业务 SSOT,只负责接收参数并渲染
@@ -254,6 +323,11 @@ export declare class Chart {
254
323
  * @param deltaY Y轴像素偏移(正数向下拖动)
255
324
  */
256
325
  translatePrice(paneId: string, deltaY: number): void;
326
+ /**
327
+ * 重置价格轴垂直偏移
328
+ * @param paneId 目标 pane ID
329
+ */
330
+ resetPriceOffset(paneId: string): void;
257
331
  /**
258
332
  * 缩放价格轴(用于右侧刻度栏上下拖动)
259
333
  * @param paneId 目标 pane ID
@@ -280,8 +354,11 @@ export declare class Chart {
280
354
  getContentWidth(): number;
281
355
  /** 容器尺寸变化时调用 */
282
356
  resize(): void;
283
- /** 请求下一帧重绘(RAF 合并) */
284
- scheduleDraw(): void;
357
+ /**
358
+ * 请求下一帧重绘(RAF 合并,支持分层更新)
359
+ * @param level 更新级别,默认为 All
360
+ */
361
+ scheduleDraw(level?: UpdateLevel): void;
285
362
  /** 销毁图表实例 */
286
363
  destroy(): Promise<void>;
287
364
  /** 初始化所有 pane */
@@ -150,10 +150,24 @@ export declare class IndicatorScheduler {
150
150
  private dirtyWmsrConfig;
151
151
  private dirtyKstConfig;
152
152
  private dirtyFastkConfig;
153
+ private dirtyRsiState;
154
+ private dirtyCciState;
155
+ private dirtyStochState;
156
+ private dirtyMomState;
157
+ private dirtyWmsrState;
158
+ private dirtyKstState;
159
+ private dirtyFastkState;
160
+ /** 当前激活的主图指标列表 */
161
+ private activeMainIndicators;
153
162
  /**
154
163
  * 设置 PluginHost,用于读写 StateStore
155
164
  */
156
165
  setPluginHost(host: PluginHost): void;
166
+ /**
167
+ * 设置当前激活的主图指标(用于极值计算过滤)
168
+ * @param indicators 激活的指标ID列表,如 ['ma', 'boll', 'expma', 'ene']
169
+ */
170
+ setActiveMainIndicators(indicators: string[]): void;
157
171
  /**
158
172
  * 数据变更时调用
159
173
  * @param data 新的 K 线数据
@@ -240,5 +254,13 @@ export declare class IndicatorScheduler {
240
254
  * 3. 写入所有指标的 StateStore
241
255
  */
242
256
  private computeIfDirty;
257
+ /**
258
+ * 获取主图指标极值(用于与K线极值合并计算价格轴范围)
259
+ * @returns 主图指标的价格范围,无指标时返回 null
260
+ */
261
+ getMainIndicatorPriceRange(): {
262
+ min: number;
263
+ max: number;
264
+ } | null;
243
265
  }
244
266
  export {};
@@ -3,6 +3,17 @@ import { PriceRange } from '../scale/price';
3
3
  import { PriceScale } from '../scale/priceScale';
4
4
  import { MarkerManager } from '../marker/registry';
5
5
  import { PaneCapabilities, PaneRole } from '../../plugin';
6
+ /**
7
+ * 更新级别枚举 - 用于双层 Canvas 架构
8
+ * Main: 只更新主画布(K线、指标等静态内容)
9
+ * Overlay: 只更新覆盖层(十字线、Tooltip等动态内容)
10
+ * All: 更新所有层
11
+ */
12
+ export declare enum UpdateLevel {
13
+ Main = "main",
14
+ Overlay = "overlay",
15
+ All = "all"
16
+ }
6
17
  export type VisibleRange = {
7
18
  start: number;
8
19
  end: number;
@@ -83,6 +94,10 @@ export declare class Pane {
83
94
  * 根据当前可见索引区间更新 priceRange 并同步到 yAxis
84
95
  * @param data 全量 K 线数据
85
96
  * @param range 当前视口可见的索引范围(由 getVisibleRange 计算)
97
+ * @param indicatorRange 可选的指标极值范围,与K线极值合并
86
98
  */
87
- updateRange(data: KLineData[], range: VisibleRange): void;
99
+ updateRange(data: KLineData[], range: VisibleRange, indicatorRange?: {
100
+ min: number;
101
+ max: number;
102
+ } | null): void;
88
103
  }
@@ -1,5 +1,6 @@
1
1
  export type PaneRendererDom = {
2
- plotCanvas: HTMLCanvasElement;
2
+ mainCanvas: HTMLCanvasElement;
3
+ overlayCanvas: HTMLCanvasElement;
3
4
  yAxisCanvas: HTMLCanvasElement;
4
5
  };
5
6
  export type PaneRendererOptions = {
@@ -9,3 +9,4 @@ export declare const FONT_FAMILY = "\"Trebuchet MS\", Roboto, Ubuntu, sans-serif
9
9
  export declare function getFont(size: number, options?: {
10
10
  bold?: boolean;
11
11
  }): string;
12
+ export declare function setCanvasFont(ctx: CanvasRenderingContext2D, font: string): void;
@@ -0,0 +1,21 @@
1
+ type MetricEntry = {
2
+ count: number;
3
+ totalTime: number;
4
+ };
5
+ type MetricBucket = Record<string, MetricEntry>;
6
+ type CanvasProfilerMetrics = {
7
+ ctxMethods: MetricBucket;
8
+ ctxProps: MetricBucket;
9
+ canvasProps: MetricBucket;
10
+ ctxMethodSources: Record<string, MetricBucket>;
11
+ };
12
+ declare global {
13
+ interface Window {
14
+ __KMAP_CANVAS_PROFILER_INSTALLED__?: boolean;
15
+ __KMAP_CANVAS_PROFILER_METRICS__?: CanvasProfilerMetrics;
16
+ showCanvasReport?: () => void;
17
+ resetCanvasReport?: () => void;
18
+ }
19
+ }
20
+ export declare function installCanvasProfiler(): void;
21
+ export {};
@@ -1,4 +1,5 @@
1
1
  import { RendererPlugin, RenderContext, PaneInfo, RendererPluginWithHost, PluginHost } from './types';
2
+ import { UpdateLevel } from '../core/layout/pane';
2
3
  /** 渲染器错误事件(裁剪后,不含大数据) */
3
4
  export interface RendererErrorEvent {
4
5
  name: string;
@@ -55,8 +56,8 @@ export declare class RendererPluginManager {
55
56
  private getMergedRenderers;
56
57
  /** 获取指定 pane 的渲染器(已缓存,无穿透) */
57
58
  getRenderers(paneId: string): RendererPlugin[];
58
- /** 渲染指定 pane(带错误隔离) */
59
- render(paneId: string, context: RenderContext): RendererErrorEvent[];
59
+ /** 渲染指定 pane(带错误隔离,支持按 UpdateLevel 过滤) */
60
+ render(paneId: string, context: RenderContext, level?: UpdateLevel): RendererErrorEvent[];
60
61
  /** 渲染指定名称的插件(带错误隔离,用于系统渲染器) */
61
62
  renderPlugin(name: string, context: RenderContext): RendererErrorEvent[];
62
63
  /** 启用/禁用渲染器(修改独立状态,不影响原始插件对象) */
@@ -226,6 +226,8 @@ export interface RenderContext {
226
226
  yAxisCtx?: CanvasRenderingContext2D;
227
227
  xAxisCtx?: CanvasRenderingContext2D;
228
228
  borderCtx?: CanvasRenderingContext2D;
229
+ /** 覆盖层 Canvas 上下文(用于十字线、Tooltip 等动态内容) */
230
+ overlayCtx?: CanvasRenderingContext2D;
229
231
  /** 当前缩放级别(1 ~ zoomLevels) */
230
232
  zoomLevel?: number;
231
233
  /** 总缩放级别数 */
@@ -396,6 +398,13 @@ export interface RendererPlugin {
396
398
  * 用于时间轴、全局边框等需要单独控制渲染时机的场景
397
399
  */
398
400
  isSystem?: boolean;
401
+ /**
402
+ * 渲染器所属层,决定 UpdateLevel 过滤行为
403
+ * - 'main': 低频/静态内容,随主画布一起渲染
404
+ * - 'overlay': 高频/动态内容,可在 overlay-only 更新时独立重绘
405
+ * 未指定时默认为 'main'(向后兼容)
406
+ */
407
+ layer?: 'main' | 'overlay';
399
408
  /** 渲染方法 */
400
409
  draw(context: RenderContext): void;
401
410
  /** 数据更新时回调 */
@@ -113,15 +113,7 @@ export interface CrosshairTimeLabelOptions {
113
113
  paddingX?: number;
114
114
  paddingY?: number;
115
115
  }
116
- /**
117
- * 在底部时间轴上绘制"十字线日期标签"
118
- * 说明:该函数假设时间轴背景/刻度已绘制完(即 drawTimeAxis 之后调用)。
119
- */
120
116
  export declare function drawCrosshairTimeLabel(ctx: CanvasRenderingContext2D, opts: CrosshairTimeLabelOptions): void;
121
- /**
122
- * 在右侧价格轴上绘制"十字线价格标签"
123
- * 说明:该函数假设价格轴背景/刻度已绘制完(即 drawPriceAxis 之后调用)。
124
- */
125
117
  export declare function drawCrosshairPriceLabel(ctx: CanvasRenderingContext2D, opts: CrosshairPriceLabelOptions): void;
126
118
  /** 绘制"最新价水平虚线"(画在 plotCanvas 的 world 坐标系:需在 translate(-scrollLeft,0) 之后调用) */
127
119
  export declare function drawLastPriceDashedLine(ctx: CanvasRenderingContext2D, opts: LastPriceLineOptions): void;
@@ -141,10 +133,6 @@ export interface AxisPriceLabelOptions {
141
133
  textColor?: string;
142
134
  fontSize?: number;
143
135
  }
144
- /**
145
- * 在右侧价格轴上绘制价格标签
146
- * 与 drawCrosshairPriceLabel 类似,但简化了参数(价格直接传入,无需计算)
147
- */
148
136
  export declare function drawAxisPriceLabel(ctx: CanvasRenderingContext2D, opts: AxisPriceLabelOptions): void;
149
137
  export interface AxisTimeLabelOptions {
150
138
  x: number;
@@ -159,8 +147,4 @@ export interface AxisTimeLabelOptions {
159
147
  fontSize?: number;
160
148
  paddingX?: number;
161
149
  }
162
- /**
163
- * 在底部时间轴上绘制时间标签
164
- * 与 drawCrosshairTimeLabel 类似,但 labelX 是屏幕坐标(已处理 scrollLeft)
165
- */
166
150
  export declare function drawAxisTimeLabel(ctx: CanvasRenderingContext2D, opts: AxisTimeLabelOptions): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@363045841yyt/klinechart",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "A lightweight financial K-line charting library with first-class AI Agent support, crisp ResizeObserver-driven rendering, and plugin-based architecture. Focused on quantitative trading scenarios with TradingView-level interaction experience.",
5
5
  "author": "363045841 <slslswbsy@qq.com>",
6
6
  "license": "MIT",
@@ -51,6 +51,7 @@
51
51
  "build-only": "vite build",
52
52
  "build:demo": "vite build --config vite.demo.config.ts",
53
53
  "preview": "vite preview",
54
+ "preview:demo": "vite preview --config vite.demo.config.ts",
54
55
  "type-check": "vue-tsc --build",
55
56
  "test:unit": "vitest",
56
57
  "format": "prettier --write --experimental-cli src/",