variable-explorer 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. variable_explorer/__init__.py +7 -0
  2. variable_explorer/_version.py +4 -0
  3. variable_explorer/kernel/__init__.py +5 -0
  4. variable_explorer/kernel/comm_handler.py +255 -0
  5. variable_explorer/kernel/data_provider.py +235 -0
  6. variable_explorer/kernel/editor.py +88 -0
  7. variable_explorer/kernel/introspection.py +186 -0
  8. variable_explorer/kernel/serialization.py +73 -0
  9. variable_explorer/kernel/sorter.py +34 -0
  10. variable_explorer/kernel/statistics.py +101 -0
  11. variable_explorer/labextension/build_log.json +726 -0
  12. variable_explorer/labextension/package.json +96 -0
  13. variable_explorer/labextension/schemas/variable-explorer/package.json.orig +91 -0
  14. variable_explorer/labextension/schemas/variable-explorer/plugin.json +75 -0
  15. variable_explorer/labextension/static/lib_index_js.88a2cd3be0f2bf49f0eb.js +1417 -0
  16. variable_explorer/labextension/static/lib_index_js.88a2cd3be0f2bf49f0eb.js.map +1 -0
  17. variable_explorer/labextension/static/remoteEntry.a8ed3dcc7548f0b68f93.js +576 -0
  18. variable_explorer/labextension/static/remoteEntry.a8ed3dcc7548f0b68f93.js.map +1 -0
  19. variable_explorer/labextension/static/style.js +4 -0
  20. variable_explorer/labextension/static/style_index_js-data_font_woff2_charset_utf-8_base64_d09GMgABAAAAABmsAAsAAAAANbQAABlcAAEAAAAAA-5c9677.c69a59632d259bde8f84.js +785 -0
  21. variable_explorer/labextension/static/style_index_js-data_font_woff2_charset_utf-8_base64_d09GMgABAAAAABmsAAsAAAAANbQAABlcAAEAAAAAA-5c9677.c69a59632d259bde8f84.js.map +1 -0
  22. variable_explorer/labextension/static/vendors-node_modules_ag-grid-community_dist_package_main_esm_mjs.c38425b170e91e5db052.js +50347 -0
  23. variable_explorer/labextension/static/vendors-node_modules_ag-grid-community_dist_package_main_esm_mjs.c38425b170e91e5db052.js.map +1 -0
  24. variable_explorer/labextension/static/vendors-node_modules_ag-grid-community_styles_ag-grid_css-node_modules_ag-grid-community_styl-7d25f0.7424d30423d9f1c112f6.js +8124 -0
  25. variable_explorer/labextension/static/vendors-node_modules_ag-grid-community_styles_ag-grid_css-node_modules_ag-grid-community_styl-7d25f0.7424d30423d9f1c112f6.js.map +1 -0
  26. variable_explorer/labextension/static/vendors-node_modules_ag-grid-react_dist_package_index_esm_mjs.ca52d36c364e6562240a.js +2917 -0
  27. variable_explorer/labextension/static/vendors-node_modules_ag-grid-react_dist_package_index_esm_mjs.ca52d36c364e6562240a.js.map +1 -0
  28. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/build_log.json +726 -0
  29. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/install.json +5 -0
  30. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/package.json +96 -0
  31. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/schemas/variable-explorer/package.json.orig +91 -0
  32. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/schemas/variable-explorer/plugin.json +75 -0
  33. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/lib_index_js.88a2cd3be0f2bf49f0eb.js +1417 -0
  34. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/lib_index_js.88a2cd3be0f2bf49f0eb.js.map +1 -0
  35. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/remoteEntry.a8ed3dcc7548f0b68f93.js +576 -0
  36. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/remoteEntry.a8ed3dcc7548f0b68f93.js.map +1 -0
  37. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/style.js +4 -0
  38. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/style_index_js-data_font_woff2_charset_utf-8_base64_d09GMgABAAAAABmsAAsAAAAANbQAABlcAAEAAAAAA-5c9677.c69a59632d259bde8f84.js +785 -0
  39. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/style_index_js-data_font_woff2_charset_utf-8_base64_d09GMgABAAAAABmsAAsAAAAANbQAABlcAAEAAAAAA-5c9677.c69a59632d259bde8f84.js.map +1 -0
  40. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-community_dist_package_main_esm_mjs.c38425b170e91e5db052.js +50347 -0
  41. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-community_dist_package_main_esm_mjs.c38425b170e91e5db052.js.map +1 -0
  42. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-community_styles_ag-grid_css-node_modules_ag-grid-community_styl-7d25f0.7424d30423d9f1c112f6.js +8124 -0
  43. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-community_styles_ag-grid_css-node_modules_ag-grid-community_styl-7d25f0.7424d30423d9f1c112f6.js.map +1 -0
  44. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-react_dist_package_index_esm_mjs.ca52d36c364e6562240a.js +2917 -0
  45. variable_explorer-0.1.0.data/data/share/jupyter/labextensions/variable-explorer/static/vendors-node_modules_ag-grid-react_dist_package_index_esm_mjs.ca52d36c364e6562240a.js.map +1 -0
  46. variable_explorer-0.1.0.dist-info/METADATA +80 -0
  47. variable_explorer-0.1.0.dist-info/RECORD +49 -0
  48. variable_explorer-0.1.0.dist-info/WHEEL +4 -0
  49. variable_explorer-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib_index_js.88a2cd3be0f2bf49f0eb.js","mappings":";;;;;;;;;;;;;;;AAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,EAAE;AAC5D;AACA,4CAA4C,EAAE;AAC9C;AACO;AACP;AACA;AACA;AACA,oCAAoC,qDAAM;AAC1C,sCAAsC,qDAAM;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;;;;;;;;;;;;;;;;;ACpG+B;AACxB,4BAA4B,0BAA0B;AAC7D;AACA,YAAY,gDAAmB,UAAU,oCAAoC;AAC7E,QAAQ,gDAAmB,WAAW,+BAA+B;AACrE;AACA;AACA;AACA;AACA,QAAQ,gDAAmB,WAAW,iDAAiD;AACvF;;;;;;;;;;;;;;;;;;;;ACV+B;AACa;AACQ;AACgB;AAC7D,oBAAoB,iIAAiI;AAC5J,oBAAoB,yCAAY;AAChC;AACA,qBAAqB,0CAAa;AAClC;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,oBAAoB,0CAAa;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,6DAAe;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA,yCAAyC,kEAAc;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA,yCAAyC,gEAAY;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,0BAA0B;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;AACA,8BAA8B,8CAAiB;AAC/C;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB,cAAc;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,KAAK;AACL;AACA,8BAA8B,8CAAiB;AAC/C;AACA;AACA;AACA,KAAK;AACL;AACA,kCAAkC,8CAAiB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,gCAAgC,8CAAiB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,YAAY,gDAAmB,UAAU,8BAA8B;AACvE,QAAQ,gDAAmB,UAAU,gCAAgC,iCAAiC;AACtG,YAAY,gDAAmB,CAAC,sDAAW,IAAI;AAC/C;AACA;AACA;AACA,iBAAiB,sRAAsR,gBAAgB,iMAAiM,oBAAoB;AAC5gB;;;;;;;;;;;;;;;;;;AC1J+B;AAC4B;AAC3D;AACA;AACA;AACA;AACA,6CAA6C,0BAA0B;AACvE;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA,kBAAkB,sBAAsB,SAAS,yBAAyB,IAAI,kCAAkC;AAChH;AACA;AACA,gBAAgB,iBAAiB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,iBAAiB,IAAI,kCAAkC;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sCAAsC,GAAG,8CAA8C;AACnH;AACA;AACA,6BAA6B,uCAAuC,GAAG,+CAA+C;AACtH;AACA;AACA,4BAA4B,sCAAsC,GAAG,8CAA8C;AACnH;AACA;AACA;AACA;AACO,2BAA2B,0CAA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mB,WAAW,6BAA6B;AACvE;AACA;AACA,YAAY,gDAAmB,WAAW,kCAAkC;AAC5E,YAAY,gDAAmB,WAAW,6BAA6B;AACvE;AACA;AACA,YAAY,gDAAmB,WAAW,kCAAkC;AAC5E,YAAY,gDAAmB,WAAW,6BAA6B;AACvE;AACA;AACA;;;;;;;;;;;;;;;;;;;;;;;ACpB+B;AACe;AACR;AACc;AACE;AACd;AACM;AACvC,+BAA+B,aAAa;AACnD,sCAAsC,2CAAc;AACpD,sCAAsC,2CAAc;AACpD,0CAA0C,2CAAc;AACxD,4BAA4B,2CAAc;AAC1C,sCAAsC,2CAAc;AACpD,kCAAkC,2CAAc;AAChD,0CAA0C,2CAAc;AACxD,sCAAsC,2CAAc;AACpD,8CAA8C,2CAAc;AAC5D,0CAA0C,2CAAc;AACxD,kCAAkC,2CAAc;AAChD,8CAA8C,2CAAc;AAC5D;AACA,sCAAsC,2CAAc;AACpD,wCAAwC,2CAAc;AACtD,8BAA8B,8CAAiB;AAC/C,yBAAyB,8CAAiB;AAC1C;AACA,KAAK;AACL;AACA,+BAA+B,8CAAiB;AAChD,0BAA0B,8CAAiB;AAC3C;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,IAAI,4CAAe;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,IAAI,4CAAe;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,6BAA6B,8CAAiB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL,uBAAuB,8CAAiB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL,0BAA0B,8CAAiB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL,2BAA2B,8CAAiB;AAC5C,2BAA2B,0BAA0B;AACrD,KAAK;AACL,uBAAuB,8CAAiB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL,2BAA2B,8CAAiB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL,sBAAsB,8CAAiB;AACvC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,YAAY,gDAAmB,UAAU,gCAAgC;AACzE,0BAA0B,gDAAmB,CAAC,+DAAgB,IAAI,8FAA8F;AAChK,QAAQ,gDAAmB,UAAU,8BAA8B;AACnE,YAAY,gDAAmB,UAAU,SAAS,kDAAkD;AACpG,gBAAgB,gDAAmB,CAAC,uDAAY,IAAI,4EAA4E;AAChI,YAAY,gDAAmB,CAAC,uDAAY,IAAI,mFAAmF;AACnI,YAAY,gDAAmB,UAAU,gCAAgC;AACzE,gBAAgB,gDAAmB,UAAU,8BAA8B;AAC3E,oBAAoB,gDAAmB,WAAW,+BAA+B;AACjF;AACA,4CAA4C,gDAAmB,WAAW,SAAS,uEAAuE;AAC1J;AACA;AACA;AACA;AACA,oCAAoC,gDAAmB,CAAC,2CAAc;AACtE,wBAAwB,gDAAmB,aAAa,2CAA2C;AACnG,wBAAwB,gDAAmB,aAAa,+EAA+E;AACvI;AACA;AACA,qDAAqD,gDAAmB,CAAC,+CAAQ,IAAI,kQAAkQ,MAAM,gDAAmB,UAAU,6BAA6B,aAAa,gDAAmB,UAAU,yBAAyB;AAC1d,oBAAoB,gDAAmB,UAAU,yBAAyB,oBAAoB,gDAAmB,CAAC,2CAAc;AAChI,oBAAoB,gDAAmB,UAAU,4BAA4B;AAC7E,oBAAoB,gDAAmB;AACvC,oBAAoB,gDAAmB,UAAU,SAAS,gDAAgD,oDAAoD,gDAAmB,CAAC,2CAAc;AAChM,oBAAoB,gDAAmB,UAAU,4BAA4B;AAC7E,oBAAoB,gDAAmB;AACvC;AACA;AACA,qEAAqE,gDAAmB,CAAC,2CAAc;AACvG,gBAAgB,gDAAmB,CAAC,uDAAY,IAAI,mGAAmG;AACvJ,gBAAgB,gDAAmB,UAAU,SAAS,mDAAmD;AACzG,oBAAoB,gDAAmB,CAAC,6DAAe,IAAI,oJAAoJ;AAC/M,QAAQ,gDAAmB,CAAC,iDAAS,IAAI,uHAAuH;AAChK;;;;;;;;;;;;;;;;;ACrM+B;AAC/B;AACA;AACA,kBAAkB,OAAO;AACzB;AACA,kBAAkB,2BAA2B;AAC7C;AACA,kBAAkB,oCAAoC;AACtD,cAAc,2CAA2C;AACzD;AACA;AACA;AACA;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,wBAAwB,kCAAkC;AACjE,gCAAgC,2CAAc;AAC9C,qBAAqB,0CAAa;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL,mBAAmB,0CAAa;AAChC;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL,YAAY,gDAAmB,UAAU,+BAA+B;AACxE,QAAQ,gDAAmB,UAAU,sCAAsC;AAC3E,YAAY,gDAAmB,YAAY,0IAA0I;AACrL,QAAQ,gDAAmB,UAAU,gCAAgC,yBAAyB,gDAAmB,UAAU,SAAS,4EAA4E;AAChN;AACA,oBAAoB,gDAAmB,UAAU,4CAA4C,4CAA4C,4DAA4D,6EAA6E,wCAAwC,OAAO,OAAO,QAAQ,GAAG,WAAW,IAAI;AAClW,gBAAgB,gDAAmB,UAAU,SAAS,mEAAmE;AACzH,oBAAoB,gDAAmB,WAAW,0BAA0B;AAC5E,oBAAoB,gDAAmB,WAAW,4BAA4B,8BAA8B,GAAG;AAC/G,kCAAkC,gDAAmB,WAAW,4BAA4B;AAC5F,gBAAgB,gDAAmB,UAAU,0BAA0B;AACvE,oBAAoB,gDAAmB;AACvC,oBAAoB,gDAAmB;AACvC,SAAS;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzEwD;AACF;AACC;AACK;AACX;AACsB;AACX;AAC7B;AACO;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,0DAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,MAAM,UAAU,OAAO,QAAQ,KAAK,OAAO,IAAI;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW,YAAY,aAAa,cAAc;AACnE,eAAe,aAAa;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yEAAgB;AACxB;AACA;AACA;AACA,wBAAwB,kCAAkC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,6CAAe,CAAC,gDAAmB,CAAC,gFAAmB;AAC/D;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,6DAA+B;AAC/C;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,kEAAgB;AAC/B,eAAe,iEAAe,EAAE,gEAAe;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAkB,sEAAe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,iEAAe,MAAM,EAAC;;;;;;;;;;;;;;;;AC7KtB;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,qCAAqC,sBAAsB;AAC3D;AACA,6BAA6B;AAC7B,gCAAgC,sBAAsB;AACtD;AACO;AACP;AACA,yCAAyC;AACzC;AACA;AACA,0CAA0C;AAC1C;AACA,uCAAuC;AACvC;;;;;;;;;;;;;;;ACxBA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,gCAAgC;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;;;ACvFA;AACO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,oBAAoB,+BAA+B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,2BAA2B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sBAAsB;AAC1C;AACA;AACA;AACA;AACA;AACA","sources":["webpack://variable-explorer/./lib/comm/CommManager.js","webpack://variable-explorer/./lib/components/CellReferenceBar.js","webpack://variable-explorer/./lib/components/DataGrid.js","webpack://variable-explorer/./lib/components/HistogramHeader.js","webpack://variable-explorer/./lib/components/MetadataSidebar.js","webpack://variable-explorer/./lib/components/ResizeHandle.js","webpack://variable-explorer/./lib/components/StatusBar.js","webpack://variable-explorer/./lib/components/VariableExplorerApp.js","webpack://variable-explorer/./lib/components/VariableList.js","webpack://variable-explorer/./lib/index.js","webpack://variable-explorer/./lib/utils/colorScales.js","webpack://variable-explorer/./lib/utils/histogramRenderer.js","webpack://variable-explorer/./lib/utils/stylesheetCloner.js"],"sourcesContent":["import { Signal } from '@lumino/signaling';\nconst COMM_TARGET = 'variable_explorer';\nconst INIT_CODE = `\ntry:\n from variable_explorer.kernel import init_comm as _ve_init\n _ve_init()\n del _ve_init\nexcept ImportError as e:\n print(f\"Variable Explorer: kernel package not found: {e}\")\nexcept Exception as e:\n print(f\"Variable Explorer: init error: {e}\")\n`.trim();\nexport class CommManager {\n constructor() {\n this._comm = null;\n this._kernel = null;\n this._messageReceived = new Signal(this);\n this._connectionChanged = new Signal(this);\n this._isConnected = false;\n }\n get messageReceived() {\n return this._messageReceived;\n }\n get connectionChanged() {\n return this._connectionChanged;\n }\n get isConnected() {\n return this._isConnected;\n }\n async connect(kernel) {\n // Disconnect existing\n this.disconnect();\n this._kernel = kernel;\n // Inject the Python init code\n const future = kernel.requestExecute({\n code: INIT_CODE,\n silent: true,\n store_history: false\n });\n await future.done;\n // Open a comm from the frontend\n this._comm = kernel.createComm(COMM_TARGET);\n // Handle incoming messages\n this._comm.onMsg = (msg) => {\n const data = msg.content.data;\n if (data && data.type) {\n this._messageReceived.emit(data);\n }\n };\n this._comm.onClose = () => {\n this._setConnected(false);\n };\n // Open the comm channel\n await this._comm.open({}).done;\n this._setConnected(true);\n // Listen for kernel shutdown/restart\n kernel.statusChanged.connect(this._onKernelStatus, this);\n }\n send(msg) {\n if (this._comm && this._isConnected) {\n this._comm.send(msg);\n }\n }\n refresh() {\n this.send({ type: 'refresh' });\n }\n disconnect() {\n if (this._kernel) {\n this._kernel.statusChanged.disconnect(this._onKernelStatus, this);\n }\n if (this._comm) {\n try {\n this._comm.close({});\n }\n catch (_a) {\n // Comm may already be closed\n }\n this._comm = null;\n }\n this._kernel = null;\n this._setConnected(false);\n }\n _setConnected(connected) {\n if (this._isConnected !== connected) {\n this._isConnected = connected;\n this._connectionChanged.emit(connected);\n }\n }\n _onKernelStatus(kernel, status) {\n if (status === 'restarting' || status === 'dead') {\n this._setConnected(false);\n this._comm = null;\n }\n if (status === 'idle' && !this._isConnected && this._kernel) {\n // Kernel restarted — try to reconnect\n this.connect(this._kernel).catch(e => {\n console.error('Variable Explorer: reconnect failed', e);\n });\n }\n }\n}\n","import * as React from 'react';\nexport const CellReferenceBar = ({ rowIndex, colName, value }) => {\n const displayValue = value == null ? 'null' : String(value);\n return (React.createElement(\"div\", { className: \"ve-cell-reference-bar\" },\n React.createElement(\"span\", { className: \"ve-cell-location\" },\n \"Row \",\n rowIndex.toLocaleString(),\n \" / Col: \",\n colName),\n React.createElement(\"span\", { className: \"ve-cell-value\", title: displayValue }, displayValue)));\n};\n","import * as React from 'react';\nimport { AgGridReact } from 'ag-grid-react';\nimport { HistogramHeader } from './HistogramHeader';\nimport { numericHeatmap, booleanColor } from '../utils/colorScales';\nexport const DataGrid = ({ rows, columns, columnStats, totalRows, sortModel, hiddenColumns, loading, onSortChanged, onLoadMore, onCellSelected, onCellEdit }) => {\n const gridRef = React.useRef(null);\n // Build a stats lookup map\n const statsMap = React.useMemo(() => {\n const map = {};\n for (const s of columnStats) {\n map[s.name] = s;\n }\n return map;\n }, [columnStats]);\n // Build AG Grid column definitions\n const colDefs = React.useMemo(() => {\n // Row index column\n const indexCol = {\n headerName: '#',\n colId: '__index__',\n valueGetter: (params) => {\n var _a;\n return ((_a = params.node) === null || _a === void 0 ? void 0 : _a.rowIndex) != null ? params.node.rowIndex : '';\n },\n width: 70,\n pinned: 'left',\n sortable: true,\n resizable: false,\n cellStyle: {\n color: 'var(--jp-ui-font-color2)',\n fontWeight: '500',\n fontSize: '11px'\n }\n };\n const dataCols = columns\n .filter(c => !hiddenColumns.has(c.name))\n .map(col => {\n const stats = statsMap[col.name];\n const def = {\n headerName: col.name,\n field: col.name,\n sortable: true,\n resizable: true,\n editable: true,\n minWidth: 80,\n headerComponent: HistogramHeader,\n headerComponentParams: {\n displayName: col.name,\n stats: stats\n }\n };\n // Conditional formatting\n if (col.isNumeric && (stats === null || stats === void 0 ? void 0 : stats.histogram) && stats.histogram.type === 'numeric') {\n const h = stats.histogram;\n def.cellStyle = (params) => {\n if (params.value == null) {\n return { backgroundColor: 'var(--jp-layout-color2)', opacity: 0.5 };\n }\n return {\n backgroundColor: numericHeatmap(params.value, h.min, h.max),\n color: 'var(--jp-ui-font-color0)'\n };\n };\n }\n else if (col.isBool) {\n def.cellStyle = (params) => {\n if (params.value == null) {\n return { backgroundColor: 'var(--jp-layout-color2)', opacity: 0.5 };\n }\n return {\n backgroundColor: booleanColor(params.value),\n color: '#fff',\n fontWeight: '600',\n textAlign: 'center'\n };\n };\n }\n // Format numbers\n if (col.isNumeric) {\n def.valueFormatter = (params) => {\n if (params.value == null)\n return '';\n const val = Number(params.value);\n if (Number.isInteger(val))\n return val.toLocaleString();\n return val.toLocaleString(undefined, { maximumFractionDigits: 4 });\n };\n }\n // Format dates\n if (col.isDatetime) {\n def.valueFormatter = (params) => {\n if (params.value == null)\n return '';\n return new Date(params.value).toLocaleString();\n };\n }\n return def;\n });\n return [indexCol, ...dataCols];\n }, [columns, statsMap, hiddenColumns]);\n // Handle sort\n const handleSortChanged = React.useCallback((event) => {\n const colState = event.api.getColumnState();\n const sorted = colState.filter((c) => c.sort);\n // If the index column (#) is being sorted, clear all sorts → reset to original order\n if (sorted.some((c) => c.colId === '__index__')) {\n event.api.applyColumnState({ defaultState: { sort: null } });\n onSortChanged([]);\n return;\n }\n const newSortModel = sorted\n .sort((a, b) => (a.sortIndex || 0) - (b.sortIndex || 0))\n .map((c) => ({\n colId: c.colId,\n sort: c.sort\n }));\n onSortChanged(newSortModel);\n }, [onSortChanged]);\n // Handle cell click\n const handleCellClicked = React.useCallback((event) => {\n if (event.colDef.field && event.rowIndex != null) {\n onCellSelected(event.rowIndex, event.colDef.field, event.value);\n }\n }, [onCellSelected]);\n // Handle cell edit\n const handleCellEditRequest = React.useCallback((event) => {\n if (event.colDef.field && event.rowIndex != null) {\n onCellEdit(event.rowIndex, event.colDef.field, String(event.newValue));\n // Optimistic update\n const rowNode = event.api.getRowNode(String(event.rowIndex));\n if (rowNode) {\n rowNode.setDataValue(event.colDef.field, event.newValue);\n }\n }\n }, [onCellEdit]);\n // Infinite scroll: load more rows when scrolled near bottom\n const handleBodyScrollEnd = React.useCallback((event) => {\n if (loading)\n return;\n const lastRow = event.api.getLastDisplayedRow();\n if (lastRow >= rows.length - 200 && rows.length < totalRows) {\n onLoadMore(rows.length);\n }\n }, [loading, rows.length, totalRows, onLoadMore]);\n // Detect JupyterLab dark theme\n const isDark = document.body.getAttribute('data-jp-theme-light') === 'false';\n const themeClass = isDark ? 'ag-theme-quartz-dark' : 'ag-theme-quartz';\n return (React.createElement(\"div\", { className: \"ve-grid-wrapper\" },\n React.createElement(\"div\", { className: themeClass, style: { width: '100%', height: '100%' } },\n React.createElement(AgGridReact, { ref: gridRef, rowData: rows, columnDefs: colDefs, defaultColDef: {\n sortable: true,\n resizable: true,\n minWidth: 60\n }, headerHeight: 64, rowHeight: 28, animateRows: false, suppressMovableColumns: false, readOnlyEdit: true, onSortChanged: handleSortChanged, onCellClicked: handleCellClicked, onCellEditRequest: handleCellEditRequest, onBodyScrollEnd: handleBodyScrollEnd, getRowId: (params) => { var _a, _b, _c; return String((_c = (_a = params.data.__row_index__) !== null && _a !== void 0 ? _a : (_b = params.node) === null || _b === void 0 ? void 0 : _b.rowIndex) !== null && _c !== void 0 ? _c : 0); }, loading: loading }))));\n};\n","import * as React from 'react';\nimport { drawHistogram } from '../utils/histogramRenderer';\nfunction getTooltipText(histogram, mouseX, mouseY, canvasWidth, canvasHeight) {\n const fmt = (v) => {\n if (Number.isInteger(v) && Math.abs(v) < 1e6)\n return v.toLocaleString();\n return v.toLocaleString(undefined, { maximumFractionDigits: 2 });\n };\n if (histogram.type === 'numeric') {\n const { counts, edges } = histogram;\n const binIndex = Math.floor((mouseX / canvasWidth) * counts.length);\n if (binIndex < 0 || binIndex >= counts.length)\n return null;\n return `${fmt(edges[binIndex])} \\u2013 ${fmt(edges[binIndex + 1])}: ${counts[binIndex].toLocaleString()}`;\n }\n if (histogram.type === 'categorical') {\n const { labels, counts } = histogram;\n const barCount = Math.min(labels.length, 8);\n // Bars are drawn horizontally, stacked vertically\n const barHeight = canvasHeight / barCount;\n const barIndex = Math.floor(mouseY / barHeight);\n if (barIndex < 0 || barIndex >= barCount)\n return null;\n return `${labels[barIndex]}: ${counts[barIndex].toLocaleString()}`;\n }\n if (histogram.type === 'boolean') {\n const total = histogram.trueCount + histogram.falseCount + histogram.nullCount;\n if (total === 0)\n return null;\n const trueWidth = (histogram.trueCount / total) * canvasWidth;\n const falseWidth = (histogram.falseCount / total) * canvasWidth;\n if (mouseX < trueWidth) {\n return `True: ${histogram.trueCount.toLocaleString()} (${Math.round(100 * histogram.trueCount / total)}%)`;\n }\n else if (mouseX < trueWidth + falseWidth) {\n return `False: ${histogram.falseCount.toLocaleString()} (${Math.round(100 * histogram.falseCount / total)}%)`;\n }\n else {\n return `Null: ${histogram.nullCount.toLocaleString()} (${Math.round(100 * histogram.nullCount / total)}%)`;\n }\n }\n return null;\n}\nexport const HistogramHeader = ({ displayName, stats, column, setSort, api }) => {\n const canvasRef = React.useRef(null);\n const tooltipRef = React.useRef(null);\n const [sortState, setSortState] = React.useState(null);\n const [tooltip, setTooltip] = React.useState(null);\n // Draw histogram when stats change\n React.useEffect(() => {\n const canvas = canvasRef.current;\n if (!canvas || !(stats === null || stats === void 0 ? void 0 : stats.histogram))\n return;\n drawHistogram(canvas, stats.histogram);\n }, [stats]);\n // Track sort state\n React.useEffect(() => {\n var _a;\n if (!column || !api)\n return;\n const onSortChanged = () => {\n var _a;\n const colState = (_a = api.getColumnState) === null || _a === void 0 ? void 0 : _a.call(api);\n if (colState) {\n const myState = colState.find((s) => s.colId === column.getColId());\n setSortState((myState === null || myState === void 0 ? void 0 : myState.sort) || null);\n }\n };\n (_a = api.addEventListener) === null || _a === void 0 ? void 0 : _a.call(api, 'sortChanged', onSortChanged);\n return () => {\n var _a;\n (_a = api.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(api, 'sortChanged', onSortChanged);\n };\n }, [column, api]);\n const handleClick = (e) => {\n if (!setSort)\n return;\n let nextSort;\n if (sortState === null) {\n nextSort = 'asc';\n }\n else if (sortState === 'asc') {\n nextSort = 'desc';\n }\n else {\n nextSort = '';\n }\n setSort(nextSort, e.shiftKey);\n };\n const handleCanvasMouseMove = React.useCallback((e) => {\n if (!(stats === null || stats === void 0 ? void 0 : stats.histogram) || !canvasRef.current)\n return;\n const rect = canvasRef.current.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const text = getTooltipText(stats.histogram, mouseX, mouseY, rect.width, rect.height);\n if (text) {\n setTooltip({ text, x: e.clientX, y: rect.top - 4 });\n }\n else {\n setTooltip(null);\n }\n }, [stats]);\n const handleCanvasMouseLeave = React.useCallback(() => {\n setTooltip(null);\n }, []);\n const sortIcon = sortState === 'asc' ? ' \\u25b2' : sortState === 'desc' ? ' \\u25bc' : '';\n return (React.createElement(\"div\", { className: \"ve-histogram-header\", style: { width: '100%' } },\n React.createElement(\"div\", { className: \"ve-header-label\", onClick: handleClick, title: `Click to sort by ${displayName}` },\n React.createElement(\"span\", { style: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, displayName),\n sortIcon && React.createElement(\"span\", { className: \"ve-sort-icon\" }, sortIcon)),\n (stats === null || stats === void 0 ? void 0 : stats.histogram) && (React.createElement(\"div\", { style: { position: 'relative', width: '100%' } },\n React.createElement(\"canvas\", { ref: canvasRef, width: 120, height: 30, style: { width: '100%', height: '30px', cursor: 'crosshair' }, onMouseMove: handleCanvasMouseMove, onMouseLeave: handleCanvasMouseLeave }),\n tooltip && (React.createElement(\"div\", { ref: tooltipRef, className: \"ve-histogram-tooltip\", style: { left: tooltip.x, top: tooltip.y, transform: 'translate(-50%, -100%)' } }, tooltip.text.split('\\n').map((line, i) => (React.createElement(\"div\", { key: i }, line)))))))));\n};\n","import * as React from 'react';\nfunction formatBytes(bytes) {\n if (bytes < 1024)\n return `${bytes} B`;\n if (bytes < 1024 * 1024)\n return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\nexport const MetadataSidebar = ({ columns, columnStats, hiddenColumns, onToggleColumn, selectedVarInfo }) => {\n var _a, _b, _c, _d;\n const [filter, setFilter] = React.useState('');\n const [selectedCol, setSelectedCol] = React.useState(null);\n const [propertiesHeight, setPropertiesHeight] = React.useState(220);\n const handleRef = React.useRef(null);\n const statsMap = React.useMemo(() => {\n const map = {};\n for (const s of columnStats) {\n map[s.name] = s;\n }\n return map;\n }, [columnStats]);\n const filtered = React.useMemo(() => {\n if (!filter)\n return columns;\n const lower = filter.toLowerCase();\n return columns.filter(c => c.name.toLowerCase().includes(lower));\n }, [columns, filter]);\n const selectedStats = selectedCol ? statsMap[selectedCol] : null;\n const selectedColDef = selectedCol ? columns.find(c => c.name === selectedCol) : null;\n // Horizontal resize for properties panel\n const onHandleMouseDown = React.useCallback((e) => {\n var _a;\n e.preventDefault();\n e.stopPropagation();\n const startY = e.clientY;\n const baseHeight = propertiesHeight;\n const doc = ((_a = handleRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || document;\n const onMouseMove = (moveEvent) => {\n moveEvent.preventDefault();\n const delta = startY - moveEvent.clientY; // dragging up = increase height\n setPropertiesHeight(Math.max(80, Math.min(500, baseHeight + delta)));\n };\n const onMouseUp = () => {\n doc.removeEventListener('mousemove', onMouseMove);\n doc.removeEventListener('mouseup', onMouseUp);\n doc.body.style.cursor = '';\n doc.body.style.userSelect = '';\n };\n doc.addEventListener('mousemove', onMouseMove);\n doc.addEventListener('mouseup', onMouseUp);\n doc.body.style.cursor = 'row-resize';\n doc.body.style.userSelect = 'none';\n }, [propertiesHeight]);\n return (React.createElement(\"div\", { className: \"ve-metadata-sidebar\" },\n React.createElement(\"div\", { className: \"ve-metadata-header\" },\n React.createElement(\"span\", null, \"Columns\"),\n React.createElement(\"span\", { style: { fontSize: '11px', fontWeight: 'normal', opacity: 0.6 } }, columns.length)),\n React.createElement(\"input\", { className: \"ve-metadata-search\", type: \"text\", placeholder: \"Filter columns...\", value: filter, onChange: e => setFilter(e.target.value) }),\n React.createElement(\"div\", { className: \"ve-metadata-columns\" }, filtered.map(col => {\n return (React.createElement(\"div\", { key: col.name, className: \"ve-metadata-column-item\", onClick: () => setSelectedCol(col.name), style: {\n cursor: 'pointer',\n background: col.name === selectedCol ? 'var(--jp-layout-color2)' : undefined\n } },\n React.createElement(\"input\", { type: \"checkbox\", checked: !hiddenColumns.has(col.name), onChange: () => onToggleColumn(col.name), onClick: e => e.stopPropagation() }),\n React.createElement(\"span\", { className: \"ve-col-name\", title: col.name }, col.name),\n React.createElement(\"span\", { className: \"ve-col-type\" }, col.dtype)));\n })),\n React.createElement(\"div\", { ref: handleRef, className: \"ve-resize-handle-horizontal\", onMouseDown: onHandleMouseDown }),\n React.createElement(\"div\", { className: \"ve-properties-panel\", style: { height: propertiesHeight, minHeight: 80 } }, selectedStats && selectedColDef ? (React.createElement(React.Fragment, null,\n React.createElement(\"h4\", null,\n \"Column: \",\n selectedCol),\n React.createElement(\"table\", { className: \"ve-properties-table\" },\n React.createElement(\"tbody\", null,\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Name\"),\n React.createElement(\"td\", null, selectedColDef.name)),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Type\"),\n React.createElement(\"td\", null, selectedColDef.dtype)),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Nulls\"),\n React.createElement(\"td\", null, selectedStats.nullCount.toLocaleString())),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Unique\"),\n React.createElement(\"td\", null, selectedStats.uniqueCount.toLocaleString())),\n ((_a = selectedStats.histogram) === null || _a === void 0 ? void 0 : _a.type) === 'numeric' && (React.createElement(React.Fragment, null,\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Min\"),\n React.createElement(\"td\", null, selectedStats.histogram.min.toLocaleString(undefined, { maximumFractionDigits: 4 }))),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Max\"),\n React.createElement(\"td\", null, selectedStats.histogram.max.toLocaleString(undefined, { maximumFractionDigits: 4 }))),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Mean\"),\n React.createElement(\"td\", null, selectedStats.histogram.mean.toLocaleString(undefined, { maximumFractionDigits: 4 }))),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Std\"),\n React.createElement(\"td\", null, selectedStats.histogram.std.toLocaleString(undefined, { maximumFractionDigits: 4 }))))),\n ((_b = selectedStats.histogram) === null || _b === void 0 ? void 0 : _b.type) === 'boolean' && (React.createElement(React.Fragment, null,\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"True\"),\n React.createElement(\"td\", null, selectedStats.histogram.trueCount.toLocaleString())),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"False\"),\n React.createElement(\"td\", null, selectedStats.histogram.falseCount.toLocaleString())))),\n ((_c = selectedStats.histogram) === null || _c === void 0 ? void 0 : _c.type) === 'categorical' && (React.createElement(React.Fragment, null,\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Top values\"),\n React.createElement(\"td\", null, selectedStats.histogram.labels.slice(0, 5).map((label, i) => {\n var _a;\n return (React.createElement(\"div\", { key: i, style: { fontSize: '11px' } },\n label,\n \": \",\n selectedStats.histogram.type === 'categorical'\n ? (_a = selectedStats.histogram.counts[i]) === null || _a === void 0 ? void 0 : _a.toLocaleString()\n : ''));\n }))))))))) : selectedVarInfo ? (React.createElement(React.Fragment, null,\n React.createElement(\"h4\", null, \"Dataset\"),\n React.createElement(\"table\", { className: \"ve-properties-table\" },\n React.createElement(\"tbody\", null,\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Name\"),\n React.createElement(\"td\", null, selectedVarInfo.name)),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Type\"),\n React.createElement(\"td\", null, selectedVarInfo.typeName)),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Shape\"),\n React.createElement(\"td\", null, selectedVarInfo.shape.map(s => s.toLocaleString()).join(' \\u00d7 '))),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Memory\"),\n React.createElement(\"td\", null, formatBytes(selectedVarInfo.memoryBytes))),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Variables\"),\n React.createElement(\"td\", null, columns.length)),\n React.createElement(\"tr\", null,\n React.createElement(\"td\", null, \"Observations\"),\n React.createElement(\"td\", null, (_d = selectedVarInfo.shape[0]) === null || _d === void 0 ? void 0 : _d.toLocaleString())))))) : (React.createElement(\"div\", { style: { fontSize: '12px', opacity: 0.5, textAlign: 'center', paddingTop: 12 } }, \"Click a column for details\")))));\n};\n","import * as React from 'react';\nexport const ResizeHandle = ({ onResizeStart, onResize, direction, invert }) => {\n const handleRef = React.useRef(null);\n const onMouseDown = React.useCallback((e) => {\n var _a;\n e.preventDefault();\n e.stopPropagation();\n const startX = e.clientX;\n const baseWidth = onResizeStart();\n // Use the ownerDocument so this works in detached popup windows\n const doc = ((_a = handleRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || document;\n const onMouseMove = (moveEvent) => {\n moveEvent.preventDefault();\n const delta = moveEvent.clientX - startX;\n const newWidth = invert ? baseWidth - delta : baseWidth + delta;\n onResize(newWidth);\n };\n const onMouseUp = () => {\n doc.removeEventListener('mousemove', onMouseMove);\n doc.removeEventListener('mouseup', onMouseUp);\n doc.body.style.cursor = '';\n doc.body.style.userSelect = '';\n };\n doc.addEventListener('mousemove', onMouseMove);\n doc.addEventListener('mouseup', onMouseUp);\n doc.body.style.cursor = 'col-resize';\n doc.body.style.userSelect = 'none';\n }, [onResizeStart, onResize, invert]);\n return (React.createElement(\"div\", { ref: handleRef, className: \"ve-resize-handle\", onMouseDown: onMouseDown }));\n};\n","import * as React from 'react';\nexport const StatusBar = ({ selectedVar, totalRows, totalCols, sortModel, connected }) => {\n const sortDisplay = sortModel.length > 0\n ? sortModel.map(s => `${s.colId} ${s.sort}`).join(', ')\n : 'none';\n return (React.createElement(\"div\", { className: \"ve-status-bar\" },\n React.createElement(\"span\", { className: \"ve-status-item\", style: { color: connected ? 'var(--jp-success-color1)' : 'var(--jp-error-color1)' } }, connected ? '\\u25cf Connected' : '\\u25cb Disconnected'),\n selectedVar && (React.createElement(React.Fragment, null,\n React.createElement(\"span\", { className: \"ve-status-separator\" }, \"|\"),\n React.createElement(\"span\", { className: \"ve-status-item\" },\n \"Vars: \",\n totalCols),\n React.createElement(\"span\", { className: \"ve-status-separator\" }, \"|\"),\n React.createElement(\"span\", { className: \"ve-status-item\" },\n \"Obs: \",\n totalRows.toLocaleString()),\n React.createElement(\"span\", { className: \"ve-status-separator\" }, \"|\"),\n React.createElement(\"span\", { className: \"ve-status-item\" },\n \"Sorted: \",\n sortDisplay)))));\n};\n","import * as React from 'react';\nimport { VariableList } from './VariableList';\nimport { DataGrid } from './DataGrid';\nimport { MetadataSidebar } from './MetadataSidebar';\nimport { CellReferenceBar } from './CellReferenceBar';\nimport { StatusBar } from './StatusBar';\nimport { ResizeHandle } from './ResizeHandle';\nexport const VariableExplorerApp = ({ commManager }) => {\n const [connected, setConnected] = React.useState(commManager.isConnected);\n const [variables, setVariables] = React.useState([]);\n const [selectedVar, setSelectedVar] = React.useState(null);\n const [rows, setRows] = React.useState([]);\n const [totalRows, setTotalRows] = React.useState(0);\n const [columns, setColumns] = React.useState([]);\n const [columnStats, setColumnStats] = React.useState([]);\n const [sortModel, setSortModel] = React.useState([]);\n const [cellSelection, setCellSelection] = React.useState(null);\n const [showSidebar, setShowSidebar] = React.useState(true);\n const [loading, setLoading] = React.useState(false);\n const [hiddenColumns, setHiddenColumns] = React.useState(new Set());\n // Panel sizing\n const [leftWidth, setLeftWidth] = React.useState(220);\n const [rightWidth, setRightWidth] = React.useState(280);\n const onLeftResizeStart = React.useCallback(() => leftWidth, [leftWidth]);\n const onLeftResize = React.useCallback((newWidth) => {\n setLeftWidth(Math.max(120, Math.min(500, newWidth)));\n }, []);\n // For the right panel, dragging right = panel shrinks, so invert\n const onRightResizeStart = React.useCallback(() => rightWidth, [rightWidth]);\n const onRightResize = React.useCallback((newWidth) => {\n // ResizeHandle sends base + delta. For the right side,\n // we want: base - delta = base - (newWidth - base) = 2*base - newWidth\n // But we don't have base here. Instead, let's just negate in the component.\n setRightWidth(Math.max(150, Math.min(500, newWidth)));\n }, []);\n // Listen for connection changes\n React.useEffect(() => {\n const onConnectionChanged = (_, isConnected) => {\n setConnected(isConnected);\n if (!isConnected) {\n setVariables([]);\n setSelectedVar(null);\n setRows([]);\n }\n };\n commManager.connectionChanged.connect(onConnectionChanged);\n return () => {\n commManager.connectionChanged.disconnect(onConnectionChanged);\n };\n }, [commManager]);\n // Listen for kernel messages\n React.useEffect(() => {\n const onMessage = (_, msg) => {\n switch (msg.type) {\n case 'variable_list':\n setVariables(msg.variables);\n break;\n case 'data_page': {\n const dp = msg;\n if (dp.startRow === 0) {\n setRows(dp.rows);\n }\n else {\n setRows(prev => [...prev, ...dp.rows]);\n }\n setTotalRows(dp.totalRows);\n setColumns(dp.columns);\n setLoading(false);\n break;\n }\n case 'column_stats': {\n const cs = msg;\n setColumnStats(cs.stats);\n break;\n }\n case 'error':\n console.error('Variable Explorer kernel error:', msg.message);\n setLoading(false);\n break;\n }\n };\n commManager.messageReceived.connect(onMessage);\n return () => {\n commManager.messageReceived.disconnect(onMessage);\n };\n }, [commManager]);\n const onSelectVariable = React.useCallback((name, childKey) => {\n setSelectedVar(name);\n setRows([]);\n setSortModel([]);\n setCellSelection(null);\n setHiddenColumns(new Set());\n setLoading(true);\n commManager.send({\n type: 'get_data',\n variable: name,\n startRow: 0,\n endRow: 1000,\n childKey\n });\n commManager.send({\n type: 'get_stats',\n variable: name\n });\n }, [commManager]);\n const onLoadMore = React.useCallback((startRow) => {\n if (selectedVar) {\n commManager.send({\n type: 'get_data',\n variable: selectedVar,\n startRow,\n endRow: startRow + 1000,\n sortModel: sortModel.length > 0 ? sortModel : undefined\n });\n }\n }, [commManager, selectedVar, sortModel]);\n const onSortChanged = React.useCallback((newSortModel) => {\n setSortModel(newSortModel);\n setRows([]);\n setLoading(true);\n if (selectedVar) {\n commManager.send({\n type: 'get_data',\n variable: selectedVar,\n startRow: 0,\n endRow: 1000,\n sortModel: newSortModel.length > 0 ? newSortModel : undefined\n });\n }\n }, [commManager, selectedVar]);\n const onCellSelected = React.useCallback((rowIndex, colName, value) => {\n setCellSelection({ rowIndex, colName, value });\n }, []);\n const onCellEdit = React.useCallback((rowIndex, column, newValue) => {\n if (selectedVar) {\n commManager.send({\n type: 'edit_cell',\n variable: selectedVar,\n rowIndex,\n column,\n newValue\n });\n }\n }, [commManager, selectedVar]);\n const onToggleColumn = React.useCallback((colName) => {\n setHiddenColumns(prev => {\n const next = new Set(prev);\n if (next.has(colName)) {\n next.delete(colName);\n }\n else {\n next.add(colName);\n }\n return next;\n });\n }, []);\n const onRefresh = React.useCallback(() => {\n commManager.refresh();\n if (selectedVar) {\n onSelectVariable(selectedVar);\n }\n }, [commManager, selectedVar, onSelectVariable]);\n const selectedVarInfo = variables.find(v => v.name === selectedVar);\n return (React.createElement(\"div\", { className: \"ve-main-container\" },\n cellSelection && (React.createElement(CellReferenceBar, { rowIndex: cellSelection.rowIndex, colName: cellSelection.colName, value: cellSelection.value })),\n React.createElement(\"div\", { className: \"ve-content-area\" },\n React.createElement(\"div\", { style: { width: leftWidth, minWidth: 120, flexShrink: 0 } },\n React.createElement(VariableList, { variables: variables, selectedVar: selectedVar, onSelect: onSelectVariable })),\n React.createElement(ResizeHandle, { direction: \"horizontal\", onResizeStart: onLeftResizeStart, onResize: onLeftResize }),\n React.createElement(\"div\", { className: \"ve-grid-container\" },\n React.createElement(\"div\", { className: \"ve-grid-toolbar\" },\n React.createElement(\"span\", { className: \"ve-toolbar-title\" },\n selectedVar || 'Select a variable',\n selectedVarInfo && (React.createElement(\"span\", { style: { fontWeight: 'normal', opacity: 0.6, marginLeft: 8, fontSize: '12px' } },\n selectedVarInfo.typeName,\n \" (\",\n selectedVarInfo.shape.map(s => s.toLocaleString()).join(' \\u00d7 '),\n \")\"))),\n selectedVar && (React.createElement(React.Fragment, null,\n React.createElement(\"button\", { onClick: onRefresh, title: \"Refresh data\" }, \"\\u21BB Refresh\"),\n React.createElement(\"button\", { onClick: () => setShowSidebar(!showSidebar), title: \"Toggle metadata sidebar\" },\n showSidebar ? 'Hide' : 'Show',\n \" Metadata\")))),\n selectedVar && columns.length > 0 ? (React.createElement(DataGrid, { rows: rows, columns: columns, columnStats: columnStats, totalRows: totalRows, sortModel: sortModel, hiddenColumns: hiddenColumns, loading: loading, onSortChanged: onSortChanged, onLoadMore: onLoadMore, onCellSelected: onCellSelected, onCellEdit: onCellEdit })) : (React.createElement(\"div\", { className: \"ve-empty-state\" }, loading ? (React.createElement(\"div\", { className: \"ve-loading\" },\n React.createElement(\"div\", { className: \"ve-spinner\" }))) : !connected ? (React.createElement(React.Fragment, null,\n React.createElement(\"div\", { className: \"ve-empty-icon\" }, \"\\uD83D\\uDD0C\"),\n React.createElement(\"div\", null, \"Not connected to a kernel\"),\n React.createElement(\"div\", { style: { fontSize: '12px', marginTop: 8, opacity: 0.7 } }, \"Open a notebook and run a cell to connect\"))) : (React.createElement(React.Fragment, null,\n React.createElement(\"div\", { className: \"ve-empty-icon\" }, \"\\uD83D\\uDCCA\"),\n React.createElement(\"div\", null, variables.length === 0\n ? 'No variables in kernel namespace'\n : 'Select a DataFrame to view its contents')))))),\n showSidebar && selectedVar && columnStats.length > 0 && (React.createElement(React.Fragment, null,\n React.createElement(ResizeHandle, { direction: \"horizontal\", onResizeStart: onRightResizeStart, onResize: onRightResize, invert: true }),\n React.createElement(\"div\", { style: { width: rightWidth, minWidth: 150, flexShrink: 0 } },\n React.createElement(MetadataSidebar, { columns: columns, columnStats: columnStats, hiddenColumns: hiddenColumns, onToggleColumn: onToggleColumn, selectedVarInfo: selectedVarInfo || null }))))),\n React.createElement(StatusBar, { selectedVar: selectedVar, totalRows: totalRows, totalCols: columns.length, sortModel: sortModel, connected: connected })));\n};\n","import * as React from 'react';\nfunction formatBytes(bytes) {\n if (bytes < 1024)\n return `${bytes} B`;\n if (bytes < 1024 * 1024)\n return `${(bytes / 1024).toFixed(1)} KB`;\n if (bytes < 1024 * 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;\n}\nfunction formatShape(shape) {\n if (shape.length === 0)\n return 'scalar';\n if (shape.length === 1)\n return `${shape[0].toLocaleString()} items`;\n return shape.map(s => s.toLocaleString()).join(' \\u00d7 ');\n}\nfunction getTypeBadgeClass(typeName) {\n const lower = typeName.toLowerCase();\n if (lower === 'dataframe')\n return 've-type-dataframe';\n if (lower === 'series')\n return 've-type-series';\n if (lower === 'ndarray')\n return 've-type-ndarray';\n if (lower === 'list' || lower === 'tuple')\n return 've-type-list';\n if (lower === 'dict')\n return 've-type-dict';\n return 've-type-other';\n}\nfunction getKindLabel(kind) {\n switch (kind) {\n case 'list_of_dicts': return 'records';\n case 'list_of_lists': return 'matrix';\n case 'list_of_dataframes': return 'container';\n case 'dict_of_dataframes': return 'container';\n case 'dict_of_lists': return 'table';\n case 'dict_of_dicts': return 'nested';\n case 'list_scalar': return 'values';\n case 'dict_scalar': return 'record';\n default: return '';\n }\n}\nexport const VariableList = ({ variables, selectedVar, onSelect }) => {\n const [filter, setFilter] = React.useState('');\n const filtered = React.useMemo(() => {\n if (!filter)\n return variables;\n const lower = filter.toLowerCase();\n return variables.filter(v => v.name.toLowerCase().includes(lower) || v.typeName.toLowerCase().includes(lower));\n }, [variables, filter]);\n const sorted = React.useMemo(() => {\n return [...filtered].sort((a, b) => {\n if (a.isTabular !== b.isTabular)\n return a.isTabular ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n }, [filtered]);\n return (React.createElement(\"div\", { className: \"ve-variable-list\" },\n React.createElement(\"div\", { className: \"ve-variable-list-header\" },\n React.createElement(\"input\", { className: \"ve-variable-search\", type: \"text\", placeholder: \"Filter objects...\", value: filter, onChange: e => setFilter(e.target.value) })),\n React.createElement(\"div\", { className: \"ve-variable-items\" }, sorted.length === 0 ? (React.createElement(\"div\", { style: { padding: '12px 8px', textAlign: 'center', opacity: 0.5, fontSize: '12px' } }, variables.length === 0 ? 'No variables' : 'No matches')) : (sorted.map(v => {\n const kindLabel = getKindLabel(v.tabularKind);\n return (React.createElement(\"div\", { key: v.name, className: `ve-variable-item ${v.name === selectedVar ? 've-selected' : ''}`, onClick: () => v.isTabular && onSelect(v.name), style: { opacity: v.isTabular ? 1 : 0.6, cursor: v.isTabular ? 'pointer' : 'default' }, title: v.isTabular ? `Click to view ${v.name}` : `${v.name} (${v.typeName})` },\n React.createElement(\"div\", { style: { display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' } },\n React.createElement(\"span\", { className: \"ve-var-name\" }, v.name),\n React.createElement(\"span\", { className: `ve-type-badge ${getTypeBadgeClass(v.typeName)}` }, v.typeName),\n kindLabel && (React.createElement(\"span\", { className: \"ve-kind-label\" }, kindLabel))),\n React.createElement(\"div\", { className: \"ve-var-meta\" },\n React.createElement(\"span\", null, formatShape(v.shape)),\n React.createElement(\"span\", null, formatBytes(v.memoryBytes)))));\n })))));\n};\n","import { INotebookTracker } from '@jupyterlab/notebook';\nimport { IConsoleTracker } from '@jupyterlab/console';\nimport { ICommandPalette } from '@jupyterlab/apputils';\nimport { spreadsheetIcon } from '@jupyterlab/ui-components';\nimport { CommManager } from './comm/CommManager';\nimport { VariableExplorerApp } from './components/VariableExplorerApp';\nimport { cloneStylesheets } from './utils/stylesheetCloner';\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nconst PLUGIN_ID = 'variable-explorer:plugin';\nconst COMMAND_ID = 'variable-explorer:open';\n/**\n * Manages the detached Variable Explorer window and its React tree.\n */\nclass VariableExplorerManager {\n constructor() {\n this._commManager = new CommManager();\n this._externalWindow = null;\n this._root = null;\n this._pollTimer = null;\n }\n get commManager() {\n return this._commManager;\n }\n get isOpen() {\n return this._externalWindow !== null && !this._externalWindow.closed;\n }\n /**\n * Open the Variable Explorer in a detached window.\n */\n open() {\n if (this.isOpen) {\n this._externalWindow.focus();\n return;\n }\n const width = Math.min(1400, screen.availWidth * 0.8);\n const height = Math.min(900, screen.availHeight * 0.8);\n const left = Math.round((screen.availWidth - width) / 2);\n const top = Math.round((screen.availHeight - height) / 2);\n this._externalWindow = window.open('', 'variable-explorer', `width=${width},height=${height},left=${left},top=${top},menubar=no,toolbar=no,location=no,status=no,resizable=yes,scrollbars=no`);\n if (!this._externalWindow) {\n console.error('Variable Explorer: Popup blocked.');\n return;\n }\n const doc = this._externalWindow.document;\n doc.write(`<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>Variable Explorer</title>\n <style>\n html, body { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; }\n #ve-root { width: 100%; height: 100%; }\n </style>\n</head>\n<body>\n <div id=\"ve-root\"></div>\n</body>\n</html>`);\n doc.close();\n cloneStylesheets(document, doc);\n // Copy theme\n const parentBody = document.body;\n const childBody = doc.body;\n for (let i = 0; i < parentBody.attributes.length; i++) {\n const attr = parentBody.attributes[i];\n if (attr.name.startsWith('data-jp-')) {\n childBody.setAttribute(attr.name, attr.value);\n }\n }\n childBody.className = parentBody.className;\n const container = doc.getElementById('ve-root');\n ReactDOM.render(React.createElement(VariableExplorerApp, {\n commManager: this._commManager,\n autoDetach: false\n }), container);\n this._root = container;\n this._pollTimer = window.setInterval(() => {\n if (this._externalWindow && this._externalWindow.closed) {\n this._cleanup();\n }\n }, 500);\n this._externalWindow.addEventListener('beforeunload', () => {\n this._cleanup();\n });\n }\n _cleanup() {\n if (this._pollTimer !== null) {\n window.clearInterval(this._pollTimer);\n this._pollTimer = null;\n }\n if (this._root) {\n try {\n ReactDOM.unmountComponentAtNode(this._root);\n }\n catch ( /* */_a) { /* */ }\n this._root = null;\n }\n this._externalWindow = null;\n }\n}\nconst plugin = {\n id: PLUGIN_ID,\n description: 'A Spyder/Stata-grade variable explorer for JupyterLab',\n autoStart: true,\n requires: [INotebookTracker],\n optional: [ICommandPalette, IConsoleTracker],\n activate: (app, notebookTracker, palette, consoleTracker) => {\n console.log('Variable Explorer extension activated');\n const manager = new VariableExplorerManager();\n const connectToKernel = async (kernel) => {\n if (!kernel)\n return;\n try {\n await manager.commManager.connect(kernel);\n }\n catch (e) {\n console.error('Variable Explorer: Failed to connect to kernel', e);\n }\n };\n notebookTracker.currentChanged.connect(async (_, notebook) => {\n if (!notebook)\n return;\n const session = notebook.sessionContext;\n session.ready.then(() => {\n var _a;\n connectToKernel((_a = session.session) === null || _a === void 0 ? void 0 : _a.kernel);\n });\n session.kernelChanged.connect((_, args) => {\n if (args.newValue) {\n connectToKernel(args.newValue);\n }\n });\n });\n if (consoleTracker) {\n consoleTracker.currentChanged.connect(async (_, consolePanel) => {\n if (!consolePanel)\n return;\n const session = consolePanel.sessionContext;\n session.ready.then(() => {\n var _a;\n connectToKernel((_a = session.session) === null || _a === void 0 ? void 0 : _a.kernel);\n });\n session.kernelChanged.connect((_, args) => {\n if (args.newValue) {\n connectToKernel(args.newValue);\n }\n });\n });\n }\n // Register command — the schema declares this as a toolbar button + menu item\n app.commands.addCommand(COMMAND_ID, {\n label: 'Variable Explorer',\n caption: 'Open Variable Explorer in a separate window',\n icon: spreadsheetIcon,\n execute: () => {\n var _a;\n manager.open();\n const currentNotebook = notebookTracker.currentWidget;\n if (currentNotebook) {\n const kernel = (_a = currentNotebook.sessionContext.session) === null || _a === void 0 ? void 0 : _a.kernel;\n connectToKernel(kernel);\n }\n }\n });\n if (palette) {\n palette.addItem({\n command: COMMAND_ID,\n category: 'Variable Explorer'\n });\n }\n }\n};\nexport default plugin;\n","/** Color scale utilities for conditional formatting */\nexport function numericHeatmap(value, min, max) {\n if (value == null || isNaN(value))\n return 'transparent';\n const range = max - min;\n if (range === 0)\n return 'rgba(100, 149, 237, 0.15)';\n const t = Math.max(0, Math.min(1, (value - min) / range));\n // Blue (cold) → transparent (mid) → Red (hot)\n if (t < 0.5) {\n const s = 1 - t * 2; // 1..0\n return `rgba(66, 133, 244, ${(s * 0.25).toFixed(3)})`;\n }\n const s = (t - 0.5) * 2; // 0..1\n return `rgba(234, 67, 53, ${(s * 0.25).toFixed(3)})`;\n}\nexport function booleanColor(value) {\n if (value === true || value === 1) {\n return 'rgba(52, 168, 83, 0.7)'; // Green\n }\n if (value === false || value === 0) {\n return 'rgba(66, 133, 244, 0.7)'; // Blue\n }\n return 'rgba(128, 128, 128, 0.3)'; // Gray for null\n}\n","/** Canvas-based mini histogram rendering for column headers */\nexport function drawHistogram(canvas, data) {\n const ctx = canvas.getContext('2d');\n if (!ctx)\n return;\n const dpr = window.devicePixelRatio || 1;\n const w = canvas.clientWidth;\n const h = canvas.clientHeight;\n canvas.width = w * dpr;\n canvas.height = h * dpr;\n ctx.scale(dpr, dpr);\n ctx.clearRect(0, 0, w, h);\n switch (data.type) {\n case 'numeric':\n drawNumericHistogram(ctx, w, h, data);\n break;\n case 'categorical':\n drawCategoricalHistogram(ctx, w, h, data);\n break;\n case 'boolean':\n drawBooleanBar(ctx, w, h, data);\n break;\n }\n}\nfunction drawNumericHistogram(ctx, w, h, data) {\n const { counts } = data;\n if (counts.length === 0)\n return;\n const maxCount = Math.max(...counts);\n if (maxCount === 0)\n return;\n const barWidth = w / counts.length;\n const padding = 1;\n // Get computed style for theming\n const style = getComputedStyle(document.documentElement);\n const barColor = style.getPropertyValue('--jp-brand-color1').trim() || '#1976d2';\n for (let i = 0; i < counts.length; i++) {\n const barHeight = (counts[i] / maxCount) * (h - 2);\n const x = i * barWidth + padding / 2;\n const y = h - barHeight - 1;\n ctx.fillStyle = barColor;\n ctx.globalAlpha = 0.6;\n ctx.fillRect(x, y, barWidth - padding, barHeight);\n }\n ctx.globalAlpha = 1.0;\n}\nfunction drawCategoricalHistogram(ctx, w, h, data) {\n const { counts } = data;\n if (counts.length === 0)\n return;\n const maxCount = Math.max(...counts);\n if (maxCount === 0)\n return;\n const barHeight = h / Math.min(counts.length, 8);\n const padding = 1;\n const colors = [\n '#1976d2', '#388e3c', '#f57c00', '#7b1fa2',\n '#c62828', '#00838f', '#4e342e', '#546e7a'\n ];\n for (let i = 0; i < Math.min(counts.length, 8); i++) {\n const barWidth = (counts[i] / maxCount) * (w - 2);\n const y = i * barHeight + padding / 2;\n ctx.fillStyle = colors[i % colors.length];\n ctx.globalAlpha = 0.6;\n ctx.fillRect(1, y, barWidth, barHeight - padding);\n }\n ctx.globalAlpha = 1.0;\n}\nfunction drawBooleanBar(ctx, w, h, data) {\n const total = data.trueCount + data.falseCount + data.nullCount;\n if (total === 0)\n return;\n const trueWidth = (data.trueCount / total) * w;\n const falseWidth = (data.falseCount / total) * w;\n const barY = h * 0.2;\n const barH = h * 0.6;\n // True (green)\n ctx.fillStyle = 'rgba(52, 168, 83, 0.7)';\n ctx.fillRect(0, barY, trueWidth, barH);\n // False (blue)\n ctx.fillStyle = 'rgba(66, 133, 244, 0.7)';\n ctx.fillRect(trueWidth, barY, falseWidth, barH);\n // Null (gray)\n if (data.nullCount > 0) {\n ctx.fillStyle = 'rgba(128, 128, 128, 0.4)';\n ctx.fillRect(trueWidth + falseWidth, barY, w - trueWidth - falseWidth, barH);\n }\n}\n","/** Clone stylesheets from the main document to a detached window */\nexport function cloneStylesheets(source, target) {\n var _a;\n // Copy <link> stylesheets\n const links = source.querySelectorAll('link[rel=\"stylesheet\"]');\n links.forEach(link => {\n const clone = target.createElement('link');\n clone.rel = 'stylesheet';\n clone.href = link.href;\n target.head.appendChild(clone);\n });\n // Copy <style> elements\n const styles = source.querySelectorAll('style');\n styles.forEach(style => {\n const clone = target.createElement('style');\n clone.textContent = style.textContent;\n target.head.appendChild(clone);\n });\n // Copy inline style sheets that might be injected by webpack\n for (let i = 0; i < source.styleSheets.length; i++) {\n const sheet = source.styleSheets[i];\n if (!sheet.href && ((_a = sheet.ownerNode) === null || _a === void 0 ? void 0 : _a.nodeName) === 'STYLE') {\n // Already copied above via querySelectorAll('style')\n continue;\n }\n try {\n // Try to access cssRules (may fail for cross-origin sheets)\n if (sheet.cssRules) {\n let cssText = '';\n for (let j = 0; j < sheet.cssRules.length; j++) {\n cssText += sheet.cssRules[j].cssText + '\\n';\n }\n if (cssText && !sheet.href) {\n const styleEl = target.createElement('style');\n styleEl.textContent = cssText;\n target.head.appendChild(styleEl);\n }\n }\n }\n catch (_b) {\n // Cross-origin stylesheet — skip\n }\n }\n // Copy body data attributes for theme detection\n const bodyAttrs = source.body.attributes;\n for (let i = 0; i < bodyAttrs.length; i++) {\n const attr = bodyAttrs[i];\n if (attr.name.startsWith('data-jp-')) {\n target.body.setAttribute(attr.name, attr.value);\n }\n }\n}\n"],"names":[],"sourceRoot":""}