diff --git a/packages/syft/src/syft/assets/css/tabulator_pysyft.min.css b/packages/syft/src/syft/assets/css/tabulator_pysyft.min.css index f474df40562..fde1ee7edc8 100644 --- a/packages/syft/src/syft/assets/css/tabulator_pysyft.min.css +++ b/packages/syft/src/syft/assets/css/tabulator_pysyft.min.css @@ -1,6 +1,1651 @@ -:root{--tabulator-background-color:#fff;--tabulator-border-color:rgba(0,0,0,.12);--tabulator-text-size:16px;--tabulator-header-background-color:#f5f5f5;--tabulator-header-text-color:#555;--tabulator-header-border-color:rgba(0,0,0,.12);--tabulator-header-separator-color:rgba(0,0,0,.12);--tabulator-header-margin:4px;--tabulator-sort-arrow-hover:#555;--tabulator-sort-arrow-active:#666;--tabulator-sort-arrow-inactive:#bbb;--tabulator-column-resize-guide-color:#999;--tabulator-row-background-color:#fff;--tabulator-row-alt-background-color:#f8f8f8;--tabulator-row-border-color:rgba(0,0,0,.12);--tabulator-row-text-color:#333;--tabulator-row-hover-background:#e1f5fe;--tabulator-row-selected-background:#17161d;--tabulator-row-selected-background-hover:#17161d;--tabulator-edit-box-color:#17161d;--tabulator-error-color:#d00;--tabulator-footer-background-color:transparent;--tabulator-footer-text-color:#555;--tabulator-footer-border-color:rgba(0,0,0,.12);--tabulator-footer-separator-color:rgba(0,0,0,.12);--tabulator-footer-active-color:#17161d;--tabulator-spreadsheet-active-tab-color:#fff;--tabulator-range-border-color:#17161d;--tabulator-range-handle-color:#17161d;--tabulator-range-header-selected-background:var( - --tabulator-range-border-color - );--tabulator-range-header-selected-text-color:#fff;--tabulator-range-header-highlight-background:colors-gray-timberwolf;--tabulator-range-header-text-highlight-background:#fff;--tabulator-pagination-button-background:#fff;--tabulator-pagination-button-background-hover:#06c;--tabulator-pagination-button-color:#999;--tabulator-pagination-button-color-hover:#fff;--tabulator-pagination-button-color-active:#000;--tabulator-cell-padding:15px}body.vscode-dark,body[data-jp-theme-light=false]{--tabulator-background-color:#080808;--tabulator-border-color:#666;--tabulator-text-size:16px;--tabulator-header-background-color:#212121;--tabulator-header-text-color:#555;--tabulator-header-border-color:#666;--tabulator-header-separator-color:#666;--tabulator-header-margin:4px;--tabulator-sort-arrow-hover:#fff;--tabulator-sort-arrow-active:#e6e6e6;--tabulator-sort-arrow-inactive:#666;--tabulator-column-resize-guide-color:#999;--tabulator-row-background-color:#080808;--tabulator-row-alt-background-color:#212121;--tabulator-row-border-color:#666;--tabulator-row-text-color:#f8f8f8;--tabulator-row-hover-background:#333;--tabulator-row-selected-background:#241e1e;--tabulator-row-selected-background-hover:#333;--tabulator-edit-box-color:#333;--tabulator-error-color:#d00;--tabulator-footer-background-color:transparent;--tabulator-footer-text-color:#555;--tabulator-footer-border-color:rgba(0,0,0,.12);--tabulator-footer-separator-color:rgba(0,0,0,.12);--tabulator-footer-active-color:#17161d;--tabulator-spreadsheet-active-tab-color:#fff;--tabulator-range-border-color:#17161d;--tabulator-range-handle-color:var(--tabulator-range-border-color);--tabulator-range-header-selected-background:var( - --tabulator-range-border-color - );--tabulator-range-header-selected-text-color:#fff;--tabulator-range-header-highlight-background:#d6d6d6;--tabulator-range-header-text-highlight-background:#fff;--tabulator-pagination-button-background:#212121;--tabulator-pagination-button-background-hover:#555;--tabulator-pagination-button-color:#999;--tabulator-pagination-button-color-hover:#fff;--tabulator-pagination-button-color-active:#fff;--tabulator-cell-padding:15px}.tabulator{border:1px solid var(--tabulator-border-color);font-size:var(--tabulator-text-size);overflow:hidden;position:relative;text-align:left;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0)}.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table{min-width:100%}.tabulator[tabulator-layout=fitDataTable]{display:inline-block}.tabulator.tabulator-block-select,.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing){user-select:none}.tabulator .tabulator-header{background-color:var(--tabulator-header-background-color);border-bottom:1px solid var(--tabulator-header-separator-color);box-sizing:border-box;color:var(--tabulator-header-text-color);font-weight:700;outline:none;overflow:hidden;position:relative;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap;width:100%}.tabulator .tabulator-header.tabulator-header-hidden{display:none}.tabulator .tabulator-header .tabulator-header-contents{overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers{display:inline-block}.tabulator .tabulator-header .tabulator-col{background:var(--tabulator-header-background-color);border-right:1px solid var(--tabulator-header-border-color);box-sizing:border-box;display:inline-flex;flex-direction:column;justify-content:flex-start;overflow:hidden;position:relative;text-align:left;vertical-align:bottom}.tabulator .tabulator-header .tabulator-col.tabulator-moving{background:hsl(var(--tabulator-header-background-color),calc(var(--tabulator-header-background-color) - 5%))!important;border:1px solid var(--tabulator-header-separator-color);pointer-events:none;position:absolute}.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight{background-color:var(--tabulator-range-header-highlight-background);color:var(--tabulator-range-header-text-highlight-background)}.tabulator .tabulator-header .tabulator-col.tabulator-range-selected{background-color:var(--tabulator-range-header-selected-background);color:var(--tabulator-range-header-selected-text-color)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{box-sizing:border-box;padding:4px;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button{padding:0 8px}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover{cursor:pointer;opacity:.6}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder{position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title{box-sizing:border-box;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap{text-overflow:clip;white-space:normal}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor{background:#fff;border:1px solid #999;box-sizing:border-box;padding:1px;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor{width:calc(100% - 22px)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{align-items:center;bottom:0;display:flex;position:absolute;right:4px;top:0}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid var(--tabulator-sort-arrow-inactive);border-left:6px solid transparent;border-right:6px solid transparent;height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid var(--tabulator-header-border-color);display:flex;margin-right:-1px;overflow:hidden;position:relative}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter{box-sizing:border-box;margin-top:2px;position:relative;text-align:center;width:100%}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea{height:auto!important}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg{margin-top:3px}.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear{height:0;width:0}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:25px}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover{background-color:hsl(var(--tabulator-header-background-color),calc(var(--tabulator-header-background-color) - 10%))!important;cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter{color:var(--tabulator-sort-arrow-inactive)}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid var(--tabulator-sort-arrow-hover);cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid var(--tabulator-sort-arrow-inactive);border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter{color:var(--tabulator-sort-arrow-active)}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-bottom:6px solid var(--tabulator-sort-arrow-hover);cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:6px solid var(--tabulator-sort-arrow-active);border-top:none}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter{color:var(--tabulator-sort-arrow-active)}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover{border-top:6px solid var(--tabulator-sort-arrow-hover);cursor:pointer}}.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow{border-bottom:none;border-top:6px solid var(--tabulator-sort-arrow-active);color:var(--tabulator-sort-arrow-active)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title{align-items:center;display:flex;justify-content:center;text-orientation:mixed;writing-mode:vertical-rl}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title{transform:rotate(180deg)}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title{padding-right:0;padding-top:20px}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title{padding-bottom:20px;padding-right:0}.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter{bottom:auto;justify-content:center;left:0;right:0;top:4px}.tabulator .tabulator-header .tabulator-frozen{left:0;position:sticky;z-index:11}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left{border-right:2px solid var(--tabulator-row-border-color)}.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right{border-left:2px solid var(--tabulator-row-border-color)}.tabulator .tabulator-header .tabulator-calcs-holder{border-bottom:1px solid var(--tabulator-header-border-color);border-top:1px solid var(--tabulator-row-border-color);box-sizing:border-box;display:inline-block}.tabulator .tabulator-header .tabulator-calcs-holder,.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row{background:hsl(var(--tabulator-header-background-color),calc(var(--tabulator-header-background-color) + 5%))!important}.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-header .tabulator-frozen-rows-holder{display:inline-block}.tabulator .tabulator-tableholder{-webkit-overflow-scrolling:touch;overflow:auto;position:relative;white-space:nowrap;width:100%}.tabulator .tabulator-tableholder:focus{outline:none}.tabulator .tabulator-tableholder .tabulator-placeholder{align-items:center;box-sizing:border-box;display:flex;justify-content:center;min-width:100%;width:100%}.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual]{min-height:100%}.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents{color:#ccc;display:inline-block;font-size:20px;font-weight:700;padding:10px;text-align:center;white-space:normal}.tabulator .tabulator-tableholder .tabulator-table{background-color:var(--tabulator-row-background-color);color:var(--tabulator-row-text-color);display:inline-block;overflow:visible;position:relative;white-space:nowrap}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs{background:hsl(var(--tabulator-row-atl-background-color),calc(var(--tabulator-row-alt-background-color) - 5%))!important;font-weight:700}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top{border-bottom:2px solid var(--tabulator-row-border-color)}.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom{border-top:2px solid var(--tabulator-row-border-color)}.tabulator .tabulator-tableholder .tabulator-range-overlay{inset:0;pointer-events:none;position:absolute;z-index:10}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range{border:1px solid var(--tabulator-range-border-color);box-sizing:border-box;position:absolute}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:var(--tabulator-range-handle-color);border-radius:999px;bottom:-3px;content:"";height:6px;position:absolute;right:-3px;width:6px}.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active{border:2px solid var(--tabulator-range-border-color);box-sizing:border-box;position:absolute}.tabulator .tabulator-footer{border-top:1px solid var(--tabulator-footer-separator-color);color:var(--tabulator-footer-text-color);font-weight:700;user-select:none;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;white-space:nowrap}.tabulator .tabulator-footer .tabulator-footer-contents{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:5px 10px}.tabulator .tabulator-footer .tabulator-footer-contents:empty{display:none}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs{margin-top:-5px;overflow-x:auto}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{border:1px solid var(--tabulator-border-color);border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top:none;display:inline-block;font-size:.9em;padding:5px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover{cursor:pointer;opacity:.7}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{background:var(--tabulator-spreadsheet-active-tab-color)}.tabulator .tabulator-footer .tabulator-calcs-holder{border-bottom:1px solid var(--tabulator-row-border-color);border-top:1px solid var(--tabulator-row-border-color);box-sizing:border-box;overflow:hidden;text-align:left;width:100%}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row{display:inline-block}.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle{display:none}.tabulator .tabulator-footer .tabulator-calcs-holder:only-child{border-bottom:none;margin-bottom:-5px}.tabulator .tabulator-footer>*+.tabulator-page-counter{margin-left:10px}.tabulator .tabulator-footer .tabulator-page-counter{font-weight:400}.tabulator .tabulator-footer .tabulator-paginator{color:var(--tabulator-footer-text-color);flex:1;font-family:inherit;font-size:inherit;font-weight:inherit;text-align:right}.tabulator .tabulator-footer .tabulator-page-size{border:1px solid var(--tabulator-footer-border-color);border-radius:3px;display:inline-block;margin:0 5px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-pages{margin:0 7px}.tabulator .tabulator-footer .tabulator-page{background:hsla(0,0%,100%,.2);border:1px solid var(--tabulator-footer-border-color);border-radius:3px;display:inline-block;margin:0 2px;padding:2px 5px}.tabulator .tabulator-footer .tabulator-page.active{color:var(--tabulator-footer-active-color)}.tabulator .tabulator-footer .tabulator-page:disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:rgba(0,0,0,.2);color:#fff;cursor:pointer}}.tabulator .tabulator-col-resize-handle{display:inline-block;margin-left:-3px;margin-right:-3px;position:relative;vertical-align:middle;width:6px;z-index:11}@media (hover:hover) and (pointer:fine){.tabulator .tabulator-col-resize-handle:hover{cursor:ew-resize}}.tabulator .tabulator-col-resize-handle:last-of-type{margin-right:0;width:3px}.tabulator .tabulator-col-resize-guide{height:100%;margin-left:-.5px;top:0;width:4px}.tabulator .tabulator-col-resize-guide,.tabulator .tabulator-row-resize-guide{background-color:var(--tabulator-column-resize-guide-color);opacity:.5;position:absolute}.tabulator .tabulator-row-resize-guide{height:4px;left:0;margin-top:-.5px;width:100%}.tabulator .tabulator-alert{align-items:center;background:rgba(0,0,0,.4);display:flex;height:100%;left:0;position:absolute;text-align:center;top:0;width:100%;z-index:100}.tabulator .tabulator-alert .tabulator-alert-msg{background:#fff;border-radius:10px;display:inline-block;font-size:16px;font-weight:700;margin:0 auto;padding:10px 20px}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg{border:4px solid #333;color:#000}.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error{border:4px solid #d00;color:#590000}.tabulator-row{background-color:var(--tabulator-row-background-color);box-sizing:border-box;min-height:calc(var(--tabulator-text-size) + var(--tabulator-header-margin)*2);position:relative}.tabulator-row.tabulator-row-even{background-color:var(--tabulator-row-alt-background-color)}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selectable:hover{background-color:var(--tabulator-row-hover-background);cursor:pointer}}.tabulator-row.tabulator-selected{background-color:var(--tabulator-row-selected-background)}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-selected:hover{background-color:var(--tabulator-row-selected-background-hover);cursor:pointer}}.tabulator-row.tabulator-row-moving{background:#fff;border:1px solid #000}.tabulator-row.tabulator-moving{border-bottom:1px solid var(--tabulator-row-border-color);border-top:1px solid var(--tabulator-row-border-color);pointer-events:none;position:absolute;z-index:15}.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header{background-color:var(--tabulator-range-header-highlight-background);color:var(--tabulator-range-header-text-highlight-background)}.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header,.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header{background-color:var(--tabulator-range-header-selected-background);color:var(--tabulator-range-header-selected-text-color)}.tabulator-row .tabulator-row-resize-handle{bottom:0;height:5px;left:0;position:absolute;right:0}.tabulator-row .tabulator-row-resize-handle.prev{bottom:auto;top:0}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-row-resize-handle:hover{cursor:ns-resize}}.tabulator-row .tabulator-responsive-collapse{border-bottom:1px solid var(--tabulator-row-border-color);border-top:1px solid var(--tabulator-row-border-color);box-sizing:border-box;padding:5px}.tabulator-row .tabulator-responsive-collapse:empty{display:none}.tabulator-row .tabulator-responsive-collapse table{font-size:var(--tabulator-text-size)}.tabulator-row .tabulator-responsive-collapse table tr td{position:relative}.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type{padding-right:10px}.tabulator-row .tabulator-cell{border-right:1px solid var(--tabulator-row-border-color);box-sizing:border-box;display:inline-block;outline:none;overflow:hidden;padding:4px;position:relative;text-overflow:ellipsis;vertical-align:middle;white-space:nowrap}.tabulator-row .tabulator-cell.tabulator-row-header{border-bottom:1px solid var(--tabulator-row-border-color)}.tabulator-row .tabulator-cell.tabulator-frozen{background-color:inherit;display:inline-block;left:0;position:sticky;z-index:11}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-right:2px solid var(--tabulator-row-border-color)}.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-left:2px solid var(--tabulator-row-border-color)}.tabulator-row .tabulator-cell.tabulator-editing{border:1px solid var(--tabulator-edit-box-color);outline:none;padding:0}.tabulator-row .tabulator-cell.tabulator-editing input,.tabulator-row .tabulator-cell.tabulator-editing select{background:transparent;border:1px;outline:none}.tabulator-row .tabulator-cell.tabulator-validation-fail{border:1px solid var(--tabulator-error-color)}.tabulator-row .tabulator-cell.tabulator-validation-fail input,.tabulator-row .tabulator-cell.tabulator-validation-fail select{background:transparent;border:1px;color:var(--tabulator-error-color)}.tabulator-row .tabulator-cell.tabulator-row-handle{align-items:center;display:inline-flex;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box{width:80%}.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar{background:#666;height:3px;margin-top:2px;width:100%}.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header){background-color:var(--tabulator-row-selected-background)}.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty{display:inline-block;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom:2px solid var(--tabulator-row-border-color);border-bottom-left-radius:1px;border-left:2px solid var(--tabulator-row-border-color);display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid var(--tabulator-row-text-color);border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:var(--tabulator-row-text-color);content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:var(--tabulator-row-text-color);display:inline-block;height:7px;position:relative;width:1px}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:var(--tabulator-row-text-color);content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle{align-items:center;background:#666;border-radius:20px;color:var(--tabulator-row-background-color);display:inline-flex;font-size:1.1em;font-weight:700;height:15px;justify-content:center;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;width:15px}@media (hover:hover) and (pointer:fine){.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover{cursor:pointer;opacity:.7}}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close{display:initial}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open{display:none}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg{stroke:var(--tabulator-row-background-color)}.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close{display:none}.tabulator-row .tabulator-cell .tabulator-traffic-light{border-radius:14px;display:inline-block;height:14px;width:14px}.tabulator-row.tabulator-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid var(--tabulator-row-border-color);border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-row.tabulator-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid var(--tabulator-sort-arrow-active);margin-right:10px}.tabulator-row.tabulator-group.tabulator-group-level-1{padding-left:30px}.tabulator-row.tabulator-group.tabulator-group-level-2{padding-left:50px}.tabulator-row.tabulator-group.tabulator-group-level-3{padding-left:70px}.tabulator-row.tabulator-group.tabulator-group-level-4{padding-left:90px}.tabulator-row.tabulator-group.tabulator-group-level-5{padding-left:110px}.tabulator-row.tabulator-group .tabulator-group-toggle{display:inline-block}.tabulator-row.tabulator-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid var(--tabulator-sort-arrow-active);border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-row.tabulator-group span{color:#d00}.tabulator-toggle{background:#dcdcdc;border:1px solid #ccc;box-sizing:border-box;display:flex;flex-direction:row}.tabulator-toggle.tabulator-toggle-on{background:#1c6cc2}.tabulator-toggle .tabulator-toggle-switch{background:#fff;border:1px solid #ccc;box-sizing:border-box}.tabulator-popup-container{-webkit-overflow-scrolling:touch;background:var(--tabulator-row-background-color);border:1px solid var(--tabulator-row-border-color);box-shadow:0 0 5px 0 rgba(0,0,0,.2);box-sizing:border-box;display:inline-block;font-size:var(--tabulator-text-size);overflow-y:auto;position:absolute;z-index:10000}.tabulator-popup{border-radius:3px;padding:5px}.tabulator-tooltip{border-radius:2px;box-shadow:none;font-size:12px;max-width:min(500px,100%);padding:3px 5px;pointer-events:none}.tabulator-menu .tabulator-menu-item{box-sizing:border-box;padding:5px 10px;position:relative;user-select:none}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled{opacity:.5}@media (hover:hover) and (pointer:fine){.tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover{background:var(--tabulator-row-alt-background-color);cursor:pointer}}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu{padding-right:25px}.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after{border-color:var(--tabulator-row-border-color);border-style:solid;border-width:1px 1px 0 0;content:"";display:inline-block;height:7px;position:absolute;right:10px;top:calc(5px + .4em);transform:rotate(45deg);vertical-align:top;width:7px}.tabulator-menu .tabulator-menu-separator{border-top:1px solid var(--tabulator-row-border-color)}.tabulator-edit-list{-webkit-overflow-scrolling:touch;font-size:var(--tabulator-text-size);max-height:200px;overflow-y:auto}.tabulator-edit-list .tabulator-edit-list-item{color:var(--tabulator-row-text-color);outline:none;padding:4px}.tabulator-edit-list .tabulator-edit-list-item.active{background:var(--tabulator-edit-box-color);color:var(--tabulator-row-background-color)}.tabulator-edit-list .tabulator-edit-list-item.active.focused{outline:1px solid rgba(var(--tabulator-row-background-color),.5)}.tabulator-edit-list .tabulator-edit-list-item.focused{outline:1px solid var(--tabulator-edit-box-color)}@media (hover:hover) and (pointer:fine){.tabulator-edit-list .tabulator-edit-list-item:hover{background:var(--tabulator-edit-box-color);color:var(--tabulator-row-background-color);cursor:pointer}}.tabulator-edit-list .tabulator-edit-list-placeholder{color:var(--tabulator-row-text-color);padding:4px;text-align:center}.tabulator-edit-list .tabulator-edit-list-group{border-bottom:1px solid var(--tabulator-row-border-color);color:var(--tabulator-row-text-color);font-weight:700;padding:6px 4px 4px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2{padding-left:12px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3{padding-left:20px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4{padding-left:28px}.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5,.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5{padding-left:36px}.tabulator.tabulator-ltr{direction:ltr}.tabulator.tabulator-rtl{direction:rtl;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:1px solid var(--tabulator-header-border-color);border-right:initial;text-align:initial}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{margin-left:-1px;margin-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-left:25px;padding-right:0}.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{left:8px;right:auto}.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after{background-color:var(--tabulator-range-handle-color);border-radius:999px;bottom:-3px;content:"";height:6px;left:-3px;position:absolute;right:auto;width:6px}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell{border-left:1px solid var(--tabulator-row-border-color);border-right:initial}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch{border-bottom-left-radius:0;border-bottom-right-radius:1px;border-left:initial;border-right:2px solid var(--tabulator-row-border-color);margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control{margin-left:5px;margin-right:0}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left{border-left:2px solid var(--tabulator-row-border-color)}.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right{border-right:2px solid var(--tabulator-row-border-color)}.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type{margin-left:0;margin-right:-3px;width:3px}.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder{text-align:initial}.tabulator-print-fullscreen{bottom:0;left:0;position:absolute;right:0;top:0;z-index:10000}body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen){display:none!important}.tabulator-print-table{border-collapse:collapse}.tabulator-print-table .tabulator-data-tree-branch{border-bottom:2px solid var(--tabulator-row-border-color);border-bottom-left-radius:1px;border-left:2px solid var(--tabulator-row-border-color);display:inline-block;height:9px;margin-right:5px;margin-top:-9px;vertical-align:middle;width:7px}.tabulator-print-table .tabulator-print-table-group{background:#ccc;border-bottom:1px solid #999;border-right:1px solid var(--tabulator-row-border-color);border-top:1px solid #999;box-sizing:border-box;font-weight:700;min-width:100%;padding:5px 5px 5px 10px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-print-table-group:hover{background-color:rgba(0,0,0,.1);cursor:pointer}}.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow{border-bottom:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid var(--tabulator-sort-arrow-active);margin-right:10px}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td{padding-left:30px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td{padding-left:50px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td{padding-left:70px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td{padding-left:90px!important}.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td{padding-left:110px!important}.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle{display:inline-block}.tabulator-print-table .tabulator-print-table-group .tabulator-arrow{border-bottom:6px solid transparent;border-left:6px solid var(--tabulator-sort-arrow-active);border-right:0;border-top:6px solid transparent;display:inline-block;height:0;margin-right:16px;vertical-align:middle;width:0}.tabulator-print-table .tabulator-print-table-group span{color:#d00}.tabulator-print-table .tabulator-data-tree-control{align-items:center;background:rgba(0,0,0,.1);border:1px solid var(--tabulator-row-text-color);border-radius:2px;display:inline-flex;height:11px;justify-content:center;margin-right:5px;overflow:hidden;vertical-align:middle;width:11px}@media (hover:hover) and (pointer:fine){.tabulator-print-table .tabulator-data-tree-control:hover{background:rgba(0,0,0,.2);cursor:pointer}}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse{background:transparent;display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after{background:var(--tabulator-row-text-color);content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand{background:var(--tabulator-row-text-color);display:inline-block;height:7px;position:relative;width:1px}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:var(--tabulator-row-text-color);content:"";height:1px;left:-3px;position:absolute;top:3px;width:7px}.tabulator{background-color:var(--tabulator-background-color);max-width:100%;width:100%}.tabulator .tabulator-header{color:inherit}.tabulator .tabulator-header .tabulator-col{border-top:none}.tabulator .tabulator-header .tabulator-col:first-of-type{border-left:none}.tabulator .tabulator-header .tabulator-col:last-of-type{border-right:none}.tabulator .tabulator-header .tabulator-col:not(first-of-type),.tabulator .tabulator-header .tabulator-col:not(last-of-type){border-right:1px solid var(--tabulator-header-border-color)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content{padding:var(--tabulator-cell-padding)}.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter{right:-10px}.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols{border-top:1px solid var(--tabulator-border-color)}.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title{padding-right:10px}.tabulator .tabulator-header .tabulator-calcs-holder{border-bottom:1px solid var(--tabulator-header-separator-color);width:100%}.tabulator .tabulator-header .tabulator-frozen-rows-holder{min-width:600%}.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty{display:none}.tabulator .tabulator-header .tabulator-frozen .tabulator-frozen-left,.tabulator .tabulator-header .tabulator-frozen .tabulator-frozen-right{background:inherit}.tabulator .tabulator-tableholder .tabulator-table{color:inherit}.tabulator .tabulator-footer{background-color:var(--tabulator-footer-background-color);color:inherit}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab{font-weight:400;padding:8px 12px}.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active{color:var(--tabulator-footer-active-color)}.tabulator .tabulator-footer .tabulator-paginator{color:inherit}.tabulator .tabulator-footer .tabulator-page{background:var(--tabulator-pagination-button-background);border-radius:0;border-right:none;color:var(--tabulator-pagination-button-color);margin:5px 0 0;padding:8px 12px}.tabulator .tabulator-footer .tabulator-page:first-of-type,.tabulator .tabulator-footer .tabulator-page[data-page=next]{border-bottom-left-radius:4px;border-top-left-radius:4px}.tabulator .tabulator-footer .tabulator-page:last-of-type,.tabulator .tabulator-footer .tabulator-page[data-page=prev]{border:1px solid var(--tabulator-footer-border-color);border-bottom-right-radius:4px;border-top-right-radius:4px}.tabulator .tabulator-footer .tabulator-page:not(disabled):hover{background:var(--tabulator-pagination-button-background-hover);color:var(--tabulator-pagination-button-color-hover)}.tabulator .tabulator-footer .tabulator-page.active,.tabulator .tabulator-footer .tabulator-page[data-page=first] :not(disabled):not(:hover),.tabulator .tabulator-footer .tabulator-page[data-page=last] :not(disabled):not(:hover),.tabulator .tabulator-footer .tabulator-page[data-page=next] :not(disabled):not(:hover),.tabulator .tabulator-footer .tabulator-page[data-page=prev] :not(disabled):not(:hover){color:var(--tabulator-pagination-button-color-active)}.tabulator.striped .tabulator-row:nth-child(2n){background-color:var(--tabulator-row-alt-background-color)}.tabulator.striped .tabulator-row:nth-child(2n).tabulator-selected{background-color:var(--tabulator-row-selected-background)!important}@media (hover:hover) and (pointer:fine){.tabulator.striped .tabulator-row:nth-child(2n).tabulator-selectable:hover{background-color:var(--tabulator-row-hover-background);cursor:pointer}.tabulator.striped .tabulator-row:nth-child(2n).tabulator-selected:hover{background-color:var(--tabulator-row-selected-background-hover)!important;cursor:pointer}}.tabulator-row{border-bottom:1px solid var(--tabulator-row-border-color);min-height:calc(var(--tabulator-text-size) + var(--tabulator-cell-padding)*2)}.tabulator-row.tabulator-row-even{background-color:var(--tabulator-row-background-color)}.tabulator-row .tabulator-cell{padding:var(--tabulator-cell-padding)}.tabulator-row .tabulator-cell:last-of-type{border-right:none}.tabulator-row .tabulator-cell.tabulator-row-header{background:var(--tabulator-header-background-color);border-bottom:none;border-right:1px solid var(--tabulator-border-color)}.tabulator-row .tabulator-cell .tabulator-data-tree-control{border:1px solid #ccc}.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after,.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand,.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#ccc}.tabulator-row.tabulator-group{background:#fafafa}.tabulator-row.tabulator-group span{color:#666;margin-left:10px}.tabulator-edit-select-list{background:var(--tabulator-header-background-color)}.tabulator-edit-select-list .tabulator-edit-select-list-item{color:inherit}.tabulator-edit-select-list .tabulator-edit-select-list-item.active{color:var(--tabulator-header-background-color)}.tabulator-edit-select-list .tabulator-edit-select-list-item.active.focused{outline:1px solid rgba(var(--tabulator-header-background-color),.5)}@media (hover:hover) and (pointer:fine){.tabulator-edit-select-list .tabulator-edit-select-list-item:hover{color:var(--tabulator-header-background-color)}}.tabulator-edit-select-list .tabulator-edit-select-list-group,.tabulator-edit-select-list .tabulator-edit-select-list-notice{color:inherit}.tabulator.tabulator-rtl .tabulator-header .tabulator-col{border-left:none;border-right:none}.tabulator-print-table .tabulator-print-table-group{background:#fafafa}.tabulator-print-table .tabulator-print-table-group span{color:#666;margin-left:10px}.tabulator-print-table .tabulator-data-tree-control{border:1px solid #ccc}.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after,.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand,.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after{background:#ccc} +:root { + --tabulator-background-color: #fff; + --tabulator-border-color: rgba(0, 0, 0, .12); + --tabulator-text-size: 16px; + --tabulator-header-background-color: #f5f5f5; + --tabulator-header-text-color: #555; + --tabulator-header-border-color: rgba(0, 0, 0, .12); + --tabulator-header-separator-color: rgba(0, 0, 0, .12); + --tabulator-header-margin: 4px; + --tabulator-sort-arrow-hover: #555; + --tabulator-sort-arrow-active: #666; + --tabulator-sort-arrow-inactive: #bbb; + --tabulator-column-resize-guide-color: #999; + --tabulator-row-background-color: #fff; + --tabulator-row-alt-background-color: #f8f8f8; + --tabulator-row-border-color: rgba(0, 0, 0, .12); + --tabulator-row-text-color: #333; + --tabulator-row-hover-background: #e1f5fe; + --tabulator-row-selected-background: #ace5ff; + --tabulator-row-selected-background-hover: #9bcfe8; + --tabulator-edit-box-color: #17161d; + --tabulator-error-color: #d00; + --tabulator-footer-background-color: transparent; + --tabulator-footer-text-color: #555; + --tabulator-footer-border-color: rgba(0, 0, 0, .12); + --tabulator-footer-separator-color: rgba(0, 0, 0, .12); + --tabulator-footer-active-color: #17161d; + --tabulator-spreadsheet-active-tab-color: #fff; + --tabulator-range-border-color: #17161d; + --tabulator-range-handle-color: #17161d; + --tabulator-range-header-selected-background: var(--tabulator-range-border-color); + --tabulator-range-header-selected-text-color: #fff; + --tabulator-range-header-highlight-background: colors-gray-timberwolf; + --tabulator-range-header-text-highlight-background: #fff; + --tabulator-pagination-button-background: #fff; + --tabulator-pagination-button-background-hover: #06c; + --tabulator-pagination-button-color: #999; + --tabulator-pagination-button-color-hover: #fff; + --tabulator-pagination-button-color-active: #000; + --tabulator-cell-padding: 15px +} + +body.vscode-dark, +body[data-jp-theme-light=false] { + --tabulator-background-color: #080808; + --tabulator-border-color: #666; + --tabulator-text-size: 16px; + --tabulator-header-background-color: #212121; + --tabulator-header-text-color: #555; + --tabulator-header-border-color: #666; + --tabulator-header-separator-color: #666; + --tabulator-header-margin: 4px; + --tabulator-sort-arrow-hover: #fff; + --tabulator-sort-arrow-active: #e6e6e6; + --tabulator-sort-arrow-inactive: #666; + --tabulator-column-resize-guide-color: #999; + --tabulator-row-background-color: #080808; + --tabulator-row-alt-background-color: #212121; + --tabulator-row-border-color: #666; + --tabulator-row-text-color: #f8f8f8; + --tabulator-row-hover-background: #333; + --tabulator-row-selected-background: #3d355d; + --tabulator-row-selected-background-hover: #483f69; + --tabulator-edit-box-color: #333; + --tabulator-error-color: #d00; + --tabulator-footer-background-color: transparent; + --tabulator-footer-text-color: #555; + --tabulator-footer-border-color: rgba(0, 0, 0, .12); + --tabulator-footer-separator-color: rgba(0, 0, 0, .12); + --tabulator-footer-active-color: #17161d; + --tabulator-spreadsheet-active-tab-color: #fff; + --tabulator-range-border-color: #17161d; + --tabulator-range-handle-color: var(--tabulator-range-border-color); + --tabulator-range-header-selected-background: var(--tabulator-range-border-color); + --tabulator-range-header-selected-text-color: #fff; + --tabulator-range-header-highlight-background: #d6d6d6; + --tabulator-range-header-text-highlight-background: #fff; + --tabulator-pagination-button-background: #212121; + --tabulator-pagination-button-background-hover: #555; + --tabulator-pagination-button-color: #999; + --tabulator-pagination-button-color-hover: #fff; + --tabulator-pagination-button-color-active: #fff; + --tabulator-cell-padding: 15px +} + +.tabulator { + border: 1px solid var(--tabulator-border-color); + font-size: var(--tabulator-text-size); + overflow: hidden; + position: relative; + text-align: left; + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0) +} + +.tabulator[tabulator-layout=fitDataFill] .tabulator-tableholder .tabulator-table { + min-width: 100% +} + +.tabulator[tabulator-layout=fitDataTable] { + display: inline-block +} + +.tabulator.tabulator-block-select, +.tabulator.tabulator-ranges .tabulator-cell:not(.tabulator-editing) { + user-select: none +} + +.tabulator .tabulator-header { + background-color: var(--tabulator-header-background-color); + border-bottom: 1px solid var(--tabulator-header-separator-color); + box-sizing: border-box; + color: var(--tabulator-header-text-color); + font-weight: 700; + outline: none; + overflow: hidden; + position: relative; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + white-space: nowrap; + width: 100% +} + +.tabulator .tabulator-header.tabulator-header-hidden { + display: none +} + +.tabulator .tabulator-header .tabulator-header-contents { + overflow: hidden; + position: relative +} + +.tabulator .tabulator-header .tabulator-header-contents .tabulator-headers { + display: inline-block +} + +.tabulator .tabulator-header .tabulator-col { + background: var(--tabulator-header-background-color); + border-right: 1px solid var(--tabulator-header-border-color); + box-sizing: border-box; + display: inline-flex; + flex-direction: column; + justify-content: flex-start; + overflow: hidden; + position: relative; + text-align: left; + vertical-align: bottom +} + +.tabulator .tabulator-header .tabulator-col.tabulator-moving { + background: hsl(var(--tabulator-header-background-color), calc(var(--tabulator-header-background-color) - 5%)) !important; + border: 1px solid var(--tabulator-header-separator-color); + pointer-events: none; + position: absolute +} + +.tabulator .tabulator-header .tabulator-col.tabulator-range-highlight { + background-color: var(--tabulator-range-header-highlight-background); + color: var(--tabulator-range-header-text-highlight-background) +} + +.tabulator .tabulator-header .tabulator-col.tabulator-range-selected { + background-color: var(--tabulator-range-header-selected-background); + color: var(--tabulator-range-header-selected-text-color) +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content { + box-sizing: border-box; + padding: 4px; + position: relative +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button { + padding: 0 8px +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-header-popup-button:hover { + cursor: pointer; + opacity: .6 +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title-holder { + position: relative +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { + box-sizing: border-box; + overflow: hidden; + text-overflow: ellipsis; + vertical-align: bottom; + white-space: nowrap; + width: 100% +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title.tabulator-col-title-wrap { + text-overflow: clip; + white-space: normal +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor { + background: #fff; + border: 1px solid #999; + box-sizing: border-box; + padding: 1px; + width: 100% +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-header-popup-button+.tabulator-title-editor { + width: calc(100% - 22px) +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter { + align-items: center; + bottom: 0; + display: flex; + position: absolute; + right: 4px; + top: 0 +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter .tabulator-arrow { + border-bottom: 6px solid var(--tabulator-sort-arrow-inactive); + border-left: 6px solid transparent; + border-right: 6px solid transparent; + height: 0; + width: 0 +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols { + border-top: 1px solid var(--tabulator-header-border-color); + display: flex; + margin-right: -1px; + overflow: hidden; + position: relative +} + +.tabulator .tabulator-header .tabulator-col .tabulator-header-filter { + box-sizing: border-box; + margin-top: 2px; + position: relative; + text-align: center; + width: 100% +} + +.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea { + height: auto !important +} + +.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg { + margin-top: 3px +} + +.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear { + height: 0; + width: 0 +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { + padding-right: 25px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-header .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover { + background-color: hsl(var(--tabulator-header-background-color), calc(var(--tabulator-header-background-color) - 10%)) !important; + cursor: pointer + } +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter { + color: var(--tabulator-sort-arrow-inactive) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover { + border-bottom: 6px solid var(--tabulator-sort-arrow-hover); + cursor: pointer + } +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=none] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow { + border-bottom: 6px solid var(--tabulator-sort-arrow-inactive); + border-top: none +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter { + color: var(--tabulator-sort-arrow-active) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover { + border-bottom: 6px solid var(--tabulator-sort-arrow-hover); + cursor: pointer + } +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=ascending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow { + border-bottom: 6px solid var(--tabulator-sort-arrow-active); + border-top: none +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter { + color: var(--tabulator-sort-arrow-active) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter.tabulator-col-sorter-element .tabulator-arrow:hover { + border-top: 6px solid var(--tabulator-sort-arrow-hover); + cursor: pointer + } +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort=descending] .tabulator-col-content .tabulator-col-sorter .tabulator-arrow { + border-bottom: none; + border-top: 6px solid var(--tabulator-sort-arrow-active); + color: var(--tabulator-sort-arrow-active) +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title { + align-items: center; + display: flex; + justify-content: center; + text-orientation: mixed; + writing-mode: vertical-rl +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title { + transform: rotate(180deg) +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title { + padding-right: 0; + padding-top: 20px +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title { + padding-bottom: 20px; + padding-right: 0 +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-sorter { + bottom: auto; + justify-content: center; + left: 0; + right: 0; + top: 4px +} + +.tabulator .tabulator-header .tabulator-frozen { + left: 0; + position: sticky; + z-index: 11 +} + +.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left { + border-right: 2px solid var(--tabulator-row-border-color) +} + +.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right { + border-left: 2px solid var(--tabulator-row-border-color) +} + +.tabulator .tabulator-header .tabulator-calcs-holder { + border-bottom: 1px solid var(--tabulator-header-border-color); + border-top: 1px solid var(--tabulator-row-border-color); + box-sizing: border-box; + display: inline-block +} + +.tabulator .tabulator-header .tabulator-calcs-holder, +.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row { + background: hsl(var(--tabulator-header-background-color), calc(var(--tabulator-header-background-color) + 5%)) !important +} + +.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle { + display: none +} + +.tabulator .tabulator-header .tabulator-frozen-rows-holder { + display: inline-block +} + +.tabulator .tabulator-tableholder { + -webkit-overflow-scrolling: touch; + overflow: auto; + position: relative; + white-space: nowrap; + width: 100% +} + +.tabulator .tabulator-tableholder:focus { + outline: none +} + +.tabulator .tabulator-tableholder .tabulator-placeholder { + align-items: center; + box-sizing: border-box; + display: flex; + justify-content: center; + min-width: 100%; + width: 100% +} + +.tabulator .tabulator-tableholder .tabulator-placeholder[tabulator-render-mode=virtual] { + min-height: 100% +} + +.tabulator .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents { + color: #ccc; + display: inline-block; + font-size: 20px; + font-weight: 700; + padding: 10px; + text-align: center; + white-space: normal +} + +.tabulator .tabulator-tableholder .tabulator-table { + background-color: var(--tabulator-row-background-color); + color: var(--tabulator-row-text-color); + display: inline-block; + overflow: visible; + position: relative; + white-space: nowrap +} + +.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs { + background: hsl(var(--tabulator-row-atl-background-color), calc(var(--tabulator-row-alt-background-color) - 5%)) !important; + font-weight: 700 +} + +.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top { + border-bottom: 2px solid var(--tabulator-row-border-color) +} + +.tabulator .tabulator-tableholder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom { + border-top: 2px solid var(--tabulator-row-border-color) +} + +.tabulator .tabulator-tableholder .tabulator-range-overlay { + inset: 0; + pointer-events: none; + position: absolute; + z-index: 10 +} + +.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range { + border: 1px solid var(--tabulator-range-border-color); + box-sizing: border-box; + position: absolute +} + +.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after { + background-color: var(--tabulator-range-handle-color); + border-radius: 999px; + bottom: -3px; + content: ""; + height: 6px; + position: absolute; + right: -3px; + width: 6px +} + +.tabulator .tabulator-tableholder .tabulator-range-overlay .tabulator-range-cell-active { + border: 2px solid var(--tabulator-range-border-color); + box-sizing: border-box; + position: absolute +} + +.tabulator .tabulator-footer { + color: var(--tabulator-footer-text-color); + font-weight: 700; + user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + white-space: nowrap +} + +.tabulator .tabulator-footer .tabulator-footer-contents { + align-items: center; + display: flex; + flex-direction: row; + justify-content: space-between; + padding: 5px 10px +} + +.tabulator .tabulator-footer .tabulator-footer-contents:empty { + display: none +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs { + margin-top: -5px; + overflow-x: auto +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab { + border: 1px solid var(--tabulator-border-color); + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + border-top: none; + display: inline-block; + font-size: .9em; + padding: 5px +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab:hover { + cursor: pointer; + opacity: .7 +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active { + background: var(--tabulator-spreadsheet-active-tab-color) +} + +.tabulator .tabulator-footer .tabulator-calcs-holder { + border-bottom: 1px solid var(--tabulator-row-border-color); + border-top: 1px solid var(--tabulator-row-border-color); + box-sizing: border-box; + overflow: hidden; + text-align: left; + width: 100% +} + +.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row { + display: inline-block +} + +.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle { + display: none +} + +.tabulator .tabulator-footer .tabulator-calcs-holder:only-child { + border-bottom: none; + margin-bottom: -5px +} + +.tabulator .tabulator-footer>*+.tabulator-page-counter { + margin-left: 10px +} + +.tabulator .tabulator-footer .tabulator-page-counter { + font-weight: 400 +} + +.tabulator .tabulator-footer .tabulator-paginator { + color: var(--tabulator-footer-text-color); + flex: 1; + font-family: inherit; + font-size: inherit; + font-weight: inherit; + text-align: right +} + +.tabulator .tabulator-footer .tabulator-page-size { + border: 1px solid var(--tabulator-footer-border-color); + border-radius: 3px; + display: inline-block; + margin: 0 5px; + padding: 2px 5px +} + +.tabulator .tabulator-footer .tabulator-pages { + margin: 0 7px +} + +.tabulator .tabulator-footer .tabulator-page { + background: hsla(0, 0%, 100%, .2); + border: 1px solid var(--tabulator-footer-border-color); + border-radius: 3px; + display: inline-block; + margin: 0 2px; + padding: 2px 5px +} + +.tabulator .tabulator-footer .tabulator-page.active { + color: var(--tabulator-footer-active-color) +} + +.tabulator .tabulator-footer .tabulator-page:disabled { + opacity: .5 +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-footer .tabulator-page:not(disabled):hover { + background: rgba(0, 0, 0, .2); + color: #fff; + cursor: pointer + } +} + +.tabulator .tabulator-col-resize-handle { + display: inline-block; + margin-left: -3px; + margin-right: -3px; + position: relative; + vertical-align: middle; + width: 6px; + z-index: 11 +} + +@media (hover:hover) and (pointer:fine) { + .tabulator .tabulator-col-resize-handle:hover { + cursor: ew-resize + } +} + +.tabulator .tabulator-col-resize-handle:last-of-type { + margin-right: 0; + width: 3px +} + +.tabulator .tabulator-col-resize-guide { + height: 100%; + margin-left: -.5px; + top: 0; + width: 4px +} + +.tabulator .tabulator-col-resize-guide, +.tabulator .tabulator-row-resize-guide { + background-color: var(--tabulator-column-resize-guide-color); + opacity: .5; + position: absolute +} + +.tabulator .tabulator-row-resize-guide { + height: 4px; + left: 0; + margin-top: -.5px; + width: 100% +} + +.tabulator .tabulator-alert { + align-items: center; + background: rgba(0, 0, 0, .4); + display: flex; + height: 100%; + left: 0; + position: absolute; + text-align: center; + top: 0; + width: 100%; + z-index: 100 +} + +.tabulator .tabulator-alert .tabulator-alert-msg { + background: #fff; + border-radius: 10px; + display: inline-block; + font-size: 16px; + font-weight: 700; + margin: 0 auto; + padding: 10px 20px +} + +.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-msg { + border: 4px solid #333; + color: #000 +} + +.tabulator .tabulator-alert .tabulator-alert-msg.tabulator-alert-state-error { + border: 4px solid #d00; + color: #590000 +} + +.tabulator-row { + background-color: var(--tabulator-row-background-color); + box-sizing: border-box; + min-height: calc(var(--tabulator-text-size) + var(--tabulator-header-margin)*2); + position: relative +} + +.tabulator-row.tabulator-row-even { + background-color: var(--tabulator-row-alt-background-color) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row.tabulator-selectable:hover { + background-color: var(--tabulator-row-hover-background); + cursor: pointer + } +} + +.tabulator-row.tabulator-selected { + background-color: var(--tabulator-row-selected-background) !important; +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row.tabulator-selected:hover { + background-color: var(--tabulator-row-selected-background-hover) !important; + cursor: pointer + } +} + +.tabulator-row.tabulator-row-moving { + background: #fff; + border: 1px solid #000 +} + +.tabulator-row.tabulator-moving { + border-bottom: 1px solid var(--tabulator-row-border-color); + border-top: 1px solid var(--tabulator-row-border-color); + pointer-events: none; + position: absolute; + z-index: 15 +} + +.tabulator-row.tabulator-range-highlight .tabulator-cell.tabulator-range-row-header { + background-color: var(--tabulator-range-header-highlight-background); + color: var(--tabulator-range-header-text-highlight-background) +} + +.tabulator-row.tabulator-range-highlight.tabulator-range-selected .tabulator-cell.tabulator-range-row-header, +.tabulator-row.tabulator-range-selected .tabulator-cell.tabulator-range-row-header { + background-color: var(--tabulator-range-header-selected-background); + color: var(--tabulator-range-header-selected-text-color) +} + +.tabulator-row .tabulator-row-resize-handle { + bottom: 0; + height: 5px; + left: 0; + position: absolute; + right: 0 +} + +.tabulator-row .tabulator-row-resize-handle.prev { + bottom: auto; + top: 0 +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row .tabulator-row-resize-handle:hover { + cursor: ns-resize + } +} + +.tabulator-row .tabulator-responsive-collapse { + border-bottom: 1px solid var(--tabulator-row-border-color); + border-top: 1px solid var(--tabulator-row-border-color); + box-sizing: border-box; + padding: 5px +} + +.tabulator-row .tabulator-responsive-collapse:empty { + display: none +} + +.tabulator-row .tabulator-responsive-collapse table { + font-size: var(--tabulator-text-size) +} + +.tabulator-row .tabulator-responsive-collapse table tr td { + position: relative +} + +.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type { + padding-right: 10px +} + +.tabulator-row .tabulator-cell { + border-right: 1px solid var(--tabulator-row-border-color); + box-sizing: border-box; + display: inline-block; + outline: none; + overflow: hidden; + padding: 4px; + position: relative; + text-overflow: ellipsis; + vertical-align: middle; + white-space: nowrap +} + +.tabulator-row .tabulator-cell.tabulator-row-header { + border-bottom: 1px solid var(--tabulator-row-border-color) +} + +.tabulator-row .tabulator-cell.tabulator-frozen { + background-color: inherit; + display: inline-block; + left: 0; + position: sticky; + z-index: 11 +} + +.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left { + border-right: 2px solid var(--tabulator-row-border-color) +} + +.tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right { + border-left: 2px solid var(--tabulator-row-border-color) +} + +.tabulator-row .tabulator-cell.tabulator-editing { + border: 1px solid var(--tabulator-edit-box-color); + outline: none; + padding: 0 +} + +.tabulator-row .tabulator-cell.tabulator-editing input, +.tabulator-row .tabulator-cell.tabulator-editing select { + background: transparent; + border: 1px; + outline: none +} + +.tabulator-row .tabulator-cell.tabulator-validation-fail { + border: 1px solid var(--tabulator-error-color) +} + +.tabulator-row .tabulator-cell.tabulator-validation-fail input, +.tabulator-row .tabulator-cell.tabulator-validation-fail select { + background: transparent; + border: 1px; + color: var(--tabulator-error-color) +} + +.tabulator-row .tabulator-cell.tabulator-row-handle { + align-items: center; + display: inline-flex; + justify-content: center; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none +} + +.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box { + width: 80% +} + +.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar { + background: #666; + height: 3px; + margin-top: 2px; + width: 100% +} + +.tabulator-row .tabulator-cell.tabulator-range-selected:not(.tabulator-range-only-cell-selected):not(.tabulator-range-row-header) { + background-color: var(--tabulator-row-selected-background) +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-branch-empty { + display: inline-block; + width: 7px +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-branch { + border-bottom: 2px solid var(--tabulator-row-border-color); + border-bottom-left-radius: 1px; + border-left: 2px solid var(--tabulator-row-border-color); + display: inline-block; + height: 9px; + margin-right: 5px; + margin-top: -9px; + vertical-align: middle; + width: 7px +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control { + align-items: center; + background: rgba(0, 0, 0, .1); + border: 1px solid var(--tabulator-row-text-color); + border-radius: 2px; + display: inline-flex; + height: 11px; + justify-content: center; + margin-right: 5px; + overflow: hidden; + vertical-align: middle; + width: 11px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row .tabulator-cell .tabulator-data-tree-control:hover { + background: rgba(0, 0, 0, .2); + cursor: pointer + } +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse { + background: transparent; + display: inline-block; + height: 7px; + position: relative; + width: 1px +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after { + background: var(--tabulator-row-text-color); + content: ""; + height: 1px; + left: -3px; + position: absolute; + top: 3px; + width: 7px +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand { + background: var(--tabulator-row-text-color); + display: inline-block; + height: 7px; + position: relative; + width: 1px +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after { + background: var(--tabulator-row-text-color); + content: ""; + height: 1px; + left: -3px; + position: absolute; + top: 3px; + width: 7px +} + +.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle { + align-items: center; + background: #666; + border-radius: 20px; + color: var(--tabulator-row-background-color); + display: inline-flex; + font-size: 1.1em; + font-weight: 700; + height: 15px; + justify-content: center; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + width: 15px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover { + cursor: pointer; + opacity: .7 + } +} + +.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close { + display: initial +} + +.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open { + display: none +} + +.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle svg { + stroke: var(--tabulator-row-background-color) +} + +.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close { + display: none +} + +.tabulator-row .tabulator-cell .tabulator-traffic-light { + border-radius: 14px; + display: inline-block; + height: 14px; + width: 14px +} + +.tabulator-row.tabulator-group { + background: #ccc; + border-bottom: 1px solid #999; + border-right: 1px solid var(--tabulator-row-border-color); + border-top: 1px solid #999; + box-sizing: border-box; + font-weight: 700; + min-width: 100%; + padding: 5px 5px 5px 10px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-row.tabulator-group:hover { + background-color: rgba(0, 0, 0, .1); + cursor: pointer + } +} + +.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow { + border-bottom: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid var(--tabulator-sort-arrow-active); + margin-right: 10px +} + +.tabulator-row.tabulator-group.tabulator-group-level-1 { + padding-left: 30px +} + +.tabulator-row.tabulator-group.tabulator-group-level-2 { + padding-left: 50px +} + +.tabulator-row.tabulator-group.tabulator-group-level-3 { + padding-left: 70px +} + +.tabulator-row.tabulator-group.tabulator-group-level-4 { + padding-left: 90px +} + +.tabulator-row.tabulator-group.tabulator-group-level-5 { + padding-left: 110px +} + +.tabulator-row.tabulator-group .tabulator-group-toggle { + display: inline-block +} + +.tabulator-row.tabulator-group .tabulator-arrow { + border-bottom: 6px solid transparent; + border-left: 6px solid var(--tabulator-sort-arrow-active); + border-right: 0; + border-top: 6px solid transparent; + display: inline-block; + height: 0; + margin-right: 16px; + vertical-align: middle; + width: 0 +} + +.tabulator-row.tabulator-group span { + color: #d00 +} + +.tabulator-toggle { + background: #dcdcdc; + border: 1px solid #ccc; + box-sizing: border-box; + display: flex; + flex-direction: row +} + +.tabulator-toggle.tabulator-toggle-on { + background: #1c6cc2 +} + +.tabulator-toggle .tabulator-toggle-switch { + background: #fff; + border: 1px solid #ccc; + box-sizing: border-box +} + +.tabulator-popup-container { + -webkit-overflow-scrolling: touch; + background: var(--tabulator-row-background-color); + border: 1px solid var(--tabulator-row-border-color); + box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2); + box-sizing: border-box; + display: inline-block; + font-size: var(--tabulator-text-size); + overflow-y: auto; + position: absolute; + z-index: 10000 +} + +.tabulator-popup { + border-radius: 3px; + padding: 5px +} + +.tabulator-tooltip { + border-radius: 2px; + box-shadow: none; + font-size: 12px; + max-width: min(500px, 100%); + padding: 3px 5px; + pointer-events: none +} + +.tabulator-menu .tabulator-menu-item { + box-sizing: border-box; + padding: 5px 10px; + position: relative; + user-select: none +} + +.tabulator-menu .tabulator-menu-item.tabulator-menu-item-disabled { + opacity: .5 +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-menu .tabulator-menu-item:not(.tabulator-menu-item-disabled):hover { + background: var(--tabulator-row-alt-background-color); + cursor: pointer + } +} + +.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu { + padding-right: 25px +} + +.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after { + border-color: var(--tabulator-row-border-color); + border-style: solid; + border-width: 1px 1px 0 0; + content: ""; + display: inline-block; + height: 7px; + position: absolute; + right: 10px; + top: calc(5px + .4em); + transform: rotate(45deg); + vertical-align: top; + width: 7px +} + +.tabulator-menu .tabulator-menu-separator { + border-top: 1px solid var(--tabulator-row-border-color) +} + +.tabulator-edit-list { + -webkit-overflow-scrolling: touch; + font-size: var(--tabulator-text-size); + max-height: 200px; + overflow-y: auto +} + +.tabulator-edit-list .tabulator-edit-list-item { + color: var(--tabulator-row-text-color); + outline: none; + padding: 4px +} + +.tabulator-edit-list .tabulator-edit-list-item.active { + background: var(--tabulator-edit-box-color); + color: var(--tabulator-row-background-color) +} + +.tabulator-edit-list .tabulator-edit-list-item.active.focused { + outline: 1px solid rgba(var(--tabulator-row-background-color), .5) +} + +.tabulator-edit-list .tabulator-edit-list-item.focused { + outline: 1px solid var(--tabulator-edit-box-color) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-edit-list .tabulator-edit-list-item:hover { + background: var(--tabulator-edit-box-color); + color: var(--tabulator-row-background-color); + cursor: pointer + } +} + +.tabulator-edit-list .tabulator-edit-list-placeholder { + color: var(--tabulator-row-text-color); + padding: 4px; + text-align: center +} + +.tabulator-edit-list .tabulator-edit-list-group { + border-bottom: 1px solid var(--tabulator-row-border-color); + color: var(--tabulator-row-text-color); + font-weight: 700; + padding: 6px 4px 4px +} + +.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-2, +.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-2 { + padding-left: 12px +} + +.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-3, +.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-3 { + padding-left: 20px +} + +.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-4, +.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-4 { + padding-left: 28px +} + +.tabulator-edit-list .tabulator-edit-list-group.tabulator-edit-list-group-level-5, +.tabulator-edit-list .tabulator-edit-list-item.tabulator-edit-list-group-level-5 { + padding-left: 36px +} + +.tabulator.tabulator-ltr { + direction: ltr +} + +.tabulator.tabulator-rtl { + direction: rtl; + text-align: initial +} + +.tabulator.tabulator-rtl .tabulator-header .tabulator-col { + border-left: 1px solid var(--tabulator-header-border-color); + border-right: initial; + text-align: initial +} + +.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols { + margin-left: -1px; + margin-right: 0 +} + +.tabulator.tabulator-rtl .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { + padding-left: 25px; + padding-right: 0 +} + +.tabulator.tabulator-rtl .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter { + left: 8px; + right: auto +} + +.tabulator.tabulator-rtl .tabulator-tableholder .tabulator-range-overlay .tabulator-range.tabulator-range-active:after { + background-color: var(--tabulator-range-handle-color); + border-radius: 999px; + bottom: -3px; + content: ""; + height: 6px; + left: -3px; + position: absolute; + right: auto; + width: 6px +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-cell { + border-left: 1px solid var(--tabulator-row-border-color); + border-right: initial +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-branch { + border-bottom-left-radius: 0; + border-bottom-right-radius: 1px; + border-left: initial; + border-right: 2px solid var(--tabulator-row-border-color); + margin-left: 5px; + margin-right: 0 +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-cell .tabulator-data-tree-control { + margin-left: 5px; + margin-right: 0 +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left { + border-left: 2px solid var(--tabulator-row-border-color) +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-right { + border-right: 2px solid var(--tabulator-row-border-color) +} + +.tabulator.tabulator-rtl .tabulator-row .tabulator-col-resize-handle:last-of-type { + margin-left: 0; + margin-right: -3px; + width: 3px +} + +.tabulator.tabulator-rtl .tabulator-footer .tabulator-calcs-holder { + text-align: initial +} + +.tabulator-print-fullscreen { + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; + z-index: 10000 +} + +body.tabulator-print-fullscreen-hide>:not(.tabulator-print-fullscreen) { + display: none !important +} + +.tabulator-print-table { + border-collapse: collapse +} + +.tabulator-print-table .tabulator-data-tree-branch { + border-bottom: 2px solid var(--tabulator-row-border-color); + border-bottom-left-radius: 1px; + border-left: 2px solid var(--tabulator-row-border-color); + display: inline-block; + height: 9px; + margin-right: 5px; + margin-top: -9px; + vertical-align: middle; + width: 7px +} + +.tabulator-print-table .tabulator-print-table-group { + background: #ccc; + border-bottom: 1px solid #999; + border-right: 1px solid var(--tabulator-row-border-color); + border-top: 1px solid #999; + box-sizing: border-box; + font-weight: 700; + min-width: 100%; + padding: 5px 5px 5px 10px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-print-table .tabulator-print-table-group:hover { + background-color: rgba(0, 0, 0, .1); + cursor: pointer + } +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-visible .tabulator-arrow { + border-bottom: 0; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-top: 6px solid var(--tabulator-sort-arrow-active); + margin-right: 10px +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-1 td { + padding-left: 30px !important +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-2 td { + padding-left: 50px !important +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-3 td { + padding-left: 70px !important +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-4 td { + padding-left: 90px !important +} + +.tabulator-print-table .tabulator-print-table-group.tabulator-group-level-5 td { + padding-left: 110px !important +} + +.tabulator-print-table .tabulator-print-table-group .tabulator-group-toggle { + display: inline-block +} + +.tabulator-print-table .tabulator-print-table-group .tabulator-arrow { + border-bottom: 6px solid transparent; + border-left: 6px solid var(--tabulator-sort-arrow-active); + border-right: 0; + border-top: 6px solid transparent; + display: inline-block; + height: 0; + margin-right: 16px; + vertical-align: middle; + width: 0 +} + +.tabulator-print-table .tabulator-print-table-group span { + color: #d00 +} + +.tabulator-print-table .tabulator-data-tree-control { + align-items: center; + background: rgba(0, 0, 0, .1); + border: 1px solid var(--tabulator-row-text-color); + border-radius: 2px; + display: inline-flex; + height: 11px; + justify-content: center; + margin-right: 5px; + overflow: hidden; + vertical-align: middle; + width: 11px +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-print-table .tabulator-data-tree-control:hover { + background: rgba(0, 0, 0, .2); + cursor: pointer + } +} + +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse { + background: transparent; + display: inline-block; + height: 7px; + position: relative; + width: 1px +} + +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after { + background: var(--tabulator-row-text-color); + content: ""; + height: 1px; + left: -3px; + position: absolute; + top: 3px; + width: 7px +} + +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand { + background: var(--tabulator-row-text-color); + display: inline-block; + height: 7px; + position: relative; + width: 1px +} + +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after { + background: var(--tabulator-row-text-color); + content: ""; + height: 1px; + left: -3px; + position: absolute; + top: 3px; + width: 7px +} + +.tabulator { + background-color: var(--tabulator-background-color); + max-width: 100%; + width: 100% +} + +.tabulator .tabulator-header { + color: inherit +} + +.tabulator .tabulator-header .tabulator-col { + border-top: none +} + +.tabulator .tabulator-header .tabulator-col:first-of-type { + border-left: none +} + +.tabulator .tabulator-header .tabulator-col:last-of-type { + border-right: none +} + +.tabulator .tabulator-header .tabulator-col:not(first-of-type), +.tabulator .tabulator-header .tabulator-col:not(last-of-type) { + border-right: 1px solid var(--tabulator-header-border-color) +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content { + padding: var(--tabulator-cell-padding) +} + +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-sorter { + right: -10px +} + +.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols { + border-top: 1px solid var(--tabulator-border-color) +} + +.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { + padding-right: 10px +} + +.tabulator .tabulator-header .tabulator-calcs-holder { + border-bottom: 1px solid var(--tabulator-header-separator-color); + width: 100% +} + +.tabulator .tabulator-header .tabulator-frozen-rows-holder { + min-width: 600% +} + +.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty { + display: none +} + +.tabulator .tabulator-header .tabulator-frozen .tabulator-frozen-left, +.tabulator .tabulator-header .tabulator-frozen .tabulator-frozen-right { + background: inherit +} + +.tabulator .tabulator-tableholder .tabulator-table { + color: inherit +} + +.tabulator .tabulator-footer { + background-color: var(--tabulator-footer-background-color); + color: inherit +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab { + font-weight: 400; + padding: 8px 12px +} + +.tabulator .tabulator-footer .tabulator-spreadsheet-tabs .tabulator-spreadsheet-tab.tabulator-spreadsheet-tab-active { + color: var(--tabulator-footer-active-color) +} + +.tabulator .tabulator-footer .tabulator-paginator { + color: inherit +} + +.tabulator .tabulator-footer .tabulator-page { + background: var(--tabulator-pagination-button-background); + border-radius: 0; + border-right: none; + color: var(--tabulator-pagination-button-color); + margin: 5px 0 0; + padding: 8px 12px +} + +.tabulator .tabulator-footer .tabulator-page:first-of-type, +.tabulator .tabulator-footer .tabulator-page[data-page=next] { + border-bottom-left-radius: 4px; + border-top-left-radius: 4px +} + +.tabulator .tabulator-footer .tabulator-page:last-of-type, +.tabulator .tabulator-footer .tabulator-page[data-page=prev] { + border: 1px solid var(--tabulator-footer-border-color); + border-bottom-right-radius: 4px; + border-top-right-radius: 4px +} + +.tabulator .tabulator-footer .tabulator-page:not(disabled):hover { + background: var(--tabulator-pagination-button-background-hover); + color: var(--tabulator-pagination-button-color-hover) +} + +.tabulator .tabulator-footer .tabulator-page.active, +.tabulator .tabulator-footer .tabulator-page[data-page=first] :not(disabled):not(:hover), +.tabulator .tabulator-footer .tabulator-page[data-page=last] :not(disabled):not(:hover), +.tabulator .tabulator-footer .tabulator-page[data-page=next] :not(disabled):not(:hover), +.tabulator .tabulator-footer .tabulator-page[data-page=prev] :not(disabled):not(:hover) { + color: var(--tabulator-pagination-button-color-active) +} + +.tabulator.striped .tabulator-row:nth-child(2n) { + background-color: var(--tabulator-row-alt-background-color) +} + +.tabulator.striped .tabulator-row:nth-child(2n).tabulator-selected { + background-color: var(--tabulator-row-selected-background) !important +} + +@media (hover:hover) and (pointer:fine) { + .tabulator.striped .tabulator-row:nth-child(2n).tabulator-selectable:hover { + background-color: var(--tabulator-row-hover-background); + cursor: pointer + } + + .tabulator.striped .tabulator-row:nth-child(2n).tabulator-selected:hover { + background-color: var(--tabulator-row-selected-background-hover) !important; + cursor: pointer + } +} + +.tabulator-row { + border-bottom: 1px solid var(--tabulator-row-border-color); + min-height: calc(var(--tabulator-text-size) + var(--tabulator-cell-padding)*2) +} + +.tabulator-row.tabulator-row-even { + background-color: var(--tabulator-row-background-color) +} + +.tabulator-row .tabulator-cell { + padding: var(--tabulator-cell-padding) +} + +.tabulator-row .tabulator-cell:last-of-type { + border-right: none +} + +.tabulator-row .tabulator-cell.tabulator-row-header { + background: var(--tabulator-header-background-color); + border-bottom: none; + border-right: 1px solid var(--tabulator-border-color) +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control { + border: 1px solid #ccc +} + +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after, +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand, +.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after { + background: #ccc +} + +.tabulator-row.tabulator-group { + background: #fafafa +} + +.tabulator-row.tabulator-group span { + color: #666; + margin-left: 10px +} + +.tabulator-edit-select-list { + background: var(--tabulator-header-background-color) +} + +.tabulator-edit-select-list .tabulator-edit-select-list-item { + color: inherit +} + +.tabulator-edit-select-list .tabulator-edit-select-list-item.active { + color: var(--tabulator-header-background-color) +} + +.tabulator-edit-select-list .tabulator-edit-select-list-item.active.focused { + outline: 1px solid rgba(var(--tabulator-header-background-color), .5) +} + +@media (hover:hover) and (pointer:fine) { + .tabulator-edit-select-list .tabulator-edit-select-list-item:hover { + color: var(--tabulator-header-background-color) + } +} + +.tabulator-edit-select-list .tabulator-edit-select-list-group, +.tabulator-edit-select-list .tabulator-edit-select-list-notice { + color: inherit +} + +.tabulator.tabulator-rtl .tabulator-header .tabulator-col { + border-left: none; + border-right: none +} + +.tabulator-print-table .tabulator-print-table-group { + background: #fafafa +} + +.tabulator-print-table .tabulator-print-table-group span { + color: #666; + margin-left: 10px +} + +.tabulator-print-table .tabulator-data-tree-control { + border: 1px solid #ccc +} + +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after, +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand, +.tabulator-print-table .tabulator-data-tree-control .tabulator-data-tree-control-expand:after { + background: #ccc +} + /*# sourceMappingURL=tabulator_pysyft.min.css.map */ \ No newline at end of file diff --git a/packages/syft/src/syft/assets/jinja/table.jinja2 b/packages/syft/src/syft/assets/jinja/table.jinja2 index 1eb580ef01a..7a44d798540 100644 --- a/packages/syft/src/syft/assets/jinja/table.jinja2 +++ b/packages/syft/src/syft/assets/jinja/table.jinja2 @@ -38,11 +38,14 @@ diff --git a/packages/syft/src/syft/assets/js/table.js b/packages/syft/src/syft/assets/js/table.js index 1a257627d6a..35fee482bd9 100644 --- a/packages/syft/src/syft/assets/js/table.js +++ b/packages/syft/src/syft/assets/js/table.js @@ -6,7 +6,6 @@ TABULATOR_CSS = document.querySelectorAll(".escape-unfocus").forEach((input) => { input.addEventListener("keydown", (event) => { if (event.key === "Escape") { - console.log("Escape key pressed"); event.stopPropagation(); input.blur(); } @@ -58,7 +57,15 @@ function load_tabulator(elementId) { }); } -function buildTable(columns, rowHeader, data, uid) { +function buildTable( + columns, + rowHeader, + data, + uid, + pagination = true, + maxHeight = null, + headerSort = true, +) { const tableId = `table-${uid}`; const searchBarId = `search-${uid}`; const numrowsId = `numrows-${uid}`; @@ -73,11 +80,14 @@ function buildTable(columns, rowHeader, data, uid) { data: data, columns: columns, rowHeader: rowHeader, + index: "_table_repr_index", layout: "fitDataStretch", resizableColumnFit: true, resizableColumnGuide: true, - pagination: "local", + pagination: pagination, paginationSize: 5, + maxHeight: maxHeight, + headerSort: headerSort, }); // Events needed for cell overflow: @@ -100,6 +110,7 @@ function buildTable(columns, rowHeader, data, uid) { numrowsElement.innerHTML = data.length; } + configureHighlightSingleRow(table, uid); configureSearch(table, searchBarId, columns); return table; @@ -129,3 +140,87 @@ function configureSearch(table, searchBarId, columns) { table.setFilter([filterArray]); }); } + +function configureHighlightSingleRow(table, uid) { + // Listener for rowHighlight events, with fields: + // uid: string, table uid + // index: number | string, row index to highlight + // jumpToRow: bool, if true, jumps to page where the row is located + document.addEventListener("rowHighlight", function (e) { + if (e.detail.uid === uid) { + let row_idx = e.detail.index; + let rows = table.getRows(); + for (let row of rows) { + if (row.getIndex() == row_idx) { + row.select(); + if (e.detail.jumpToRow) { + // catch promise in case the table does not have pagination + table.setPageToRow(row_idx).catch((_) => {}); + table.scrollToRow(row_idx, "top", false); + } + } else { + row.deselect(); + } + } + } + }); +} + +function waitForTable(uid, timeout = 1000) { + return new Promise((resolve, reject) => { + // Check if the table is ready immediately + if (window["table_" + uid]) { + resolve(); + } else { + // Otherwise, poll until the table is ready or timeout + var startTime = Date.now(); + var checkTableInterval = setInterval(function () { + if (window["table_" + uid]) { + clearInterval(checkTableInterval); + resolve(); + } else if (Date.now() - startTime > timeout) { + clearInterval(checkTableInterval); + reject(`Timeout: table_"${uid}" not found.`); + } + }, 100); + } + }); +} + +function highlightSingleRow(uid, index = null, jumpToRow = false) { + // Highlight a single row in the table with the given uid + // If index is not provided or doesn't exist, all rows are deselected + waitForTable(uid) + .then(() => { + document.dispatchEvent( + new CustomEvent("rowHighlight", { + detail: { uid, index, jumpToRow }, + }), + ); + }) + .catch((error) => { + console.log(error); + }); +} + +function updateTableCell(uid, index, field, value) { + // Update the value of a cell in the table with the given uid + waitForTable(uid) + .then(() => { + const table = window["table_" + uid]; + if (!table) { + throw new Error(`Table with uid ${uid} not found.`); + } + + const row = table.getRow(index); + if (!row) { + throw new Error(`Row with index ${index} not found.`); + } + + // Update the cell value + row.update({ [field]: value }); + }) + .catch((error) => { + console.error(error); + }); +} diff --git a/packages/syft/src/syft/client/syncing.py b/packages/syft/src/syft/client/syncing.py index 7185cb5316e..428117634ef 100644 --- a/packages/syft/src/syft/client/syncing.py +++ b/packages/syft/src/syft/client/syncing.py @@ -8,6 +8,7 @@ from ..service.sync.diff_state import NodeDiff from ..service.sync.diff_state import ObjectDiffBatch from ..service.sync.diff_state import SyncInstruction +from ..service.sync.resolve_widget import PaginatedResolveWidget from ..service.sync.resolve_widget import ResolveWidget from ..service.sync.sync_state import SyncState from ..types.uid import UID @@ -71,28 +72,18 @@ def compare_clients( ) -def get_user_input_for_resolve() -> SyncDecision: - options = [x.value for x in SyncDecision] - options_str = ", ".join(options[:-1]) + f" or {options[-1]}" - print(f"How do you want to sync these objects? choose between {options_str}") - - while True: - decision = input() - decision = decision.lower() - - try: - return SyncDecision(decision) - except ValueError: - print(f"Please choose between {options_str}") - - -def resolve(obj_diff_batch: ObjectDiffBatch) -> ResolveWidget: - widget = ResolveWidget(obj_diff_batch) - return widget +def resolve(obj: ObjectDiffBatch | NodeDiff) -> ResolveWidget | PaginatedResolveWidget: + if not isinstance(obj, ObjectDiffBatch | NodeDiff): + raise ValueError( + f"Invalid type: could not resolve object with type {type(obj).__qualname__}" + ) + return obj.resolve() @deprecated(reason="resolve_single has been renamed to resolve", return_syfterror=True) -def resolve_single(obj_diff_batch: ObjectDiffBatch) -> ResolveWidget: +def resolve_single( + obj_diff_batch: ObjectDiffBatch, +) -> ResolveWidget | PaginatedResolveWidget: return resolve(obj_diff_batch) diff --git a/packages/syft/src/syft/service/service.py b/packages/syft/src/syft/service/service.py index c28fc1157d1..55f2c1f4b5d 100644 --- a/packages/syft/src/syft/service/service.py +++ b/packages/syft/src/syft/service/service.py @@ -288,6 +288,10 @@ def reconstruct_args_kwargs( final_kwargs[param_key] = param.default else: raise Exception(f"Missing {param_key} not in kwargs.") + + if "context": + final_kwargs["context"] = kwargs["context"] + return (args, final_kwargs) diff --git a/packages/syft/src/syft/service/settings/settings_service.py b/packages/syft/src/syft/service/settings/settings_service.py index 30e8242ceb9..80ac0cdcc55 100644 --- a/packages/syft/src/syft/service/settings/settings_service.py +++ b/packages/syft/src/syft/service/settings/settings_service.py @@ -61,10 +61,36 @@ def set( else: return SyftError(message=result.err()) - @service_method(path="settings.update", name="update") + @service_method(path="settings.update", name="update", autosplat=["settings"]) def update( self, context: AuthedServiceContext, settings: NodeSettingsUpdate ) -> Result[SyftSuccess, SyftError]: + """ + Update the Node Settings using the provided values. + + Args: + name: Optional[str] + Node name + organization: Optional[str] + Organization name + description: Optional[str] + Node description + on_board: Optional[bool] + Show onboarding panel when a user logs in for the first time + signup_enabled: Optional[bool] + Enable/Disable registration + admin_email: Optional[str] + Administrator email + association_request_auto_approval: Optional[bool] + + Returns: + Result[SyftSuccess, SyftError]: A result indicating the success or failure of the update operation. + + Example: + >>> node_client.update(name='foo', organization='bar', description='baz', signup_enabled=True) + SyftSuccess: Settings updated successfully. + """ + result = self.stash.get_all(context.credentials) if result.is_ok(): current_settings = result.ok() @@ -139,7 +165,7 @@ def allow_guest_signup( result = method(context=context, settings=settings) - if result.is_err(): + if isinstance(result, SyftError): return SyftError(message=f"Failed to update settings: {result.err()}") message = "enabled" if enable else "disabled" diff --git a/packages/syft/src/syft/service/sync/diff_state.py b/packages/syft/src/syft/service/sync/diff_state.py index 3cb360eafa4..f943174d75a 100644 --- a/packages/syft/src/syft/service/sync/diff_state.py +++ b/packages/syft/src/syft/service/sync/diff_state.py @@ -9,6 +9,7 @@ from typing import Any from typing import ClassVar from typing import Literal +from typing import TYPE_CHECKING # third party from loguru import logger @@ -38,6 +39,7 @@ from ...types.uid import UID from ...util import options from ...util.colors import SURFACE +from ...util.notebook_ui.components.sync import Label from ...util.notebook_ui.components.sync import SyncTableObject from ...util.notebook_ui.icons import Icon from ...util.notebook_ui.styles import FONT_CSS @@ -59,6 +61,11 @@ from ..user.user import UserView from .sync_state import SyncState +if TYPE_CHECKING: + # relative + from .resolve_widget import PaginatedResolveWidget + from .resolve_widget import ResolveWidget + sketchy_tab = "‎ " * 4 @@ -554,6 +561,12 @@ class ObjectDiffBatch(SyftObject): root_diff: ObjectDiff sync_direction: SyncDirection | None + def resolve(self) -> "ResolveWidget": + # relative + from .resolve_widget import ResolveWidget + + return ResolveWidget(self) + def walk_graph( self, deps: dict[UID, list[UID]], @@ -704,6 +717,21 @@ def root_id(self) -> UID: def root_type(self) -> type: return self.root_diff.obj_type + def decision_badge(self) -> str: + if self.decision is None: + return "" + if self.decision == SyncDecision.IGNORE: + decision_str = "IGNORED" + badge_color = "label-red" + if self.decision == SyncDecision.SKIP: + decision_str = "SKIPPED" + badge_color = "label-gray" + else: + decision_str = "SYNCED" + badge_color = "label-green" + + return Label(value=decision_str, label_class=badge_color).to_html() + @property def is_ignored(self) -> bool: return self.decision == SyncDecision.IGNORE @@ -846,9 +874,10 @@ def _coll_repr_(self) -> dict[str, Any]: high_html = SyncTableObject(object=self.root_diff.high_obj).to_html() return { - "Merge status": self.status_badge(), + "Diff status": self.status_badge(), "Public Sync State": low_html, "Private sync state": high_html, + "Decision": self.decision_badge(), } @property @@ -1118,6 +1147,12 @@ class NodeDiff(SyftObject): include_ignored: bool = False + def resolve(self) -> "PaginatedResolveWidget": + # relative + from .resolve_widget import PaginatedResolveWidget + + return PaginatedResolveWidget(batches=self.batches) + def __getitem__(self, idx: Any) -> ObjectDiffBatch: return self.batches[idx] diff --git a/packages/syft/src/syft/service/sync/resolve_widget.py b/packages/syft/src/syft/service/sync/resolve_widget.py index dd9dadc505e..261ed28e075 100644 --- a/packages/syft/src/syft/service/sync/resolve_widget.py +++ b/packages/syft/src/syft/service/sync/resolve_widget.py @@ -1,11 +1,15 @@ # stdlib +from collections.abc import Callable from enum import Enum from enum import auto +from functools import partial import html +import secrets from typing import Any from uuid import uuid4 # third party +from IPython import display import ipywidgets as widgets from ipywidgets import Button from ipywidgets import Checkbox @@ -22,6 +26,9 @@ from ...util.notebook_ui.components.sync import MainDescription from ...util.notebook_ui.components.sync import SyncWidgetHeader from ...util.notebook_ui.components.sync import TypeLabel +from ...util.notebook_ui.components.tabulator_template import build_tabulator_table +from ...util.notebook_ui.components.tabulator_template import highlight_single_row +from ...util.notebook_ui.components.tabulator_template import update_table_cell from ...util.notebook_ui.styles import CSS_CODE from ..action.action_object import ActionObject from ..api.api import TwinAPIEndpoint @@ -406,11 +413,14 @@ def _on_share_private_data_change(self, change: Any) -> None: class ResolveWidget: - def __init__(self, obj_diff_batch: ObjectDiffBatch): + def __init__( + self, obj_diff_batch: ObjectDiffBatch, on_sync_callback: Callable | None = None + ): self.obj_diff_batch: ObjectDiffBatch = obj_diff_batch self.id2widget: dict[ UID, CollapsableObjectDiffWidget | MainObjectDiffWidget ] = {} + self.on_sync_callback = on_sync_callback self.main_widget = self.build() self.result_widget = VBox() # Placeholder for SyftSuccess / SyftError self.widget = VBox( @@ -463,6 +473,8 @@ def click_sync(self, *args: list, **kwargs: dict) -> SyftSuccess | SyftError: ) self.set_widget_result_state(res) + if self.on_sync_callback: + self.on_sync_callback() return res @property @@ -590,3 +602,191 @@ def separator(self) -> widgets.HTML: def build_header(self) -> HTML: header_html = SyncWidgetHeader(diff_batch=self.obj_diff_batch).to_html() return HTML(value=header_html) + + +class PaginationControl: + def __init__(self, data: list, callback: Callable[[int], None]): + self.data = data + self.callback = callback + self.current_index = 0 + self.index_label = widgets.Label(value=f"Index: {self.current_index}") + + self.first_button = widgets.Button(description="First") + self.previous_button = widgets.Button(description="Previous") + self.next_button = widgets.Button(description="Next") + self.last_button = widgets.Button(description="Last") + + self.first_button.on_click(self.go_to_first) + self.previous_button.on_click(self.go_to_previous) + self.next_button.on_click(self.go_to_next) + self.last_button.on_click(self.go_to_last) + self.output = widgets.Output() + + self.buttons = widgets.HBox( + [ + self.first_button, + self.previous_button, + self.next_button, + self.last_button, + ] + ) + self.update_buttons() + self.update_index_callback() + + def update_index_label(self) -> None: + self.index_label.value = f"Current: {self.current_index}" + + def update_buttons(self) -> None: + self.first_button.disabled = self.current_index == 0 + self.previous_button.disabled = self.current_index == 0 + self.next_button.disabled = self.current_index == len(self.data) - 1 + self.last_button.disabled = self.current_index == len(self.data) - 1 + + def go_to_first(self, b: Button | None) -> None: + self.current_index = 0 + self.update_index_callback() + + def go_to_previous(self, b: Button | None) -> None: + if self.current_index > 0: + self.current_index -= 1 + self.update_index_callback() + + def go_to_next(self, b: Button | None) -> None: + if self.current_index < len(self.data) - 1: + self.current_index += 1 + self.update_index_callback() + + def go_to_last(self, b: Button | None) -> None: + self.current_index = len(self.data) - 1 + self.update_index_callback() + + def update_index_callback(self) -> None: + self.update_index_label() + self.update_buttons() + + # NOTE self.output is required to display IPython.display.HTML + # IPython.display.HTML is used to execute JS code + with self.output: + self.callback(self.current_index) + + def build(self) -> widgets.VBox: + return widgets.VBox( + [widgets.HBox([self.buttons, self.index_label]), self.output] + ) + + +class PaginatedWidget: + def __init__( + self, children: list, on_paginate_callback: Callable[[int], None] | None = None + ): + # on_paginate_callback is an optional secondary callback, + # called after updating the page index and displaying the new widget + self.children = children + self.on_paginate_callback = on_paginate_callback + self.current_index = 0 + self.container = widgets.VBox() + + self.pagination_control = PaginationControl(children, self.on_paginate) + + # Initial display + self.on_paginate(self.pagination_control.current_index) + + def __getitem__(self, index: int) -> widgets.Widget: + return self.children[index] + + def on_paginate(self, index: int) -> None: + self.container.children = [self.children[index]] + if self.on_paginate_callback: + self.on_paginate_callback(index) + + def spacer(self, height: int) -> widgets.HTML: + return widgets.HTML(f"
") + + def build(self) -> widgets.VBox: + return widgets.VBox( + [self.pagination_control.build(), self.spacer(8), self.container] + ) + + +class PaginatedResolveWidget: + """ + PaginatedResolveWidget is a widget that displays + a ResolveWidget for each ObjectDiffBatch, + paginated by a PaginationControl widget. + """ + + def __init__(self, batches: list[ObjectDiffBatch]): + self.batches = batches + self.resolve_widgets: list[ResolveWidget] = [ + ResolveWidget( + batch, + on_sync_callback=partial(self.on_click_sync, i), + ) + for i, batch in enumerate(self.batches) + ] + + self.table_uid = secrets.token_hex(4) + + # Disable the table pagination to avoid the double pagination buttons + self.batch_table = build_tabulator_table( + obj=batches, + uid=self.table_uid, + max_height=500, + pagination=False, + header_sort=False, + ) + + self.paginated_widget = PaginatedWidget( + children=[widget.widget for widget in self.resolve_widgets], + on_paginate_callback=self.on_paginate, + ) + + self.table_output = widgets.Output() + with self.table_output: + display.display(display.HTML(self.batch_table)) + highlight_single_row( + self.table_uid, self.paginated_widget.current_index, jump_to_row=True + ) + + self.widget = self.build() + + def on_click_sync(self, index: int) -> None: + self.update_table_sync_decision(index) + if self.batches[index].decision is not None: + self.paginated_widget.pagination_control.go_to_next(None) + + def update_table_sync_decision(self, index: int) -> None: + new_decision = self.batches[index].decision_badge() + with self.table_output: + update_table_cell( + uid=self.table_uid, + index=index, + field="Decision", + value=new_decision, + ) + + def __getitem__(self, index: int) -> ResolveWidget: + return self.resolve_widgets[index] + + def on_paginate(self, index: int) -> None: + return highlight_single_row(self.table_uid, index, jump_to_row=True) + + def build(self) -> widgets.VBox: + return widgets.VBox([self.table_output, self.paginated_widget.build()]) + + def click_sync(self, index: int) -> SyftSuccess | SyftError: + return self.resolve_widgets[index].click_sync() + + def click_share_all_private_data(self, index: int) -> None: + self.resolve_widgets[index].click_share_all_private_data() + + def _share_all(self) -> None: + for widget in self.resolve_widgets: + widget.click_share_all_private_data() + + def _sync_all(self) -> None: + for widget in self.resolve_widgets: + widget.click_sync() + + def _repr_mimebundle_(self, **kwargs: dict) -> dict[str, str] | None: + return self.widget._repr_mimebundle_(**kwargs) diff --git a/packages/syft/src/syft/util/notebook_ui/components/tabulator_template.py b/packages/syft/src/syft/util/notebook_ui/components/tabulator_template.py index 60ba8da4915..ee0576cc206 100644 --- a/packages/syft/src/syft/util/notebook_ui/components/tabulator_template.py +++ b/packages/syft/src/syft/util/notebook_ui/components/tabulator_template.py @@ -23,6 +23,7 @@ def create_tabulator_columns( column_names: list[str], column_widths: dict | None = None, + header_sort: bool = True, ) -> tuple[list[dict], dict | None]: """Returns tuple of (columns, row_header) for tabulator table""" if column_widths is None: @@ -33,10 +34,10 @@ def create_tabulator_columns( if TABLE_INDEX_KEY in column_names: row_header = { "field": TABLE_INDEX_KEY, - "headerSort": True, "frozen": True, "widthGrow": 0.3, "minWidth": 60, + "headerSort": header_sort, } for colname in column_names: @@ -48,6 +49,7 @@ def create_tabulator_columns( "resizable": True, "minWidth": 60, "maxInitialWidth": 500, + "headerSort": header_sort, } if colname in column_widths: column["widthGrow"] = column_widths[colname] @@ -92,7 +94,13 @@ def format_table_data(table_data: list[dict[str, Any]]) -> list[dict[str, str]]: return formatted -def build_tabulator_table(obj: Any) -> str | None: +def build_tabulator_table( + obj: Any, + uid: str | None = None, + max_height: int | None = None, + pagination: bool = True, + header_sort: bool = True, +) -> str | None: try: table_data, table_metadata = prepare_table_data(obj) if len(table_data) == 0: @@ -113,10 +121,13 @@ def build_tabulator_table(obj: Any) -> str | None: if icon is None: icon = Icon.TABLE.svg - column_data, row_header = create_tabulator_columns(table_metadata["columns"]) + uid = uid if uid is not None else secrets.token_hex(4) + column_data, row_header = create_tabulator_columns( + table_metadata["columns"], header_sort=header_sort + ) table_data = format_table_data(table_data) table_html = table_template.render( - uid=secrets.token_hex(4), + uid=uid, columns=json.dumps(column_data), row_header=json.dumps(row_header), data=json.dumps(table_data), @@ -127,6 +138,9 @@ def build_tabulator_table(obj: Any) -> str | None: name=table_metadata["name"], tabulator_js=tabulator_js, tabulator_css=tabulator_css, + max_height=json.dumps(max_height), + pagination=json.dumps(pagination), + header_sort=json.dumps(header_sort), ) return table_html @@ -140,3 +154,21 @@ def show_table(obj: Any) -> None: table = build_tabulator_table(obj) if table is not None: display(HTML(table)) + + +def highlight_single_row( + table_uid: str, + index: int | str | None = None, + jump_to_row: bool = True, +) -> None: + js_code = f"" + display(HTML(js_code)) + + +def update_table_cell(uid: str, index: int, field: str, value: str) -> None: + js_code = f""" + + """ + display(HTML(js_code)) diff --git a/packages/syft/tests/syft/service/sync/sync_resolve_single_test.py b/packages/syft/tests/syft/service/sync/sync_resolve_single_test.py index b3972532521..07585c6de87 100644 --- a/packages/syft/tests/syft/service/sync/sync_resolve_single_test.py +++ b/packages/syft/tests/syft/service/sync/sync_resolve_single_test.py @@ -36,7 +36,7 @@ def compare_and_resolve( diff_state_before = compare_clients(from_client, to_client) for obj_diff_batch in diff_state_before.active_batches: widget = resolve( - obj_diff_batch=obj_diff_batch, + obj_diff_batch, ) if decision_callback: decision = decision_callback(obj_diff_batch) diff --git a/packages/syft/tests/syft/settings/settings_service_test.py b/packages/syft/tests/syft/settings/settings_service_test.py index 13592539a7f..56bf414f373 100644 --- a/packages/syft/tests/syft/settings/settings_service_test.py +++ b/packages/syft/tests/syft/settings/settings_service_test.py @@ -151,7 +151,7 @@ def mock_stash_get_all(root_verify_key) -> Ok: monkeypatch.setattr(settings_service.stash, "get_all", mock_stash_get_all) # update the settings in the settings stash using settings_service - response = settings_service.update(authed_context, update_settings) + response = settings_service.update(context=authed_context, settings=update_settings) # not_updated_settings = response.ok()[1] @@ -174,7 +174,7 @@ def mock_stash_get_all_error(credentials) -> Err: return Err(mock_error_message) monkeypatch.setattr(settings_service.stash, "get_all", mock_stash_get_all_error) - response = settings_service.update(authed_context, update_settings) + response = settings_service.update(context=authed_context, settings=update_settings) assert isinstance(response, SyftError) assert response.message == mock_error_message @@ -185,7 +185,7 @@ def test_settingsservice_update_stash_empty( update_settings: NodeSettingsUpdate, authed_context: AuthedServiceContext, ) -> None: - response = settings_service.update(authed_context, update_settings) + response = settings_service.update(context=authed_context, settings=update_settings) assert isinstance(response, SyftError) assert response.message == "No settings found" @@ -214,7 +214,7 @@ def mock_stash_update_error(credentials, update_settings: NodeSettings) -> Err: monkeypatch.setattr(settings_service.stash, "update", mock_stash_update_error) - response = settings_service.update(authed_context, update_settings) + response = settings_service.update(context=authed_context, settings=update_settings) assert isinstance(response, SyftError) assert response.message == mock_update_error_message diff --git a/packages/syft/tests/syft/users/user_service_test.py b/packages/syft/tests/syft/users/user_service_test.py index 54a32bef836..7c0cc32562a 100644 --- a/packages/syft/tests/syft/users/user_service_test.py +++ b/packages/syft/tests/syft/users/user_service_test.py @@ -229,7 +229,7 @@ def mock_find_all(credentials: SyftVerifyKey, **kwargs) -> Ok | Err: expected_output = [guest_user.to(UserView)] # Search via id - response = user_service.search(authed_context, id=guest_user.id) + response = user_service.search(context=authed_context, id=guest_user.id) assert isinstance(response, list) assert all( r.to_dict() == expected.to_dict() @@ -238,7 +238,7 @@ def mock_find_all(credentials: SyftVerifyKey, **kwargs) -> Ok | Err: # assert response.to_dict() == expected_output.to_dict() # Search via email - response = user_service.search(authed_context, email=guest_user.email) + response = user_service.search(context=authed_context, email=guest_user.email) assert isinstance(response, list) assert all( r.to_dict() == expected.to_dict() @@ -246,7 +246,7 @@ def mock_find_all(credentials: SyftVerifyKey, **kwargs) -> Ok | Err: ) # Search via name - response = user_service.search(authed_context, name=guest_user.name) + response = user_service.search(context=authed_context, name=guest_user.name) assert isinstance(response, list) assert all( r.to_dict() == expected.to_dict() @@ -255,7 +255,7 @@ def mock_find_all(credentials: SyftVerifyKey, **kwargs) -> Ok | Err: # Search via verify_key response = user_service.search( - authed_context, + context=authed_context, verify_key=guest_user.verify_key, ) assert isinstance(response, list) @@ -266,7 +266,7 @@ def mock_find_all(credentials: SyftVerifyKey, **kwargs) -> Ok | Err: # Search via multiple kwargs response = user_service.search( - authed_context, name=guest_user.name, email=guest_user.email + context=authed_context, name=guest_user.name, email=guest_user.email ) assert isinstance(response, list) assert all( @@ -279,7 +279,7 @@ def test_userservice_search_with_invalid_kwargs( user_service: UserService, authed_context: AuthedServiceContext ) -> None: # Search with invalid kwargs - response = user_service.search(authed_context, role=ServiceRole.GUEST) + response = user_service.search(context=authed_context, role=ServiceRole.GUEST) assert isinstance(response, SyftError) assert "Invalid Search parameters" in response.message