From 9d852c9a341cd3034b610ebf2811ac16f7efa935 Mon Sep 17 00:00:00 2001 From: ash-t-luu Date: Mon, 18 Dec 2023 14:22:06 -0800 Subject: [PATCH 01/25] changed files to ts/tsx and require statements to import/export --- .gitignore | 3 +- extension.js => extension.ts | 24 ++-- package-lock.json | 55 +++++---- package.json | 24 +++- postcss.config.js => postcss.config.cjs | 2 + src/{getNonce.js => getNonce.ts} | 8 +- src/{panel.js => panel.ts} | 14 +-- src/{parser.js => parser.ts} | 105 +++++++++++------- src/treeTemplates/tree.js | 11 -- src/types/ImportObj.ts | 3 + src/types/builder.ts | 10 ++ src/types/connection.ts | 7 ++ src/types/index.d.ts | 2 + src/types/tree.ts | 18 +++ src/webview/{App.jsx => App.tsx} | 2 - src/webview/{Flow.jsx => Flow.tsx} | 10 +- .../{flowBuilder.js => flowBuilder.tsx} | 73 +++++++++--- src/webview/{index.jsx => index.tsx} | 3 +- tsconfig.json | 21 ++++ webpack.config.cjs | 31 ------ webpack.config.ts | 32 ++++++ 21 files changed, 307 insertions(+), 151 deletions(-) rename extension.js => extension.ts (64%) rename postcss.config.js => postcss.config.cjs (74%) rename src/{getNonce.js => getNonce.ts} (64%) rename src/{panel.js => panel.ts} (90%) rename src/{parser.js => parser.ts} (87%) delete mode 100644 src/treeTemplates/tree.js create mode 100644 src/types/ImportObj.ts create mode 100644 src/types/builder.ts create mode 100644 src/types/connection.ts create mode 100644 src/types/index.d.ts create mode 100644 src/types/tree.ts rename src/webview/{App.jsx => App.tsx} (98%) rename src/webview/{Flow.jsx => Flow.tsx} (90%) rename src/webview/{flowBuilder.js => flowBuilder.tsx} (62%) rename src/webview/{index.jsx => index.tsx} (89%) create mode 100644 tsconfig.json delete mode 100644 webpack.config.cjs create mode 100644 webpack.config.ts diff --git a/.gitignore b/.gitignore index 236ce59..05d2dd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -/build \ No newline at end of file +/build +/package-lock.json \ No newline at end of file diff --git a/extension.js b/extension.ts similarity index 64% rename from extension.js rename to extension.ts index fe5541b..fc415a4 100644 --- a/extension.js +++ b/extension.ts @@ -1,6 +1,8 @@ -const vscode = require('vscode'); -const { createPanel } = require('./src/panel'); -const { Parser } = require('./src/parser'); +import * as vscode from 'vscode'; +import {createPanel} from './src/panel'; +// const { createPanel } = require('./src/panel'); +// const { Parser } = require('./src/parser'); +import { Parser } from './src/parser'; // This method is called when your extension is activated // Your extension is activated the very first time the command is executed @@ -12,20 +14,26 @@ function activate(context) { }); // pass in the command we want to register (refer to package.json) - let result = vscode.commands.registerCommand('myExtension.showPanel', () => { - // call helper func - createPanel(context); - }); + // let result = vscode.commands.registerCommand('myExtension.showPanel', () => { + // // call helper func + // createPanel(context); + // }); vscode.commands.registerCommand('myExtension.pickFile', async () => { const fileArray = await vscode.window.showOpenDialog({ canSelectFolders: false, canSelectFiles: true, canSelectMany: false }); + + if (!fileArray || fileArray.length === 0) { + vscode.window.showErrorMessage('No file selected'); + return; + } + const tree = new Parser(fileArray[0].path); tree.parse(); const data = tree.getTree(); console.log('Data sent back: \n', data); createPanel(context, data); }); - context.subscriptions.push(disposable, result); + context.subscriptions.push(disposable); } // This method is called when your extension is deactivated diff --git a/package-lock.json b/package-lock.json index 342ca40..b8bf69a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "react-labyrinth", "version": "0.0.1", + "license": "MIT", "dependencies": { "@babel/core": "^7.23.3", "@babel/parser": "^7.23.4", @@ -15,11 +16,10 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", + "ts-loader": "^9.5.1", "webpack": "^5.89.0" }, "devDependencies": { @@ -32,8 +32,10 @@ "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "tailwindcss": "^3.3.6", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "webpack-cli": "^5.1.4" }, "engines": { @@ -3765,7 +3767,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3993,7 +3994,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4096,7 +4096,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4226,7 +4225,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -4237,8 +4235,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colorette": { "version": "2.0.20", @@ -4914,7 +4911,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5422,7 +5418,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -5760,7 +5755,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -6170,7 +6164,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -7848,7 +7841,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8009,7 +8001,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8023,6 +8014,33 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8048,10 +8066,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", - "dev": true, + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index b392c05..2d108e4 100644 --- a/package.json +++ b/package.json @@ -3,15 +3,30 @@ "displayName": "React Labyrinth", "description": "React Server Components visualization tool", "version": "0.0.1", + "publisher": "ReactLabyrinthDev", "engines": { "vscode": "^1.84.0" }, + "repository": { + "type": "git", + "url": "https://github.com/oslabs-beta/React-Labyrinth" + }, "categories": [ "Other" ], + "keywords": [ + "react", + "rsc", + "hierarchy tree", + "parent-child", + "visualizer", + "server component" + ], + "license": "MIT", "pricing": "Free", "activationEvents": [], - "main": "./extension.js", + "main": "./extension.ts", + "type": "module", "contributes": { "commands": [ { @@ -75,8 +90,10 @@ "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", "tailwindcss": "^3.3.6", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "webpack-cli": "^5.1.4" }, "dependencies": { @@ -87,11 +104,10 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", - "react": "^18.2.0", - "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", + "ts-loader": "^9.5.1", "webpack": "^5.89.0" } } diff --git a/postcss.config.js b/postcss.config.cjs similarity index 74% rename from postcss.config.js rename to postcss.config.cjs index dbcca66..b4d9371 100644 --- a/postcss.config.js +++ b/postcss.config.cjs @@ -1,4 +1,6 @@ const tailwindcss = require('tailwindcss'); +// import * as tailwindcss from 'tailwindcss'; + module.exports = { plugins: [ 'postcss-preset-env', diff --git a/src/getNonce.js b/src/getNonce.ts similarity index 64% rename from src/getNonce.js rename to src/getNonce.ts index bd01ad0..8231f28 100644 --- a/src/getNonce.js +++ b/src/getNonce.ts @@ -1,6 +1,6 @@ -function getNonce() { - let text = ""; - const possible = +export function getNonce() { + let text: string = ""; + const possible: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (let i = 0; i < 32; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); @@ -8,4 +8,4 @@ function getNonce() { return text; } -module.exports = { getNonce } \ No newline at end of file +// module.exports = { getNonce } \ No newline at end of file diff --git a/src/panel.js b/src/panel.ts similarity index 90% rename from src/panel.js rename to src/panel.ts index 2328f6c..a6eea21 100644 --- a/src/panel.js +++ b/src/panel.ts @@ -1,8 +1,8 @@ -const vscode = require('vscode'); -const { getNonce } = require('./getNonce.js'); -const { Parser } = require('./parser.js'); +// const vscode = require('vscode'); +import * as vscode from 'vscode'; +import { getNonce } from './getNonce'; -function createPanel(context, data) { +export function createPanel(context, data) { // if the current panel exists, then reveal the column, else make one? // utilize method on vscode.window object to create webview @@ -30,7 +30,7 @@ function createPanel(context, data) { // will need to use onDidDispose to clear cached data and reset tree when the webview and/or application is closed panel.webview.onDidReceiveMessage( - async (msg) => { + async (msg: any) => { switch (msg.type) { case 'onData': if (!msg.value) break; @@ -77,11 +77,11 @@ function createWebviewHTML(URI, initialData) { }); } - + ` ) } -module.exports = { createPanel }; \ No newline at end of file +// module.exports = { createPanel }; \ No newline at end of file diff --git a/src/parser.js b/src/parser.ts similarity index 87% rename from src/parser.js rename to src/parser.ts index 4b8982b..6d3049f 100644 --- a/src/parser.js +++ b/src/parser.ts @@ -1,7 +1,17 @@ -const fs = require('fs') -const path = require('path') -const babel = require('@babel/parser'); -const { getNonce } = require('./getNonce.js'); +// const fs = require('fs') +import * as fs from 'fs'; +import * as path from 'path'; +// const path = require('path') +// const babel = require('@babel/parser'); +import * as babel from '@babel/parser'; +import { getNonce } from './getNonce'; +// const { getNonce } = require('./getNonce'); +// const { Tree } = require('./types/tree'); +// const { File } = require('@babel/types'); +// const ImportObj = require('./types/ImportObj') +import { ImportObj } from './types/ImportObj'; +import { Tree } from "./types/tree"; +import { File } from '@babel/types'; // // function to determine server or client component (can look for 'use client' and 'hooks') // // input: ast node (object) @@ -25,8 +35,11 @@ const { getNonce } = require('./getNonce.js'); // return false; // } -class Parser { - constructor(filePath) { +export class Parser { + entryFile: string; + tree: Tree | undefined; + + constructor(filePath: string) { // Fix when selecting files in wsl file system this.entryFile = filePath; if (process.platform === 'linux' && this.entryFile.includes('wsl$')) { @@ -50,7 +63,7 @@ class Parser { } // method to generate component tree based on current entryFile - parse() { + public parse(): Tree { // Create root Tree node const root = { id: getNonce(), @@ -75,25 +88,25 @@ class Parser { return this.tree; } - getTree() { + public getTree(): Tree { return this.tree; } // Set Sapling Parser with a specific Data Tree (from workspace state) - setTree(tree) { + public setTree(tree: Tree) { this.entryFile = tree.filePath; this.tree = tree; } - updateTree(filePath) { - let children = []; + public updateTree(filePath: string): Tree { + let children: any[] = []; - const getChildNodes = (node) => { + const getChildNodes = (node: Tree): void => { const { depth, filePath, expanded } = node; children.push({ depth, filePath, expanded }); }; - const matchExpand = (node) => { + const matchExpand = (node: Tree): void => { for (let i = 0; i < children.length; i += 1) { const oldNode = children[i]; if ( @@ -106,7 +119,7 @@ class Parser { } }; - const callback = (node) => { + const callback = (node: Tree): void => { if (node.filePath === filePath) { node.children.forEach((child) => { this.traverseTree(getChildNodes, child); @@ -121,23 +134,23 @@ class Parser { }; this.traverseTree(callback, this.tree); - return this.tree; + return this.tree!; } // Traverses the tree and changes expanded property of node whose id matches provided id - toggleNode(id, expanded) { - const callback = (node) => { + public toggleNode(id: string, expanded: boolean): Tree{ + const callback = (node: { id: string; expanded: boolean }) => { if (node.id === id) { node.expanded = expanded; } }; this.traverseTree(callback, this.tree); - return this.tree; + return this.tree!; } // Traverses all nodes of current component tree and applies callback to each node - traverseTree(callback, node = this.tree) { + private traverseTree(callback: Function, node: Tree | undefined = this.tree): void { if (!node) { return; } @@ -150,7 +163,7 @@ class Parser { } // Recursively builds the React component tree structure starting from root node - parser(componentTree) { + private parser(componentTree: Tree): Tree | undefined { // console.log('componentTree:', componentTree); // If import is a node module, do not parse any deeper if (!['\\', '/', '.'].includes(componentTree.importPath[0])) { @@ -177,7 +190,7 @@ class Parser { } // Create abstract syntax tree of current component tree file - let ast; + let ast: babel.ParseResult; try { ast = babel.parse( fs.readFileSync(path.resolve(componentTree.filePath), 'utf-8'), @@ -223,9 +236,9 @@ class Parser { } // Finds files where import string does not include a file extension - getFileName(componentTree) { + private getFileName(componentTree: Tree): string | undefined { const ext = path.extname(componentTree.filePath); - let fileName = componentTree.fileName; + let fileName: string | undefined = componentTree.fileName; if (!ext) { // Try and find file extension that exists in directory: @@ -242,7 +255,7 @@ class Parser { // import Page2 from './page2'; -> is parsed as 'VariableDeclaration' // input: array of objects: ast.program.body // output: object of imoprts - getImports(body) { + private getImports(body: { [key: string]: any }[]): ImportObj { const bodyImports = body.filter((item) => item.type === 'ImportDeclaration' || 'VariableDeclaration'); return bodyImports.reduce((accum, curr) => { @@ -268,7 +281,7 @@ class Parser { }, {}); } - findVarDecImports(ast) { + private findVarDecImports(ast: { [key: string]: any }): string | boolean { // find import path in variable declaration and return it, if (ast.hasOwnProperty('callee') && ast.callee.type === 'Import') { return ast.arguments[0].value; @@ -288,7 +301,7 @@ class Parser { // helper function to determine component type (client) // input: ast.program.body // output: boolean - getCallee(body) { + private getCallee(body): boolean { const defaultErr = (err,) => { return { method: 'Error in getCallee method of Parser:', @@ -364,7 +377,7 @@ class Parser { return checkTrue; } else if (bodyCallee.length > 1) { - let calleeArr; + let calleeArr: []; for (let i = 0; i < bodyCallee.length; i++) { try { if (bodyCallee[i].declarations[0]?.init?.body?.body) { @@ -389,10 +402,16 @@ class Parser { } // Finds JSX React Components in current file - getJSXChildren(astTokens, importsObj, parentNode) { - let childNodes = {}; - let props = {}; - let token; + private getJSXChildren(astTokens: any[], + importsObj: ImportObj, + parentNode: Tree + ): Tree[] { + // let childNodes = {}; + // let props = {}; + // let token; + let childNodes: { [key: string]: Tree } = {}; + let props: { [key: string]: boolean } = {}; + let token: { [key: string]: any }; for (let i = 0; i < astTokens.length; i++) { @@ -432,13 +451,13 @@ class Parser { return Object.values(childNodes); } - getChildNodes( - imports, - astToken, - props, - parent, - children, - ) { + private getChildNodes( + imports: ImportObj, + astToken: { [key: string]: any }, + props: { [key: string]: boolean }, + parent: Tree, + children: { [key: string]: Tree } + ): { [key: string]: Tree } { if (children[astToken.value]) { children[astToken.value].count += 1; children[astToken.value].props = { @@ -473,8 +492,10 @@ class Parser { } // Extracts prop names from a JSX element - getJSXProps(astTokens, j) { - const props = {}; + private getJSXProps(astTokens: { [key: string]: any }[], + j: number + ): { [key: string]: boolean } { + const props: any = {}; while (astTokens[j].type.label !== 'jsxTagEnd') { if ( astTokens[j].type.label === 'jsxName' && @@ -488,7 +509,7 @@ class Parser { } // Checks if current Node is connected to React-Redux Store - checkForRedux(astTokens, importsObj) { + private checkForRedux(astTokens: any[], importsObj: ImportObj): boolean { // Check that react-redux is imported in this file (and we have a connect method or otherwise) let reduxImported = false; let connectAlias; @@ -520,4 +541,4 @@ class Parser { } } -module.exports = { Parser }; \ No newline at end of file +// module.exports = { Parser }; \ No newline at end of file diff --git a/src/treeTemplates/tree.js b/src/treeTemplates/tree.js deleted file mode 100644 index ae488b7..0000000 --- a/src/treeTemplates/tree.js +++ /dev/null @@ -1,11 +0,0 @@ -const Tree = { - id: undefined, - fileName: undefined, - filePath: undefined, - // children & parentList should be populated with other Tree objects - children: [], - parentList: [], - isClientComponent: false -} - -module.exports = { Tree }; \ No newline at end of file diff --git a/src/types/ImportObj.ts b/src/types/ImportObj.ts new file mode 100644 index 0000000..1d5932e --- /dev/null +++ b/src/types/ImportObj.ts @@ -0,0 +1,3 @@ +export type ImportObj = { + [key: string]: { importPath: string; importName: string; }; + }; \ No newline at end of file diff --git a/src/types/builder.ts b/src/types/builder.ts new file mode 100644 index 0000000..2517da9 --- /dev/null +++ b/src/types/builder.ts @@ -0,0 +1,10 @@ +export type Builder = { + parsedData: [object]; + id: number; + x: number; + y: number; + initialNodes: []; + viewData: any; + edgeId: number; + initialEdges: []; +} \ No newline at end of file diff --git a/src/types/connection.ts b/src/types/connection.ts new file mode 100644 index 0000000..cb70b7b --- /dev/null +++ b/src/types/connection.ts @@ -0,0 +1,7 @@ +export enum ConnectionLineType { + Bezier = 'default', + Straight = 'straight', + Step = 'step', + SmoothStep = 'smoothstep', + SimpleBezier = 'simplebezier', + } \ No newline at end of file diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..d65604a --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,2 @@ +declare module '*.jpg'; +declare module '*.jpeg'; \ No newline at end of file diff --git a/src/types/tree.ts b/src/types/tree.ts new file mode 100644 index 0000000..5b6eb7a --- /dev/null +++ b/src/types/tree.ts @@ -0,0 +1,18 @@ +export type Tree = { + id: string; + name: string; + fileName: string; + filePath: string; + importPath: string; + expanded: boolean; + depth: number; + count: number; + thirdParty: boolean; + reactRouter: boolean; + reduxConnect: boolean; + children: Tree[]; + parentList: string[]; + props: { [key: string]: boolean; }; + error: string; + isClientComponent: boolean; +} diff --git a/src/webview/App.jsx b/src/webview/App.tsx similarity index 98% rename from src/webview/App.jsx rename to src/webview/App.tsx index 0f936b2..7d4fd8c 100644 --- a/src/webview/App.jsx +++ b/src/webview/App.tsx @@ -1,7 +1,5 @@ import React from "react"; - import Flow from "./Flow"; - import "./style.css"; export default function App() { diff --git a/src/webview/Flow.jsx b/src/webview/Flow.tsx similarity index 90% rename from src/webview/Flow.jsx rename to src/webview/Flow.tsx index 96be6ec..ce9a7af 100644 --- a/src/webview/Flow.jsx +++ b/src/webview/Flow.tsx @@ -8,15 +8,14 @@ import ReactFlow, { useNodesState, useEdgesState } from "reactflow"; - import "reactflow/dist/style.css"; - -import FlowBuilder from './flowBuilder.js'; +import { ConnectionLineType } from "../types/connection"; +import FlowBuilder from './flowBuilder'; const onInit = (reactFlowInstance) => console.log("flow loaded:", reactFlowInstance); -const OverviewFlow = () => { +const OverviewFlow: React.FC = () => { const initialNodes = []; const initialEdges = []; @@ -35,9 +34,6 @@ const OverviewFlow = () => { case 'parsed-data': { const results = new FlowBuilder(msg.value); results.build(msg.settings) - // console.log('results: ', results); - // console.log('results.initialNodes: ', results.initialNodes); - // console.log('results.initialEdges: ', results.initialEdges); setNodes(results.initialNodes); setEdges(results.initialEdges); break; diff --git a/src/webview/flowBuilder.js b/src/webview/flowBuilder.tsx similarity index 62% rename from src/webview/flowBuilder.js rename to src/webview/flowBuilder.tsx index 62fd030..9eeb533 100644 --- a/src/webview/flowBuilder.js +++ b/src/webview/flowBuilder.tsx @@ -2,24 +2,71 @@ import React from 'react'; // will create a build func and then call the helper funcs to return an object // make a new instance of this class in flow, call the build method, and pass this as state +interface Node { + id: string; + data: { + label: React.ReactNode; + }; + type: string; + position: { x: number, y: number}; + style: { + borderRadius: string; + borderWidth: string; + borderColor: string; + display: string; + justifyContent: string; + placeItems: string; + backgroundColor: string; + }; +} + +interface Edge { + id: string; + source: string; + target: string; + type: string; + animated: boolean; +} + +interface ParsedDataItem { + fileName: string; + isClientComponent: boolean; + children?: ParsedDataItem[]; + thirdParty?: boolean; + reactRouter?: boolean; +} + +interface Settings { + thirdParty: boolean; + reactRouter: boolean; +} + class FlowBuilder { - constructor(data) { + private parsedData: ParsedDataItem[]; + private id: number; + private x: number; + private y: number; + public initialNodes: Node[]; + private viewData: ParsedDataItem[]; + private edgeId: number; + public initialEdges: Edge[]; + + constructor(data: ParsedDataItem) { this.parsedData = [data]; this.id = 0; this.x = 0; this.y = 0; this.initialNodes = []; - this.viewData; + this.viewData = []; this.edgeId = 0; this.initialEdges = []; } - buildNodesArray(parsedData, x = this.x, y = this.y) { + private buildNodesArray(parsedData: ParsedDataItem[] | undefined, x: number = this.x, y: number = this.y): void { if (!parsedData) return; - parsedData.forEach((item) => { - const node = { + const node: Node = { id: (++this.id).toString(), data: { label: ( @@ -28,7 +75,7 @@ class FlowBuilder { }, // type: item.depth === 0 ? 'input' : '', type: 'default', - position: { x: x += 40, y: y += 30 }, + position: { x: (x += 40), y: (y += 30) }, style: { borderRadius: '6px', borderWidth: '2px', @@ -41,18 +88,18 @@ class FlowBuilder { }; this.initialNodes.push(node); if (item.children) { - this.buildNodesArray(item.children, this.x += 40, this.y += 30); + this.buildNodesArray(item.children, (this.x += 40), (this.y += 30)); } }); }; - buildEdgesArray(parsedData, parentID) { + private buildEdgesArray(parsedData: ParsedDataItem[] | undefined, parentID?: number): void { if (!parsedData) return; parsedData.forEach((item) => { const nodeID = ++this.edgeId; if (parentID) { - const edge = { + const edge: Edge = { id: `e${parentID}-${nodeID}`, source: parentID.toString(), target: nodeID.toString(), @@ -67,13 +114,13 @@ class FlowBuilder { }); } - build(settings) { + public build(settings: Settings): void { const treeParsed = JSON.parse(JSON.stringify(this.parsedData[0])); console.log('settings: ', settings); - const traverse = (node) => { - let validChildren = []; + const traverse = (node: ParsedDataItem): void => { + let validChildren: ParsedDataItem[] = []; - for (let i = 0; i < node.children.length; i++) { + for (let i = 0; i < node.children?.length; i++) { if ( node.children[i].thirdParty && settings.thirdParty && diff --git a/src/webview/index.jsx b/src/webview/index.tsx similarity index 89% rename from src/webview/index.jsx rename to src/webview/index.tsx index 45645f4..45e01f7 100644 --- a/src/webview/index.jsx +++ b/src/webview/index.tsx @@ -1,8 +1,7 @@ import React from "react"; import { createRoot } from "react-dom/client"; import './style.css'; - -import App from "./App.jsx"; +import App from "./App"; const rootElement = document.getElementById("root"); const root = createRoot(rootElement); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..93f5276 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "outDir": "build", + "esModuleInterop": true, + "lib": ["es6", "dom"], + "jsx": "react", + "sourceMap": true, + "rootDir": "src", + "allowJs": true, + "strict": false, + }, + "include": ["src", "src/types/index.d.ts"], + "exclude": [ + "node_modules", + ".vscode-test", + "src/webviews", + "src/test/test_apps" + ] +} \ No newline at end of file diff --git a/webpack.config.cjs b/webpack.config.cjs deleted file mode 100644 index 26f1700..0000000 --- a/webpack.config.cjs +++ /dev/null @@ -1,31 +0,0 @@ -const path = require('path') - -module.exports = { - entry: './src/webview/index.jsx', - output: { - filename: 'bundle.js', - path: path.resolve(__dirname, './build'), - }, - resolve: { - extensions: ['.js', '.jsx', '.css'], - }, - module: { - rules: [ - { - test: /\.jsx?/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ['@babel/preset-env', '@babel/preset-react'] - } - } - }, - { - test: /\.(css|scss)$/, - use: ["style-loader", "css-loader", "postcss-loader"], - }, - ] - }, - mode: "development" -} diff --git a/webpack.config.ts b/webpack.config.ts new file mode 100644 index 0000000..e550916 --- /dev/null +++ b/webpack.config.ts @@ -0,0 +1,32 @@ +import * as path from 'path'; + +module.exports = { + entry: './src/webview/index.tsx', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, './build'), + }, + resolve: { + extensions: ['.js', '.ts', '.tsx', '.css'], + }, + module: { + rules: [ + // { + // test: /\.jsx?/, + // exclude: /node_modules/, + // use: { + // loader: "babel-loader", + // options: { + // presets: ['@babel/preset-env', '@babel/preset-react'] + // } + // } + // }, + { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, + { + test: /\.(css)$/, + use: ["style-loader", "css-loader", "postcss-loader"], + }, + ] + }, + mode: "development" +} From 8fe04aaa1397f4b0cb8c2d78d358ff769975b94f Mon Sep 17 00:00:00 2001 From: ash-t-luu Date: Tue, 19 Dec 2023 14:42:39 -0800 Subject: [PATCH 02/25] moved extension.ts to src folder, modified webpack to align with import/export, declared types for strict ts guidlines, installed some dev dependencies --- package-lock.json | 40 +++++++++++++++++ package.json | 5 ++- extension.ts => src/extension.ts | 4 +- src/panel.ts | 2 +- src/webview/Flow.tsx | 12 ++--- tailwind.config.js | 7 ++- tsconfig.json | 7 +-- webpack.config.ts | 77 ++++++++++++++++++++++++-------- 8 files changed, 121 insertions(+), 33 deletions(-) rename extension.ts => src/extension.ts (94%) diff --git a/package-lock.json b/package-lock.json index b8bf69a..8a9a547 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,8 @@ "devDependencies": { "@types/mocha": "^10.0.3", "@types/node": "18.x", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", "@vscode/test-electron": "^2.3.6", "eslint": "^8.54.0", @@ -3434,6 +3436,38 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", + "devOptional": true + }, + "node_modules/@types/react": { + "version": "18.2.45", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", + "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "devOptional": true + }, "node_modules/@types/vscode": { "version": "1.84.1", "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.1.tgz", @@ -4448,6 +4482,12 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true + }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", diff --git a/package.json b/package.json index 2d108e4..0c8f82b 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,7 @@ "license": "MIT", "pricing": "Free", "activationEvents": [], - "main": "./extension.ts", - "type": "module", + "main": "./build/extension.js", "contributes": { "commands": [ { @@ -83,6 +82,8 @@ "devDependencies": { "@types/mocha": "^10.0.3", "@types/node": "18.x", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", "@vscode/test-electron": "^2.3.6", "eslint": "^8.54.0", diff --git a/extension.ts b/src/extension.ts similarity index 94% rename from extension.ts rename to src/extension.ts index fc415a4..a41127c 100644 --- a/extension.ts +++ b/src/extension.ts @@ -1,8 +1,8 @@ import * as vscode from 'vscode'; -import {createPanel} from './src/panel'; +import {createPanel} from './panel'; // const { createPanel } = require('./src/panel'); // const { Parser } = require('./src/parser'); -import { Parser } from './src/parser'; +import { Parser } from './parser'; // This method is called when your extension is activated // Your extension is activated the very first time the command is executed diff --git a/src/panel.ts b/src/panel.ts index a6eea21..5a3d548 100644 --- a/src/panel.ts +++ b/src/panel.ts @@ -34,7 +34,7 @@ export function createPanel(context, data) { switch (msg.type) { case 'onData': if (!msg.value) break; - context.workspaceState = context.workspaceState || {}; + // context.workspaceState = context.workspaceState || {}; context.workspaceState.update('reactLabyrinth', msg.value); // console.log('msg.value from panel.js: ', msg.value); panel.webview.postMessage( diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index ce9a7af..6ea2230 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -54,16 +54,16 @@ const OverviewFlow: React.FC = () => { attributionPosition="top-right" > { - if (n.style?.background) return n.style.background; + nodeStrokeColor={(n): string => { + if (n.style?.background) return `${n.style.background}`; if (n.data.label.props.className.includes('orange')) return "#fdba74"; if (n.data.label.props.className.includes('blue')) return "#93C5FD"; if (n.type === "default") return "#1a192b"; return "#eee"; }} - nodeColor={(n) => { - if (n.style?.background) return n.style.background; + nodeColor={(n): string => { + if (n.style?.background) return `${n.style.background}`; return "#fff"; }} nodeBorderRadius={2} @@ -71,10 +71,10 @@ const OverviewFlow: React.FC = () => {
-

Client: 00

+

Client: 00

-

Server: 00

+

Server: 00

diff --git a/tailwind.config.js b/tailwind.config.js index a7e47f5..db6d9c1 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,12 @@ module.exports = { content: ['./build/bundle.js'], theme: { - extend: {}, + extend: { + backgroundColor: { + orange: '#fdba74', + blue: '#93C5FD', + }, + }, }, variants: { extend: {}, diff --git a/tsconfig.json b/tsconfig.json index 93f5276..d381c8c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,16 +2,17 @@ "compilerOptions": { "target": "es6", "module": "commonjs", - "outDir": "build", + "outDir": "./build", "esModuleInterop": true, "lib": ["es6", "dom"], "jsx": "react", "sourceMap": true, - "rootDir": "src", + "rootDir": "./src", "allowJs": true, "strict": false, }, - "include": ["src", "src/types/index.d.ts"], + // "include": ["src", "src/types/index.d.ts"], + "include": ["src/**/*.ts", "src/**/*.tsx"], "exclude": [ "node_modules", ".vscode-test", diff --git a/webpack.config.ts b/webpack.config.ts index e550916..f5b297c 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -1,32 +1,73 @@ +// import * as path from 'path'; + +// module.exports = { +// entry: './src/webview/index.tsx', +// output: { +// filename: 'bundle.js', +// path: path.resolve(__dirname, './build'), +// }, +// resolve: { +// extensions: ['.js', '.ts', '.tsx', '.css'], +// }, +// module: { +// rules: [ +// // { +// // test: /\.jsx?/, +// // exclude: /node_modules/, +// // use: { +// // loader: "babel-loader", +// // options: { +// // presets: ['@babel/preset-env', '@babel/preset-react'] +// // } +// // } +// // }, +// { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, +// { +// test: /\.(css)$/, +// use: ["style-loader", "css-loader", "postcss-loader"], +// }, +// ] +// }, +// mode: "development" +// } + import * as path from 'path'; +import * as webpack from 'webpack'; + +const extConfig: webpack.Configuration = { + target: 'node', + entry: './src/extension.ts', + output: { + filename: 'extension.js', + libraryTarget: 'commonjs2', + path: path.resolve(__dirname, 'build'), + }, + resolve: { extensions: ['.ts', '.js'] }, + module: { rules: [{ test: /\.ts$/, loader: 'ts-loader' }] }, + externals: { vscode: 'vscode' }, + mode: 'development' +}; -module.exports = { +const webviewConfig: webpack.Configuration = { + target: 'web', entry: './src/webview/index.tsx', output: { filename: 'bundle.js', - path: path.resolve(__dirname, './build'), + path: path.resolve(__dirname, 'build'), }, resolve: { - extensions: ['.js', '.ts', '.tsx', '.css'], + extensions: ['.js', '.ts', '.tsx', 'scss'], }, module: { rules: [ - // { - // test: /\.jsx?/, - // exclude: /node_modules/, - // use: { - // loader: "babel-loader", - // options: { - // presets: ['@babel/preset-env', '@babel/preset-react'] - // } - // } - // }, { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, { - test: /\.(css)$/, - use: ["style-loader", "css-loader", "postcss-loader"], + test: /\.css$/, + use: ['style-loader', 'css-loader'], }, - ] + ], }, - mode: "development" -} + mode: 'development' +}; + +export default [webviewConfig, extConfig]; \ No newline at end of file From fbbbfb4a4d43fcfae8e61c3c27e3e5a197980626 Mon Sep 17 00:00:00 2001 From: ash-t-luu Date: Tue, 19 Dec 2023 15:51:06 -0800 Subject: [PATCH 03/25] added tailwind loader in webpack to make working legend and minimap --- src/webview/Flow.tsx | 8 ++++---- webpack.config.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 6ea2230..c7518ae 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -55,15 +55,15 @@ const OverviewFlow: React.FC = () => { > { - if (n.style?.background) return `${n.style.background}`; - if (n.data.label.props.className.includes('orange')) return "#fdba74"; - if (n.data.label.props.className.includes('blue')) return "#93C5FD"; + if (n.style?.backgroundColor) return n.style.backgroundColor; + // if (n.data.label.props.className.includes('orange')) return "#fdba74"; + // if (n.data.label.props.className.includes('blue')) return "#93C5FD"; if (n.type === "default") return "#1a192b"; return "#eee"; }} nodeColor={(n): string => { - if (n.style?.background) return `${n.style.background}`; + if (n.style?.backgroundColor) return n.style.backgroundColor; return "#fff"; }} nodeBorderRadius={2} diff --git a/webpack.config.ts b/webpack.config.ts index f5b297c..8cc8104 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -63,7 +63,7 @@ const webviewConfig: webpack.Configuration = { { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, { test: /\.css$/, - use: ['style-loader', 'css-loader'], + use: ['style-loader', 'css-loader', 'postcss-loader'], }, ], }, From bb91598aa65dffaf25efc1884f8f5d288e4b33cd Mon Sep 17 00:00:00 2001 From: ash-t-luu Date: Thu, 21 Dec 2023 14:28:03 -0800 Subject: [PATCH 04/25] added types to certain params to keep typesafe, rearranged dependencies based on dev/prod --- package-lock.json | 4 ++-- package.json | 4 ++-- src/extension.ts | 6 +++--- src/panel.ts | 10 +++++----- src/parser.ts | 18 +++++++++--------- src/webview/Flow.tsx | 5 +++-- src/webview/flowBuilder.tsx | 10 +++++----- 7 files changed, 29 insertions(+), 28 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8a9a547..2fe2a0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,8 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", @@ -34,8 +36,6 @@ "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", "tailwindcss": "^3.3.6", "typescript": "^5.3.3", "webpack-cli": "^5.1.4" diff --git a/package.json b/package.json index 0c8f82b..54d124d 100644 --- a/package.json +++ b/package.json @@ -91,8 +91,6 @@ "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", - "react": "^18.2.0", - "react-dom": "^18.2.0", "tailwindcss": "^3.3.6", "typescript": "^5.3.3", "webpack-cli": "^5.1.4" @@ -105,6 +103,8 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "react": "^18.2.0", + "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", diff --git a/src/extension.ts b/src/extension.ts index a41127c..53e4fc5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -7,7 +7,7 @@ import { Parser } from './parser'; // This method is called when your extension is activated // Your extension is activated the very first time the command is executed -function activate(context) { +function activate(context: vscode.ExtensionContext) { let disposable = vscode.commands.registerCommand('react-labyrinth.helloWorld', function () { vscode.window.showInformationMessage('Hello World from React Labyrinth!'); @@ -37,9 +37,9 @@ function activate(context) { } // This method is called when your extension is deactivated -// function deactivate() {} +function deactivate() {} module.exports = { activate, - // deactivate + deactivate } diff --git a/src/panel.ts b/src/panel.ts index 5a3d548..306bb23 100644 --- a/src/panel.ts +++ b/src/panel.ts @@ -1,8 +1,9 @@ // const vscode = require('vscode'); import * as vscode from 'vscode'; import { getNonce } from './getNonce'; +import { Tree } from './types/tree'; -export function createPanel(context, data) { +export function createPanel(context: vscode.ExtensionContext, data: Tree) { // if the current panel exists, then reveal the column, else make one? // utilize method on vscode.window object to create webview @@ -34,14 +35,13 @@ export function createPanel(context, data) { switch (msg.type) { case 'onData': if (!msg.value) break; - // context.workspaceState = context.workspaceState || {}; context.workspaceState.update('reactLabyrinth', msg.value); // console.log('msg.value from panel.js: ', msg.value); panel.webview.postMessage( { type: 'parsed-data', value: msg.value, // tree object - settings: await vscode.workspace.getConfiguration('reactLabyrinth') + settings: vscode.workspace.getConfiguration('reactLabyrinth') }); break; @@ -56,7 +56,7 @@ export function createPanel(context, data) { const nonce = getNonce(); // function to create the HTML page for webview -function createWebviewHTML(URI, initialData) { +function createWebviewHTML(URI: vscode.Uri, initialData: Tree) { return ( ` @@ -77,7 +77,7 @@ function createWebviewHTML(URI, initialData) { }); } - + ` diff --git a/src/parser.ts b/src/parser.ts index 6d3049f..51b740d 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -301,7 +301,7 @@ export class Parser { // helper function to determine component type (client) // input: ast.program.body // output: boolean - private getCallee(body): boolean { + private getCallee(body: { [key: string]: any }[]): boolean { const defaultErr = (err,) => { return { method: 'Error in getCallee method of Parser:', @@ -402,19 +402,19 @@ export class Parser { } // Finds JSX React Components in current file - private getJSXChildren(astTokens: any[], + private getJSXChildren( + astTokens: any[], importsObj: ImportObj, parentNode: Tree ): Tree[] { // let childNodes = {}; // let props = {}; // let token; - let childNodes: { [key: string]: Tree } = {}; + let childNodes: { [key: string]: Tree } = {}; let props: { [key: string]: boolean } = {}; let token: { [key: string]: any }; for (let i = 0; i < astTokens.length; i++) { - // Case for finding JSX tags eg if ( astTokens[i].type.label === 'jsxTagStart' && @@ -453,11 +453,11 @@ export class Parser { private getChildNodes( imports: ImportObj, - astToken: { [key: string]: any }, - props: { [key: string]: boolean }, - parent: Tree, - children: { [key: string]: Tree } - ): { [key: string]: Tree } { + astToken: { [key: string]: any }, + props: { [key: string]: boolean }, + parent: Tree, + children: { [key: string]: Tree } + ): { [key: string]: Tree } { if (children[astToken.value]) { children[astToken.value].count += 1; children[astToken.value].props = { diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index c7518ae..b2394aa 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -6,13 +6,14 @@ import ReactFlow, { Controls, Background, useNodesState, - useEdgesState + useEdgesState, + ReactFlowInstance } from "reactflow"; import "reactflow/dist/style.css"; import { ConnectionLineType } from "../types/connection"; import FlowBuilder from './flowBuilder'; -const onInit = (reactFlowInstance) => +const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); const OverviewFlow: React.FC = () => { diff --git a/src/webview/flowBuilder.tsx b/src/webview/flowBuilder.tsx index 9eeb533..9df9746 100644 --- a/src/webview/flowBuilder.tsx +++ b/src/webview/flowBuilder.tsx @@ -8,7 +8,7 @@ interface Node { label: React.ReactNode; }; type: string; - position: { x: number, y: number}; + position: { x: number, y: number }; style: { borderRadius: string; borderWidth: string; @@ -16,7 +16,7 @@ interface Node { display: string; justifyContent: string; placeItems: string; - backgroundColor: string; + backgroundColor: string; }; } @@ -43,13 +43,13 @@ interface Settings { class FlowBuilder { private parsedData: ParsedDataItem[]; + private viewData: ParsedDataItem[]; private id: number; private x: number; private y: number; - public initialNodes: Node[]; - private viewData: ParsedDataItem[]; private edgeId: number; public initialEdges: Edge[]; + public initialNodes: Node[]; constructor(data: ParsedDataItem) { this.parsedData = [data]; @@ -57,9 +57,9 @@ class FlowBuilder { this.x = 0; this.y = 0; this.initialNodes = []; + this.initialEdges = []; this.viewData = []; this.edgeId = 0; - this.initialEdges = []; } private buildNodesArray(parsedData: ParsedDataItem[] | undefined, x: number = this.x, y: number = this.y): void { From 5e5f8a0e37f4f9e91d698ba9f286e5f34767c019 Mon Sep 17 00:00:00 2001 From: ash-t-luu Date: Tue, 2 Jan 2024 20:01:15 -0800 Subject: [PATCH 05/25] changed javascript to typescript --- package.json | 5 ----- postcss.config.cjs | 1 - src/extension.ts | 2 -- src/getNonce.ts | 1 - src/panel.ts | 3 --- src/parser.ts | 22 +++------------------- src/webview/Flow.tsx | 4 +--- src/webview/flowBuilder.tsx | 2 +- webpack.config.ts | 32 -------------------------------- 9 files changed, 5 insertions(+), 67 deletions(-) diff --git a/package.json b/package.json index 54d124d..fbf98dd 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,6 @@ "main": "./build/extension.js", "contributes": { "commands": [ - { - "command": "react-labyrinth.helloWorld", - "title": "Hello World", - "category": "React Labyrinth" - }, { "command": "myExtension.showPanel", "title": "Show Panel", diff --git a/postcss.config.cjs b/postcss.config.cjs index b4d9371..df3813f 100644 --- a/postcss.config.cjs +++ b/postcss.config.cjs @@ -1,5 +1,4 @@ const tailwindcss = require('tailwindcss'); -// import * as tailwindcss from 'tailwindcss'; module.exports = { plugins: [ diff --git a/src/extension.ts b/src/extension.ts index 53e4fc5..0d034e6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,7 +1,5 @@ import * as vscode from 'vscode'; import {createPanel} from './panel'; -// const { createPanel } = require('./src/panel'); -// const { Parser } = require('./src/parser'); import { Parser } from './parser'; // This method is called when your extension is activated diff --git a/src/getNonce.ts b/src/getNonce.ts index 8231f28..dafd778 100644 --- a/src/getNonce.ts +++ b/src/getNonce.ts @@ -8,4 +8,3 @@ export function getNonce() { return text; } -// module.exports = { getNonce } \ No newline at end of file diff --git a/src/panel.ts b/src/panel.ts index 306bb23..606db1e 100644 --- a/src/panel.ts +++ b/src/panel.ts @@ -1,4 +1,3 @@ -// const vscode = require('vscode'); import * as vscode from 'vscode'; import { getNonce } from './getNonce'; import { Tree } from './types/tree'; @@ -83,5 +82,3 @@ function createWebviewHTML(URI: vscode.Uri, initialData: Tree) { ` ) } - -// module.exports = { createPanel }; \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts index 51b740d..0c068f1 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -1,14 +1,7 @@ -// const fs = require('fs') import * as fs from 'fs'; import * as path from 'path'; -// const path = require('path') -// const babel = require('@babel/parser'); import * as babel from '@babel/parser'; import { getNonce } from './getNonce'; -// const { getNonce } = require('./getNonce'); -// const { Tree } = require('./types/tree'); -// const { File } = require('@babel/types'); -// const ImportObj = require('./types/ImportObj') import { ImportObj } from './types/ImportObj'; import { Tree } from "./types/tree"; import { File } from '@babel/types'; @@ -164,7 +157,6 @@ export class Parser { // Recursively builds the React component tree structure starting from root node private parser(componentTree: Tree): Tree | undefined { - // console.log('componentTree:', componentTree); // If import is a node module, do not parse any deeper if (!['\\', '/', '.'].includes(componentTree.importPath[0])) { componentTree.thirdParty = true; @@ -180,7 +172,7 @@ export class Parser { // Check that file has valid fileName/Path, if not found, add error to node and halt const fileName = this.getFileName(componentTree); if (!fileName) { - componentTree.error = 'File not found.'; + componentTree.error = 'File not found'; return; } @@ -309,11 +301,8 @@ export class Parser { } }; - // console.log('ast.program.body', body); const bodyCallee = body.filter((item) => item.type === 'VariableDeclaration'); if (bodyCallee.length === 0) return false; - // console.log('bodyCallee', bodyCallee); - // console.log('bodyCallee.length', bodyCallee.length) const calleeHelper = (item) => { const hooksObj = { @@ -368,7 +357,6 @@ export class Parser { const calleeArr = bodyCallee[0].declarations[0]?.init?.body?.body; if (calleeArr === undefined) return false; - // console.log('calleArr:', calleeArr); let checkTrue = false; for (let i = 0; i < calleeArr.length; i++) { if (checkTrue) return true; @@ -382,7 +370,6 @@ export class Parser { try { if (bodyCallee[i].declarations[0]?.init?.body?.body) { calleeArr = bodyCallee[i].declarations[0].init.body.body; - // console.log('calleeArr from body', calleeArr); } } catch (err) { @@ -407,9 +394,7 @@ export class Parser { importsObj: ImportObj, parentNode: Tree ): Tree[] { - // let childNodes = {}; - // let props = {}; - // let token; + let childNodes: { [key: string]: Tree } = {}; let props: { [key: string]: boolean } = {}; let token: { [key: string]: any }; @@ -483,6 +468,7 @@ export class Parser { count: 1, props: props, children: [], + // consider adding the id to the parentList array somehow for D3 integration... parentList: [parent.filePath].concat(parent.parentList), error: '', isClientComponent: false @@ -540,5 +526,3 @@ export class Parser { return false; } } - -// module.exports = { Parser }; \ No newline at end of file diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index b2394aa..19d827c 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -16,7 +16,7 @@ import FlowBuilder from './flowBuilder'; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); -const OverviewFlow: React.FC = () => { +const OverviewFlow = () => { const initialNodes = []; const initialEdges = []; @@ -57,8 +57,6 @@ const OverviewFlow: React.FC = () => { { if (n.style?.backgroundColor) return n.style.backgroundColor; - // if (n.data.label.props.className.includes('orange')) return "#fdba74"; - // if (n.data.label.props.className.includes('blue')) return "#93C5FD"; if (n.type === "default") return "#1a192b"; return "#eee"; diff --git a/src/webview/flowBuilder.tsx b/src/webview/flowBuilder.tsx index 9df9746..1db07e8 100644 --- a/src/webview/flowBuilder.tsx +++ b/src/webview/flowBuilder.tsx @@ -116,7 +116,7 @@ class FlowBuilder { public build(settings: Settings): void { const treeParsed = JSON.parse(JSON.stringify(this.parsedData[0])); - console.log('settings: ', settings); + // console.log('settings: ', settings); const traverse = (node: ParsedDataItem): void => { let validChildren: ParsedDataItem[] = []; diff --git a/webpack.config.ts b/webpack.config.ts index 8cc8104..8694901 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -1,35 +1,3 @@ -// import * as path from 'path'; - -// module.exports = { -// entry: './src/webview/index.tsx', -// output: { -// filename: 'bundle.js', -// path: path.resolve(__dirname, './build'), -// }, -// resolve: { -// extensions: ['.js', '.ts', '.tsx', '.css'], -// }, -// module: { -// rules: [ -// // { -// // test: /\.jsx?/, -// // exclude: /node_modules/, -// // use: { -// // loader: "babel-loader", -// // options: { -// // presets: ['@babel/preset-env', '@babel/preset-react'] -// // } -// // } -// // }, -// { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, -// { -// test: /\.(css)$/, -// use: ["style-loader", "css-loader", "postcss-loader"], -// }, -// ] -// }, -// mode: "development" -// } import * as path from 'path'; import * as webpack from 'webpack'; From 33ceabf630656762790faf69209401580be9e81d Mon Sep 17 00:00:00 2001 From: Francisco Lopez Date: Wed, 3 Jan 2024 23:00:14 -0500 Subject: [PATCH 06/25] Was able to get the nodes to render on the screen using d3, still working on adding edges and getting the positioning of the nodes to represent a tree shape. --- package-lock.json | 334 +++++++++++++++++++++++++++++++++++- package.json | 1 + src/getNonce 2.js | 11 ++ src/parser.ts | 5 + src/treeTemplates/tree 2.js | 11 ++ src/types/hierarchyData.ts | 10 ++ src/types/tree.ts | 1 + src/webview/Flow.tsx | 67 +++++++- webpack.config 2.js | 32 ++++ 9 files changed, 462 insertions(+), 10 deletions(-) create mode 100644 src/getNonce 2.js create mode 100644 src/treeTemplates/tree 2.js create mode 100644 src/types/hierarchyData.ts create mode 100644 webpack.config 2.js diff --git a/package-lock.json b/package-lock.json index 2fe2a0b..c443ff2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", @@ -3440,13 +3441,13 @@ "version": "15.7.11", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", - "devOptional": true + "dev": true }, "node_modules/@types/react": { "version": "18.2.45", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", - "devOptional": true, + "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3466,7 +3467,7 @@ "version": "0.16.8", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", - "devOptional": true + "dev": true }, "node_modules/@types/vscode": { "version": "1.84.1", @@ -4486,7 +4487,92 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true + "dev": true + }, + "node_modules/d3": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } }, "node_modules/d3-color": { "version": "3.1.0", @@ -4496,6 +4582,28 @@ "node": ">=12" } }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-dispatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", @@ -4516,6 +4624,38 @@ "node": ">=12" } }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -4524,6 +4664,57 @@ "node": ">=12" } }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", @@ -4535,6 +4726,65 @@ "node": ">=12" } }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-selection": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", @@ -4543,6 +4793,39 @@ "node": ">=12" } }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-timer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", @@ -4618,6 +4901,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -5236,6 +5527,17 @@ "node": ">= 6" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -5386,6 +5688,14 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -7501,6 +7811,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7524,11 +7839,21 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sass-loader": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", @@ -8109,6 +8434,7 @@ "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index fbf98dd..a455535 100644 --- a/package.json +++ b/package.json @@ -98,6 +98,7 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", diff --git a/src/getNonce 2.js b/src/getNonce 2.js new file mode 100644 index 0000000..bd01ad0 --- /dev/null +++ b/src/getNonce 2.js @@ -0,0 +1,11 @@ +function getNonce() { + let text = ""; + const possible = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + for (let i = 0; i < 32; i++) { + text += possible.charAt(Math.floor(Math.random() * possible.length)); + } + return text; + } + +module.exports = { getNonce } \ No newline at end of file diff --git a/src/parser.ts b/src/parser.ts index 0c068f1..f16d5d1 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -71,6 +71,7 @@ export class Parser { reactRouter: false, reduxConnect: false, children: [], + parent: null, parentList: [], props: {}, error: '', @@ -180,6 +181,9 @@ export class Parser { if (componentTree.parentList.includes(componentTree.filePath)) { return; } + // if (typeof componentTree.parentList === 'string' && componentTree.parentList.includes(componentTree.filePath)) { + // return; + // } // Create abstract syntax tree of current component tree file let ast: babel.ParseResult; @@ -468,6 +472,7 @@ export class Parser { count: 1, props: props, children: [], + parent: parent.id, // consider adding the id to the parentList array somehow for D3 integration... parentList: [parent.filePath].concat(parent.parentList), error: '', diff --git a/src/treeTemplates/tree 2.js b/src/treeTemplates/tree 2.js new file mode 100644 index 0000000..ae488b7 --- /dev/null +++ b/src/treeTemplates/tree 2.js @@ -0,0 +1,11 @@ +const Tree = { + id: undefined, + fileName: undefined, + filePath: undefined, + // children & parentList should be populated with other Tree objects + children: [], + parentList: [], + isClientComponent: false +} + +module.exports = { Tree }; \ No newline at end of file diff --git a/src/types/hierarchyData.ts b/src/types/hierarchyData.ts new file mode 100644 index 0000000..fe3bb80 --- /dev/null +++ b/src/types/hierarchyData.ts @@ -0,0 +1,10 @@ +import { Tree } from "./tree" + + +export interface hierarchyData { + children?: hierarchyData[], + data: Tree, + depth: number, + height: number, + parent: hierarchyData | null +} \ No newline at end of file diff --git a/src/types/tree.ts b/src/types/tree.ts index 5b6eb7a..03506cb 100644 --- a/src/types/tree.ts +++ b/src/types/tree.ts @@ -11,6 +11,7 @@ export type Tree = { reactRouter: boolean; reduxConnect: boolean; children: Tree[]; + parent: string; parentList: string[]; props: { [key: string]: boolean; }; error: string; diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 19d827c..7ceba22 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useCallback, useEffect, useRef } from "react"; import ReactFlow, { addEdge, MiniMap, @@ -12,13 +12,19 @@ import ReactFlow, { import "reactflow/dist/style.css"; import { ConnectionLineType } from "../types/connection"; import FlowBuilder from './flowBuilder'; +import * as d3 from 'd3'; +import { Tree } from "../types/tree"; +import { hierarchyData } from "../types/hierarchyData"; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); const OverviewFlow = () => { + const reactFlowWrapper = useRef(null); const initialNodes = []; const initialEdges = []; + const elements = []; + const edge = []; const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); @@ -33,26 +39,74 @@ const OverviewFlow = () => { const msg = e.data; // object containing type prop and value prop switch (msg.type) { case 'parsed-data': { - const results = new FlowBuilder(msg.value); - results.build(msg.settings) - setNodes(results.initialNodes); - setEdges(results.initialEdges); + // const results = new FlowBuilder(msg.value); + // results.build(msg.settings) + let data : object | undefined = msg.value; + console.log('data', data) + // setNodes(results.initialNodes); + // setEdges(results.initialEdges); + + // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + const root : any = d3.hierarchy(data) + console.log('root', root) + + + //create tree layout and give nodes their positions + const treeLayout = d3.tree() + treeLayout(root); + + root.each((node: any) : void => { + // console.log('node name',Object.keys(node)) + elements.push({ + id: node.data.name, + type: 'default', + data: { label: node.data.name }, + position: { x: node.x || 0, y: node.y || 0 }, + }); + + // figure out how to get edges to connect + if (node.data.parent) { + // elements.push(addEdge({ + // id: node.data.id, + // source: node.data.id, + // target: node.data.parent, + // // sourceHandle: null, + // // targetHandle: null, + // })) + } + }) break; } } }); + + setNodes(elements); + + //Rendering reactFlow + if (reactFlowWrapper.current) { + // Set initial position for the nodes + const initialPosition = { x: 0, y: 0 }; + // reactFlowWrapper.current?.fitView(initialPosition); + } + // assign root variable using d3.heirarchy(data[0]), this will use d3 to format our data in a easy way to visualize the heirarchy + // const elements: Tree[]; + }, []); return ( +
{ @@ -80,6 +134,7 @@ const OverviewFlow = () => { +
); }; diff --git a/webpack.config 2.js b/webpack.config 2.js new file mode 100644 index 0000000..f926942 --- /dev/null +++ b/webpack.config 2.js @@ -0,0 +1,32 @@ +const path = require('path') + + +module.exports = { +entry: './src/webview/index.jsx', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, './build'), + }, + resolve: { + extensions: ['.js', '.jsx', '.css'], + }, + module: { + rules: [ + { + test: /\.jsx?/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + options: { + presets: ['@babel/preset-env', '@babel/preset-react'] + } + } + }, + { + test: /\.(scss|css)$/, + use: ["style-loader", "css-loader"], + }, + ] + }, + mode: "development" +} From 316dcb19f5323f0c70176eb9e8a5e195c9f3c2ef Mon Sep 17 00:00:00 2001 From: ChristinaRaether Date: Thu, 4 Jan 2024 15:33:54 -0800 Subject: [PATCH 07/25] testing first pass --- .gitignore | 3 ++- .vscode/launch.json | 5 ++++- package-lock.json | 17 +++++++++++++++++ package.json | 4 +++- test/runTest.js => src/test/runTest.ts | 6 +++--- .../test/suite/extension.test.ts | 7 ++++--- test/suite/index.js => src/test/suite/index.ts | 13 +++++-------- tsconfig.json | 2 +- 8 files changed, 39 insertions(+), 18 deletions(-) rename test/runTest.js => src/test/runTest.ts (77%) rename test/suite/extension.test.js => src/test/suite/extension.test.ts (65%) rename test/suite/index.js => src/test/suite/index.ts (75%) diff --git a/.gitignore b/.gitignore index 05d2dd7..6563919 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules /build -/package-lock.json \ No newline at end of file +/package-lock.json +/.vscode-test/ \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c774552..f3c3931 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,6 +5,7 @@ { "version": "0.2.0", "configurations": [ + { "name": "Run Extension", "type": "extensionHost", @@ -20,7 +21,9 @@ "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/test/suite/index" - ] + ], + "outFiles": ["${workspaceFolder}/build/*.js"], + "preLaunchTask": "npm: test-compile" } ] } diff --git a/package-lock.json b/package-lock.json index 2fe2a0b..98c03bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,6 +25,7 @@ "webpack": "^5.89.0" }, "devDependencies": { + "@types/glob": "^8.1.0", "@types/mocha": "^10.0.3", "@types/node": "18.x", "@types/react": "^18.2.45", @@ -3417,11 +3418,27 @@ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==" }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, "node_modules/@types/mocha": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.4.tgz", diff --git a/package.json b/package.json index fbf98dd..11e1b6a 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "pricing": "Free", "activationEvents": [], "main": "./build/extension.js", + "type": "module", "contributes": { "commands": [ { @@ -70,11 +71,12 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "node ./test/runTest.js", + "test": "node ./src/test/runTest.ts", "dev": "webpack --watch", "webpack": "webpack" }, "devDependencies": { + "@types/glob": "^8.1.0", "@types/mocha": "^10.0.3", "@types/node": "18.x", "@types/react": "^18.2.45", diff --git a/test/runTest.js b/src/test/runTest.ts similarity index 77% rename from test/runTest.js rename to src/test/runTest.ts index 570e697..6f1b600 100644 --- a/test/runTest.js +++ b/src/test/runTest.ts @@ -1,12 +1,12 @@ -const path = require('path'); +import * as path from 'path'; -const { runTests } = require('@vscode/test-electron'); +import { runTests } from '@vscode/test-electron'; async function main() { try { // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../'); + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); // The path to the extension test script // Passed to --extensionTestsPath diff --git a/test/suite/extension.test.js b/src/test/suite/extension.test.ts similarity index 65% rename from test/suite/extension.test.js rename to src/test/suite/extension.test.ts index 69ead83..fc20674 100644 --- a/test/suite/extension.test.js +++ b/src/test/suite/extension.test.ts @@ -1,15 +1,16 @@ -const assert = require('assert'); +import * as assert from 'assert' // You can import and use all API from the 'vscode' module // as well as import your extension to test it -const vscode = require('vscode'); +import * as vscode from 'vscode' // const myExtension = require('../extension'); suite('Extension Test Suite', () => { vscode.window.showInformationMessage('Start all tests.'); test('Sample test', () => { - assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); // false assert.strictEqual(-1, [1, 2, 3].indexOf(0)); + assert.strictEqual(0, [1, 2, 3].indexOf(1)); // true }); }); diff --git a/test/suite/index.js b/src/test/suite/index.ts similarity index 75% rename from test/suite/index.js rename to src/test/suite/index.ts index 757fe1a..da70745 100644 --- a/test/suite/index.js +++ b/src/test/suite/index.ts @@ -1,10 +1,10 @@ -const path = require('path'); -const Mocha = require('mocha'); -const glob = require('glob'); +import * as path from 'path'; +import * as Mocha from 'mocha'; +import { glob } from 'glob'; -async function run() { +export async function run(): Promise { // Create the mocha test - const mocha = new Mocha({ + const mocha = new Mocha.default({ ui: 'tdd', color: true }); @@ -31,6 +31,3 @@ async function run() { } } -module.exports = { - run -}; diff --git a/tsconfig.json b/tsconfig.json index d381c8c..5d6a22e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,7 @@ "strict": false, }, // "include": ["src", "src/types/index.d.ts"], - "include": ["src/**/*.ts", "src/**/*.tsx"], + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/**/*.tsx", "src/**/**/*.ts"], "exclude": [ "node_modules", ".vscode-test", From f0befbdd4136779d9b904aecccb8c313680fdd1a Mon Sep 17 00:00:00 2001 From: Louis Kuczykowski Date: Thu, 4 Jan 2024 20:44:58 -0500 Subject: [PATCH 08/25] A single typo was causing the bug in ticket RL-27. Fixed the typo and works as intended --- src/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/parser.ts b/src/parser.ts index 0c068f1..050e89b 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -419,7 +419,7 @@ export class Parser { // Case for finding components passed in as props e.g. } else if ( astTokens[i].type.label === 'jsxName' && - (astTokens[i].value === 'component' || + (astTokens[i].value === 'Component' || astTokens[i].value === 'children') && importsObj[astTokens[i + 3].value] ) { From 8a4efe2f133deb52c40e9c86f713fdc13feb145c Mon Sep 17 00:00:00 2001 From: ChristinaRaether Date: Thu, 4 Jan 2024 19:34:14 -0800 Subject: [PATCH 09/25] testing day 2 --- .vscode-test.js | 9 +++ .vscode/settings.json | 3 + .vscodeignore | 1 + package-lock.json | 141 ++++++++++++++++++++++++++++++++++++++++-- package.json | 7 ++- src/test/runTest.ts | 6 ++ tsconfig.json | 4 +- 7 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 .vscode-test.js create mode 100644 .vscode/settings.json diff --git a/.vscode-test.js b/.vscode-test.js new file mode 100644 index 0000000..ecde832 --- /dev/null +++ b/.vscode-test.js @@ -0,0 +1,9 @@ +// .vscode-test.js +const { defineConfig } = require('@vscode/test-cli'); + +module.exports = defineConfig([ + { + label: 'unitTests', + files: 'build/src/test/**/*.test.js', + } +]); \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cad7657 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index a775644..a5b7de8 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -7,3 +7,4 @@ vsc-extension-quickstart.md **/jsconfig.json **/*.map **/.eslintrc.json +**/*.js.map diff --git a/package-lock.json b/package-lock.json index 98c03bf..6be480f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,8 @@ "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", - "@vscode/test-electron": "^2.3.6", + "@vscode/test-cli": "^0.0.4", + "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", "glob": "^10.3.10", "mocha": "^10.2.0", @@ -3497,10 +3498,142 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vscode/test-cli": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.4.tgz", + "integrity": "sha512-Tx0tfbxeSb2Xlo+jpd+GJrNLgKQHobhRHrYvOipZRZQYWZ82sKiK02VY09UjU1Czc/YnZnqyAnjUfaVGl3h09w==", + "dev": true, + "dependencies": { + "@types/mocha": "^10.0.2", + "chokidar": "^3.5.3", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^10.2.0", + "supports-color": "^9.4.0", + "yargs": "^17.7.2" + }, + "bin": { + "vscode-test": "out/bin.mjs" + } + }, + "node_modules/@vscode/test-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vscode/test-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vscode/test-cli/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/@vscode/test-cli/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@vscode/test-cli/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vscode/test-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@vscode/test-electron": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.6.tgz", - "integrity": "sha512-M31xGH0RgqNU6CZ4/9g39oUMJ99nLzfjA+4UbtIQ6TcXQ6+2qkjOOxedmPBDDCg26/3Al5ubjY80hIoaMwKYSw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz", + "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==", "dev": true, "dependencies": { "http-proxy-agent": "^4.0.1", diff --git a/package.json b/package.json index 11e1b6a..dc44640 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "pricing": "Free", "activationEvents": [], "main": "./build/extension.js", - "type": "module", "contributes": { "commands": [ { @@ -71,7 +70,8 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "node ./src/test/runTest.ts", + "test": "node ./build/src/test/runTest.js", + "test1": "vscode-test", "dev": "webpack --watch", "webpack": "webpack" }, @@ -82,7 +82,8 @@ "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", - "@vscode/test-electron": "^2.3.6", + "@vscode/test-cli": "^0.0.4", + "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", "glob": "^10.3.10", "mocha": "^10.2.0", diff --git a/src/test/runTest.ts b/src/test/runTest.ts index 6f1b600..d673170 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -3,15 +3,21 @@ import * as path from 'path'; import { runTests } from '@vscode/test-electron'; async function main() { + console.log('made it through the line before try block'); try { + console.log('inside try block'); // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + console.log('inside try block after first var declare'); + // The path to the extension test script // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, './suite/index'); + console.log('inside try block after second var declare'); + // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, extensionTestsPath }); } catch (err) { diff --git a/tsconfig.json b/tsconfig.json index 5d6a22e..6c608c6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,9 @@ "allowJs": true, "strict": false, }, - // "include": ["src", "src/types/index.d.ts"], + "tsnode": { + "esm": true + }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/**/*.tsx", "src/**/**/*.ts"], "exclude": [ "node_modules", From b1914fda56ba9618fc1d2ebeaa0119885cf41c65 Mon Sep 17 00:00:00 2001 From: Francisco Lopez Date: Thu, 4 Jan 2024 23:07:42 -0500 Subject: [PATCH 10/25] Got the nodes to render as a tree structure using D3. Need to get the edges to connect upon rendering to finish the tree. --- src/webview/Flow.tsx | 53 +++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 7ceba22..7859ebb 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -15,6 +15,7 @@ import FlowBuilder from './flowBuilder'; import * as d3 from 'd3'; import { Tree } from "../types/tree"; import { hierarchyData } from "../types/hierarchyData"; +import { getNonce } from "../getNonce"; const onInit = (reactFlowInstance: ReactFlowInstance) => console.log("flow loaded:", reactFlowInstance); @@ -24,7 +25,7 @@ const OverviewFlow = () => { const initialNodes = []; const initialEdges = []; const elements = []; - const edge = []; + const edgeArr = []; const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); @@ -52,7 +53,7 @@ const OverviewFlow = () => { //create tree layout and give nodes their positions - const treeLayout = d3.tree() + const treeLayout = d3.tree().size([500, 300]) treeLayout(root); root.each((node: any) : void => { @@ -61,25 +62,51 @@ const OverviewFlow = () => { id: node.data.name, type: 'default', data: { label: node.data.name }, - position: { x: node.x || 0, y: node.y || 0 }, + position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, + style: { + borderRadius: '6px', + borderWidth: '2px', + borderColor: '#6b7280', + display: 'flex', + justifyContent: 'center', + placeItems: 'center', + backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, + } }); // figure out how to get edges to connect if (node.data.parent) { - // elements.push(addEdge({ - // id: node.data.id, - // source: node.data.id, - // target: node.data.parent, - // // sourceHandle: null, - // // targetHandle: null, - // })) + const newEdge = { + id: `${getNonce()}`, + source: node.data.parent, + target: node.data.id, + type: ConnectionLineType.Bezier, + animated: true + }; + + // Check if the edge already exists before adding + const edgeExists = edgeArr.some( + edge => edge[0].source === newEdge.source && edge[0].target === newEdge.target + ); + + if (!edgeExists) { + initialEdges.push(newEdge); + } } - }) + } + ) + console.log('Initial Edges', initialEdges) + setEdges(initialEdges) + console.log('Edges', edges) break; } } + + }); + + setNodes(elements); //Rendering reactFlow @@ -97,9 +124,9 @@ const OverviewFlow = () => {
Date: Sat, 6 Jan 2024 11:13:49 -0800 Subject: [PATCH 11/25] updating version --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6be480f..c299a70 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3487,9 +3487,9 @@ "devOptional": true }, "node_modules/@types/vscode": { - "version": "1.84.1", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.1.tgz", - "integrity": "sha512-DB10vBRLEPA/us7p3gQilU2Tq5HDu6JWTyCpD9qtb7MKWIvJS5In9HU3YgVGCXf/miwHJiY62aXwjtUSMpT8HA==", + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.85.0.tgz", + "integrity": "sha512-CF/RBon/GXwdfmnjZj0WTUMZN5H6YITOfBCP4iEZlOtVQXuzw6t7Le7+cR+7JzdMrnlm7Mfp49Oj2TuSXIWo3g==", "dev": true }, "node_modules/@ungap/structured-clone": { diff --git a/package.json b/package.json index dc44640..bd36d90 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@types/node": "18.x", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", - "@types/vscode": "^1.84.0", + "@types/vscode": "^1.85.1", "@vscode/test-cli": "^0.0.4", "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", From 9ec967c0c58692909e90192a04eb4e4d801ab23f Mon Sep 17 00:00:00 2001 From: ChristinaRaether Date: Sat, 6 Jan 2024 11:40:04 -0800 Subject: [PATCH 12/25] working test --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index c299a70..ae58973 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "@types/node": "18.x", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", - "@types/vscode": "^1.84.0", + "@types/vscode": "^1.85.1", "@vscode/test-cli": "^0.0.4", "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", @@ -43,7 +43,7 @@ "webpack-cli": "^5.1.4" }, "engines": { - "vscode": "^1.84.0" + "vscode": "^1.85.1" } }, "node_modules/@aashutoshrathi/word-wrap": { diff --git a/package.json b/package.json index bd36d90..f30dd08 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "version": "0.0.1", "publisher": "ReactLabyrinthDev", "engines": { - "vscode": "^1.84.0" + "vscode": "^1.85.1" }, "repository": { "type": "git", From 8b8c34da2ef9266dfc4b26bcb42d7836eff19d19 Mon Sep 17 00:00:00 2001 From: Francisco Lopez Date: Sat, 6 Jan 2024 16:07:25 -0500 Subject: [PATCH 13/25] Got the React Flow diagram working --- src/webview/Flow.tsx | 151 ++++++++++++++++++++++++------------------- 1 file changed, 85 insertions(+), 66 deletions(-) diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx index 7859ebb..40bed50 100644 --- a/src/webview/Flow.tsx +++ b/src/webview/Flow.tsx @@ -24,17 +24,35 @@ const OverviewFlow = () => { const reactFlowWrapper = useRef(null); const initialNodes = []; const initialEdges = []; + const initialEdge = []; const elements = []; - const edgeArr = []; + // const elementsRef = useRef(elements); + // const edgesRef = useRef(initialEdges) - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); + const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); const onConnect = useCallback( (params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)), [] ); + // const memoizedOnNodesChange = useCallback( + // (newNodes) => { + // setNodes(newNodes); + // elementsRef.current = newNodes; + // }, + // [setNodes] + // ); + + // const memoizedOnEdgesChange = useCallback( + // (newEdges) => { + // setEdges(newEdges); + // edgesRef.current = newEdges + // }, + // [setEdges] + // ); + useEffect(() => { window.addEventListener('message', (e) => { const msg = e.data; // object containing type prop and value prop @@ -42,72 +60,24 @@ const OverviewFlow = () => { case 'parsed-data': { // const results = new FlowBuilder(msg.value); // results.build(msg.settings) - let data : object | undefined = msg.value; - console.log('data', data) // setNodes(results.initialNodes); // setEdges(results.initialEdges); - - // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees - const root : any = d3.hierarchy(data) - console.log('root', root) - - - //create tree layout and give nodes their positions - const treeLayout = d3.tree().size([500, 300]) - treeLayout(root); - - root.each((node: any) : void => { - // console.log('node name',Object.keys(node)) - elements.push({ - id: node.data.name, - type: 'default', - data: { label: node.data.name }, - position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, - style: { - borderRadius: '6px', - borderWidth: '2px', - borderColor: '#6b7280', - display: 'flex', - justifyContent: 'center', - placeItems: 'center', - backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, - } - }); - - // figure out how to get edges to connect - if (node.data.parent) { - const newEdge = { - id: `${getNonce()}`, - source: node.data.parent, - target: node.data.id, - type: ConnectionLineType.Bezier, - animated: true - }; - - // Check if the edge already exists before adding - const edgeExists = edgeArr.some( - edge => edge[0].source === newEdge.source && edge[0].target === newEdge.target - ); - - if (!edgeExists) { - initialEdges.push(newEdge); - } - } - } - ) - console.log('Initial Edges', initialEdges) - setEdges(initialEdges) - console.log('Edges', edges) + let data : object | undefined = msg.value; + console.log('data', data) + mappedData(data) + console.log('nodes', elements) + setEdges(initialEdges); + setNodes(elements) + console.log('edges: ', edges); break; } } - - }); - - - setNodes(elements); + + + // memoizedOnEdgesChange(edgesRef.current); + // memoizedOnNodesChange(elementsRef.current); //Rendering reactFlow if (reactFlowWrapper.current) { @@ -115,17 +85,66 @@ const OverviewFlow = () => { const initialPosition = { x: 0, y: 0 }; // reactFlowWrapper.current?.fitView(initialPosition); } - // assign root variable using d3.heirarchy(data[0]), this will use d3 to format our data in a easy way to visualize the heirarchy - // const elements: Tree[]; }, []); + function mappedData (data) { + // create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + const root : any = d3.hierarchy(data) + console.log('root', root) + + + //create tree layout and give nodes their positions + const treeLayout = d3.tree().size([800, 500]) + treeLayout(root); + + root.each((node: any) : void => { + + elements.push({ + id: node.data.id, + type: 'default', + data: { label: node.data.name }, + position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, + style: { + borderRadius: '6px', + borderWidth: '2px', + borderColor: '#6b7280', + display: 'flex', + justifyContent: 'center', + placeItems: 'center', + backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, + } + }); + + // figure out how to get edges to connect + if (node.data.parent) { + const newEdge = { + id: `${getNonce()}`, + source: node.data.parent, + target: node.data.id, + type: ConnectionLineType.Bezier, + animated: true, + }; + + + // Check if the edge already exists before adding + const edgeExists = initialEdges.some( + edge => edge.source === newEdge.source && edge.target === newEdge.target + ); + + if (!edgeExists) { + initialEdges.push(newEdge) + } + } + } + ) + + } + return (
Date: Sat, 6 Jan 2024 13:17:38 -0800 Subject: [PATCH 14/25] took build out of gitignore --- .gitignore | 1 - build/bundle.js | 378 +++++++++++++++++ build/extension.js | 128 ++++++ build/src/extension.js | 69 ++++ build/src/extension.js.map | 1 + build/src/getNonce.js | 13 + build/src/getNonce.js.map | 1 + build/src/panel.js | 100 +++++ build/src/panel.js.map | 1 + build/src/parser.js | 458 +++++++++++++++++++++ build/src/parser.js.map | 1 + build/src/test/runTest.js | 56 +++ build/src/test/runTest.js.map | 1 + build/src/test/suite/extension.test.js | 39 ++ build/src/test/suite/extension.test.js.map | 1 + build/src/test/suite/index.js | 69 ++++ build/src/test/suite/index.js.map | 1 + build/src/types/ImportObj.js | 3 + build/src/types/ImportObj.js.map | 1 + build/src/types/builder.js | 3 + build/src/types/builder.js.map | 1 + build/src/types/connection.js | 12 + build/src/types/connection.js.map | 1 + build/src/types/tree.js | 3 + build/src/types/tree.js.map | 1 + build/src/webview/App.js | 14 + build/src/webview/App.js.map | 1 + build/src/webview/Flow.js | 83 ++++ build/src/webview/Flow.js.map | 1 + build/src/webview/flowBuilder.js | 102 +++++ build/src/webview/flowBuilder.js.map | 1 + build/src/webview/index.js | 14 + build/src/webview/index.js.map | 1 + 33 files changed, 1559 insertions(+), 1 deletion(-) create mode 100644 build/bundle.js create mode 100644 build/extension.js create mode 100644 build/src/extension.js create mode 100644 build/src/extension.js.map create mode 100644 build/src/getNonce.js create mode 100644 build/src/getNonce.js.map create mode 100644 build/src/panel.js create mode 100644 build/src/panel.js.map create mode 100644 build/src/parser.js create mode 100644 build/src/parser.js.map create mode 100644 build/src/test/runTest.js create mode 100644 build/src/test/runTest.js.map create mode 100644 build/src/test/suite/extension.test.js create mode 100644 build/src/test/suite/extension.test.js.map create mode 100644 build/src/test/suite/index.js create mode 100644 build/src/test/suite/index.js.map create mode 100644 build/src/types/ImportObj.js create mode 100644 build/src/types/ImportObj.js.map create mode 100644 build/src/types/builder.js create mode 100644 build/src/types/builder.js.map create mode 100644 build/src/types/connection.js create mode 100644 build/src/types/connection.js.map create mode 100644 build/src/types/tree.js create mode 100644 build/src/types/tree.js.map create mode 100644 build/src/webview/App.js create mode 100644 build/src/webview/App.js.map create mode 100644 build/src/webview/Flow.js create mode 100644 build/src/webview/Flow.js.map create mode 100644 build/src/webview/flowBuilder.js create mode 100644 build/src/webview/flowBuilder.js.map create mode 100644 build/src/webview/index.js create mode 100644 build/src/webview/index.js.map diff --git a/.gitignore b/.gitignore index 6563919..52d1852 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ node_modules -/build /package-lock.json /.vscode-test/ \ No newline at end of file diff --git a/build/bundle.js b/build/bundle.js new file mode 100644 index 0000000..5489dd7 --- /dev/null +++ b/build/bundle.js @@ -0,0 +1,378 @@ +/* + * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). + * This devtool is neither made for production nor for readable output files. + * It uses "eval()" calls to create a separate source file in the browser devtools. + * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) + * or disable the default devtool with "devtool: false". + * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). + */ +/******/ (() => { // webpackBootstrap +/******/ var __webpack_modules__ = ({ + +/***/ "./src/types/connection.ts": +/*!*********************************!*\ + !*** ./src/types/connection.ts ***! + \*********************************/ +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; +eval("\n\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nexports.ConnectionLineType = void 0;\nvar ConnectionLineType;\n(function (ConnectionLineType) {\n ConnectionLineType[\"Bezier\"] = \"default\";\n ConnectionLineType[\"Straight\"] = \"straight\";\n ConnectionLineType[\"Step\"] = \"step\";\n ConnectionLineType[\"SmoothStep\"] = \"smoothstep\";\n ConnectionLineType[\"SimpleBezier\"] = \"simplebezier\";\n})(ConnectionLineType || (exports.ConnectionLineType = ConnectionLineType = {}));\n\n//# sourceURL=webpack://react-labyrinth/./src/types/connection.ts?"); + +/***/ }), + +/***/ "./src/webview/App.tsx": +/*!*****************************!*\ + !*** ./src/webview/App.tsx ***! + \*****************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nconst react_1 = __importDefault(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\nconst Flow_1 = __importDefault(__webpack_require__(/*! ./Flow */ \"./src/webview/Flow.tsx\"));\n__webpack_require__(/*! ./style.css */ \"./src/webview/style.css\");\nfunction App() {\n return react_1.default.createElement(\"div\", {\n className: \"App\"\n }, react_1.default.createElement(Flow_1.default, null));\n}\nexports[\"default\"] = App;\n\n//# sourceURL=webpack://react-labyrinth/./src/webview/App.tsx?"); + +/***/ }), + +/***/ "./src/webview/Flow.tsx": +/*!******************************!*\ + !*** ./src/webview/Flow.tsx ***! + \******************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nvar __createBinding = this && this.__createBinding || (Object.create ? function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = {\n enumerable: true,\n get: function () {\n return m[k];\n }\n };\n }\n Object.defineProperty(o, k2, desc);\n} : function (o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n});\nvar __setModuleDefault = this && this.__setModuleDefault || (Object.create ? function (o, v) {\n Object.defineProperty(o, \"default\", {\n enumerable: true,\n value: v\n });\n} : function (o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = this && this.__importStar || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nconst react_1 = __importStar(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\nconst reactflow_1 = __importStar(__webpack_require__(/*! reactflow */ \"./node_modules/reactflow/dist/umd/index.js\"));\n__webpack_require__(/*! reactflow/dist/style.css */ \"./node_modules/reactflow/dist/style.css\");\nconst connection_1 = __webpack_require__(/*! ../types/connection */ \"./src/types/connection.ts\");\nconst flowBuilder_1 = __importDefault(__webpack_require__(/*! ./flowBuilder */ \"./src/webview/flowBuilder.tsx\"));\nconst onInit = reactFlowInstance => console.log(\"flow loaded:\", reactFlowInstance);\nconst OverviewFlow = () => {\n const initialNodes = [];\n const initialEdges = [];\n const [nodes, setNodes, onNodesChange] = (0, reactflow_1.useNodesState)(initialNodes);\n const [edges, setEdges, onEdgesChange] = (0, reactflow_1.useEdgesState)(initialEdges);\n const onConnect = (0, react_1.useCallback)(params => setEdges(eds => (0, reactflow_1.addEdge)(Object.assign(Object.assign({}, params), {\n type: connection_1.ConnectionLineType.Bezier,\n animated: true\n }), eds)), []);\n (0, react_1.useEffect)(() => {\n window.addEventListener('message', e => {\n const msg = e.data; // object containing type prop and value prop\n switch (msg.type) {\n case 'parsed-data':\n {\n const results = new flowBuilder_1.default(msg.value);\n results.build(msg.settings);\n setNodes(results.initialNodes);\n setEdges(results.initialEdges);\n break;\n }\n }\n });\n }, []);\n return react_1.default.createElement(reactflow_1.default, {\n nodes: nodes,\n edges: edges,\n onNodesChange: onNodesChange,\n onEdgesChange: onEdgesChange,\n onConnect: onConnect,\n onInit: onInit,\n fitView: true,\n attributionPosition: \"top-right\"\n }, react_1.default.createElement(reactflow_1.MiniMap, {\n nodeStrokeColor: n => {\n var _a;\n if ((_a = n.style) === null || _a === void 0 ? void 0 : _a.backgroundColor) return n.style.backgroundColor;\n if (n.type === \"default\") return \"#1a192b\";\n return \"#eee\";\n },\n nodeColor: n => {\n var _a;\n if ((_a = n.style) === null || _a === void 0 ? void 0 : _a.backgroundColor) return n.style.backgroundColor;\n return \"#fff\";\n },\n nodeBorderRadius: 2\n }), react_1.default.createElement(reactflow_1.Panel, {\n position: \"top-left\"\n }, react_1.default.createElement(\"div\", {\n className: \"text-black\"\n }, react_1.default.createElement(\"div\", {\n className: \"flex justify-end place-items-end shadow-lg bg-slate-50 w-20 h-15\"\n }, react_1.default.createElement(\"p\", {\n className: \"pl-2 pr-2 py-2\"\n }, \"Client: \", react_1.default.createElement(\"span\", {\n className: \"bg-orange text-transparent rounded-full\"\n }, \"00\"))), react_1.default.createElement(\"div\", {\n className: \"flex justify-end place-items-end shadow-lg bg-slate-50 w-20 h-15\"\n }, react_1.default.createElement(\"p\", {\n className: \"pl-2 pr-2 pb-2\"\n }, \"Server: \", react_1.default.createElement(\"span\", {\n className: \"bg-blue text-transparent rounded-full\"\n }, \"00\"))))), react_1.default.createElement(reactflow_1.Controls, null), react_1.default.createElement(reactflow_1.Background, {\n color: \"#aaa\",\n gap: 16\n }));\n};\nexports[\"default\"] = OverviewFlow;\n\n//# sourceURL=webpack://react-labyrinth/./src/webview/Flow.tsx?"); + +/***/ }), + +/***/ "./src/webview/flowBuilder.tsx": +/*!*************************************!*\ + !*** ./src/webview/flowBuilder.tsx ***! + \*************************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nconst react_1 = __importDefault(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\nclass FlowBuilder {\n constructor(data) {\n this.parsedData = [data];\n this.id = 0;\n this.x = 0;\n this.y = 0;\n this.initialNodes = [];\n this.initialEdges = [];\n this.viewData = [];\n this.edgeId = 0;\n }\n buildNodesArray(parsedData, x = this.x, y = this.y) {\n if (!parsedData) return;\n parsedData.forEach(item => {\n const node = {\n id: (++this.id).toString(),\n data: {\n label: react_1.default.createElement(\"div\", {\n className: \"text-sm font-medium text-ellipsis overflow-hidden ...\",\n key: this.id\n }, item.fileName)\n },\n // type: item.depth === 0 ? 'input' : '',\n type: 'default',\n position: {\n x: x += 40,\n y: y += 30\n },\n style: {\n borderRadius: '6px',\n borderWidth: '2px',\n borderColor: '#6b7280',\n display: 'flex',\n justifyContent: 'center',\n placeItems: 'center',\n backgroundColor: `${item.isClientComponent ? '#fdba74' : '#93C5FD'}`\n }\n };\n this.initialNodes.push(node);\n if (item.children) {\n this.buildNodesArray(item.children, this.x += 40, this.y += 30);\n }\n });\n }\n buildEdgesArray(parsedData, parentID) {\n if (!parsedData) return;\n parsedData.forEach(item => {\n const nodeID = ++this.edgeId;\n if (parentID) {\n const edge = {\n id: `e${parentID}-${nodeID}`,\n source: parentID.toString(),\n target: nodeID.toString(),\n type: 'bezier',\n animated: false\n };\n this.initialEdges.push(edge);\n }\n if (item.children) {\n this.buildEdgesArray(item.children, nodeID);\n }\n });\n }\n build(settings) {\n const treeParsed = JSON.parse(JSON.stringify(this.parsedData[0]));\n // console.log('settings: ', settings);\n const traverse = node => {\n var _a;\n let validChildren = [];\n for (let i = 0; i < ((_a = node.children) === null || _a === void 0 ? void 0 : _a.length); i++) {\n if (node.children[i].thirdParty && settings.thirdParty && !node.children[i].reactRouter) {\n validChildren.push(node.children[i]);\n } else if (node.children[i].reactRouter && settings.reactRouter) {\n validChildren.push(node.children[i]);\n } else if (!node.children[i].thirdParty && !node.children[i].reactRouter) {\n validChildren.push(node.children[i]);\n }\n }\n // Update children with only valid nodes, and recurse through each node\n node.children = validChildren;\n node.children.forEach(child => {\n traverse(child);\n });\n };\n traverse(treeParsed);\n // Update the viewData state\n this.viewData = [treeParsed];\n console.log('viewData:', this.viewData);\n this.buildNodesArray(this.viewData);\n this.buildEdgesArray(this.viewData);\n }\n}\nexports[\"default\"] = FlowBuilder;\n\n//# sourceURL=webpack://react-labyrinth/./src/webview/flowBuilder.tsx?"); + +/***/ }), + +/***/ "./src/webview/index.tsx": +/*!*******************************!*\ + !*** ./src/webview/index.tsx ***! + \*******************************/ +/***/ (function(__unused_webpack_module, exports, __webpack_require__) { + +"use strict"; +eval("\n\nvar __importDefault = this && this.__importDefault || function (mod) {\n return mod && mod.__esModule ? mod : {\n \"default\": mod\n };\n};\nObject.defineProperty(exports, \"__esModule\", ({\n value: true\n}));\nconst react_1 = __importDefault(__webpack_require__(/*! react */ \"./node_modules/react/index.js\"));\nconst client_1 = __webpack_require__(/*! react-dom/client */ \"./node_modules/react-dom/client.js\");\n__webpack_require__(/*! ./style.css */ \"./src/webview/style.css\");\nconst App_1 = __importDefault(__webpack_require__(/*! ./App */ \"./src/webview/App.tsx\"));\nconst rootElement = document.getElementById(\"root\");\nconst root = (0, client_1.createRoot)(rootElement);\nroot.render(react_1.default.createElement(react_1.default.StrictMode, null, react_1.default.createElement(App_1.default, null)));\n\n//# sourceURL=webpack://react-labyrinth/./src/webview/index.tsx?"); + +/***/ }), + +/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js!./node_modules/reactflow/dist/style.css": +/*!*******************************************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js!./node_modules/reactflow/dist/style.css ***! + \*******************************************************************************************************************************/ +/***/ ((module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/* this gets exported as style.css and can be used for the default theming */\n/* these are the necessary styles for React Flow, they get used by base.css and style.css */\n.react-flow__container {\n position: absolute;\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n}\n.react-flow__pane {\n z-index: 1;\n cursor: grab;\n}\n.react-flow__pane.selection {\n cursor: pointer;\n }\n.react-flow__pane.dragging {\n cursor: grabbing;\n }\n.react-flow__viewport {\n transform-origin: 0 0;\n z-index: 2;\n pointer-events: none;\n}\n.react-flow__renderer {\n z-index: 4;\n}\n.react-flow__selection {\n z-index: 6;\n}\n.react-flow__nodesselection-rect:focus,\n.react-flow__nodesselection-rect:focus-visible {\n outline: none;\n}\n.react-flow .react-flow__edges {\n pointer-events: none;\n overflow: visible;\n}\n.react-flow__edge-path,\n.react-flow__connection-path {\n stroke: #b1b1b7;\n stroke-width: 1;\n fill: none;\n}\n.react-flow__edge {\n pointer-events: visibleStroke;\n cursor: pointer;\n}\n.react-flow__edge.animated path {\n stroke-dasharray: 5;\n animation: dashdraw 0.5s linear infinite;\n }\n.react-flow__edge.animated path.react-flow__edge-interaction {\n stroke-dasharray: none;\n animation: none;\n }\n.react-flow__edge.inactive {\n pointer-events: none;\n }\n.react-flow__edge.selected,\n .react-flow__edge:focus,\n .react-flow__edge:focus-visible {\n outline: none;\n }\n.react-flow__edge.selected .react-flow__edge-path,\n .react-flow__edge:focus .react-flow__edge-path,\n .react-flow__edge:focus-visible .react-flow__edge-path {\n stroke: #555;\n }\n.react-flow__edge-textwrapper {\n pointer-events: all;\n }\n.react-flow__edge-textbg {\n fill: white;\n }\n.react-flow__edge .react-flow__edge-text {\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n }\n.react-flow__connection {\n pointer-events: none;\n}\n.react-flow__connection .animated {\n stroke-dasharray: 5;\n animation: dashdraw 0.5s linear infinite;\n }\n.react-flow__connectionline {\n z-index: 1001;\n}\n.react-flow__nodes {\n pointer-events: none;\n transform-origin: 0 0;\n}\n.react-flow__node {\n position: absolute;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n pointer-events: all;\n transform-origin: 0 0;\n box-sizing: border-box;\n cursor: grab;\n}\n.react-flow__node.dragging {\n cursor: grabbing;\n }\n.react-flow__nodesselection {\n z-index: 3;\n transform-origin: left top;\n pointer-events: none;\n}\n.react-flow__nodesselection-rect {\n position: absolute;\n pointer-events: all;\n cursor: grab;\n }\n.react-flow__handle {\n position: absolute;\n pointer-events: none;\n min-width: 5px;\n min-height: 5px;\n width: 6px;\n height: 6px;\n background: #1a192b;\n border: 1px solid white;\n border-radius: 100%;\n}\n.react-flow__handle.connectionindicator {\n pointer-events: all;\n cursor: crosshair;\n }\n.react-flow__handle-bottom {\n top: auto;\n left: 50%;\n bottom: -4px;\n transform: translate(-50%, 0);\n }\n.react-flow__handle-top {\n left: 50%;\n top: -4px;\n transform: translate(-50%, 0);\n }\n.react-flow__handle-left {\n top: 50%;\n left: -4px;\n transform: translate(0, -50%);\n }\n.react-flow__handle-right {\n right: -4px;\n top: 50%;\n transform: translate(0, -50%);\n }\n.react-flow__edgeupdater {\n cursor: move;\n pointer-events: all;\n}\n.react-flow__panel {\n position: absolute;\n z-index: 5;\n margin: 15px;\n}\n.react-flow__panel.top {\n top: 0;\n }\n.react-flow__panel.bottom {\n bottom: 0;\n }\n.react-flow__panel.left {\n left: 0;\n }\n.react-flow__panel.right {\n right: 0;\n }\n.react-flow__panel.center {\n left: 50%;\n transform: translateX(-50%);\n }\n.react-flow__attribution {\n font-size: 10px;\n background: rgba(255, 255, 255, 0.5);\n padding: 2px 3px;\n margin: 0;\n}\n.react-flow__attribution a {\n -webkit-text-decoration: none;\n text-decoration: none;\n color: #999;\n }\n@keyframes dashdraw {\n from {\n stroke-dashoffset: 10;\n }\n}\n.react-flow__edgelabel-renderer {\n position: absolute;\n width: 100%;\n height: 100%;\n pointer-events: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n}\n.react-flow__edge.updating .react-flow__edge-path {\n stroke: #777;\n }\n.react-flow__edge-text {\n font-size: 10px;\n }\n.react-flow__node.selectable:focus,\n .react-flow__node.selectable:focus-visible {\n outline: none;\n }\n.react-flow__node-default,\n.react-flow__node-input,\n.react-flow__node-output,\n.react-flow__node-group {\n padding: 10px;\n border-radius: 3px;\n width: 150px;\n font-size: 12px;\n color: #222;\n text-align: center;\n border-width: 1px;\n border-style: solid;\n border-color: #1a192b;\n background-color: white;\n}\n.react-flow__node-default.selectable:hover, .react-flow__node-input.selectable:hover, .react-flow__node-output.selectable:hover, .react-flow__node-group.selectable:hover {\n box-shadow: 0 1px 4px 1px rgba(0, 0, 0, 0.08);\n }\n.react-flow__node-default.selectable.selected,\n .react-flow__node-default.selectable:focus,\n .react-flow__node-default.selectable:focus-visible,\n .react-flow__node-input.selectable.selected,\n .react-flow__node-input.selectable:focus,\n .react-flow__node-input.selectable:focus-visible,\n .react-flow__node-output.selectable.selected,\n .react-flow__node-output.selectable:focus,\n .react-flow__node-output.selectable:focus-visible,\n .react-flow__node-group.selectable.selected,\n .react-flow__node-group.selectable:focus,\n .react-flow__node-group.selectable:focus-visible {\n box-shadow: 0 0 0 0.5px #1a192b;\n }\n.react-flow__node-group {\n background-color: rgba(240, 240, 240, 0.25);\n}\n.react-flow__nodesselection-rect,\n.react-flow__selection {\n background: rgba(0, 89, 220, 0.08);\n border: 1px dotted rgba(0, 89, 220, 0.8);\n}\n.react-flow__nodesselection-rect:focus,\n .react-flow__nodesselection-rect:focus-visible,\n .react-flow__selection:focus,\n .react-flow__selection:focus-visible {\n outline: none;\n }\n.react-flow__controls {\n box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.08);\n}\n.react-flow__controls-button {\n border: none;\n background: #fefefe;\n border-bottom: 1px solid #eee;\n box-sizing: content-box;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n -webkit-user-select: none;\n -moz-user-select: none;\n user-select: none;\n padding: 5px;\n }\n.react-flow__controls-button:hover {\n background: #f4f4f4;\n }\n.react-flow__controls-button svg {\n width: 100%;\n max-width: 12px;\n max-height: 12px;\n }\n.react-flow__controls-button:disabled {\n pointer-events: none;\n }\n.react-flow__controls-button:disabled svg {\n fill-opacity: 0.4;\n }\n.react-flow__minimap {\n background-color: #fff;\n}\n.react-flow__resize-control {\n position: absolute;\n}\n.react-flow__resize-control.left,\n.react-flow__resize-control.right {\n cursor: ew-resize;\n}\n.react-flow__resize-control.top,\n.react-flow__resize-control.bottom {\n cursor: ns-resize;\n}\n.react-flow__resize-control.top.left,\n.react-flow__resize-control.bottom.right {\n cursor: nwse-resize;\n}\n.react-flow__resize-control.bottom.left,\n.react-flow__resize-control.top.right {\n cursor: nesw-resize;\n}\n/* handle styles */\n.react-flow__resize-control.handle {\n width: 4px;\n height: 4px;\n border: 1px solid #fff;\n border-radius: 1px;\n background-color: #3367d9;\n transform: translate(-50%, -50%);\n}\n.react-flow__resize-control.handle.left {\n left: 0;\n top: 50%;\n}\n.react-flow__resize-control.handle.right {\n left: 100%;\n top: 50%;\n}\n.react-flow__resize-control.handle.top {\n left: 50%;\n top: 0;\n}\n.react-flow__resize-control.handle.bottom {\n left: 50%;\n top: 100%;\n}\n.react-flow__resize-control.handle.top.left {\n left: 0;\n}\n.react-flow__resize-control.handle.bottom.left {\n left: 0;\n}\n.react-flow__resize-control.handle.top.right {\n left: 100%;\n}\n.react-flow__resize-control.handle.bottom.right {\n left: 100%;\n}\n/* line styles */\n.react-flow__resize-control.line {\n border-color: #3367d9;\n border-width: 0;\n border-style: solid;\n}\n.react-flow__resize-control.line.left,\n.react-flow__resize-control.line.right {\n width: 1px;\n transform: translate(-50%, 0);\n top: 0;\n height: 100%;\n}\n.react-flow__resize-control.line.left {\n left: 0;\n border-left-width: 1px;\n}\n.react-flow__resize-control.line.right {\n left: 100%;\n border-right-width: 1px;\n}\n.react-flow__resize-control.line.top,\n.react-flow__resize-control.line.bottom {\n height: 1px;\n transform: translate(0, -50%);\n left: 0;\n width: 100%;\n}\n.react-flow__resize-control.line.top {\n top: 0;\n border-top-width: 1px;\n}\n.react-flow__resize-control.line.bottom {\n border-bottom-width: 1px;\n top: 100%;\n}\n`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://react-labyrinth/./node_modules/reactflow/dist/style.css?./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js"); + +/***/ }), + +/***/ "./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js!./src/webview/style.css": +/*!***************************************************************************************************************!*\ + !*** ./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js!./src/webview/style.css ***! + \***************************************************************************************************************/ +/***/ ((module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, `/*\n! tailwindcss v3.3.6 | MIT License | https://tailwindcss.com\n*//*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured \\`sans\\` font-family by default.\n5. Use the user's configured \\`sans\\` font-feature-settings by default.\n6. Use the user's configured \\`sans\\` font-variation-settings by default.\n*/\n\nhtml {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from \\`html\\` so users can set them as a class directly on the \\`html\\` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured \\`mono\\` font-family by default.\n2. Use the user's configured \\`mono\\` font-feature-settings by default.\n3. Use the user's configured \\`mono\\` font-variation-settings by default.\n4. Correct the odd \\`em\\` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent \\`sub\\` and \\`sup\\` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\n[type='button'],\n[type='reset'],\n[type='submit'] {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional \\`:invalid\\` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to \\`inherit\\` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements \\`display: block\\` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add \\`vertical-align: middle\\` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden] {\n display: none;\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgba(59, 130, 246, 0.5);\n --tw-ring-offset-shadow: 0 0 rgba(0,0,0,0);\n --tw-ring-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow: 0 0 rgba(0,0,0,0);\n --tw-shadow-colored: 0 0 rgba(0,0,0,0);\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n}\n.\\\\!container {\n width: 100% !important;\n}\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n\n .\\\\!container {\n max-width: 640px !important;\n }\n\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n\n .\\\\!container {\n max-width: 768px !important;\n }\n\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n\n .\\\\!container {\n max-width: 1024px !important;\n }\n\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n\n .\\\\!container {\n max-width: 1280px !important;\n }\n\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n\n .\\\\!container {\n max-width: 1536px !important;\n }\n\n .container {\n max-width: 1536px;\n }\n}\n.visible {\n visibility: visible !important;\n}\n.invisible {\n visibility: hidden !important;\n}\n.collapse {\n visibility: collapse !important;\n}\n.static {\n position: static !important;\n}\n.fixed {\n position: fixed !important;\n}\n.absolute {\n position: absolute !important;\n}\n.relative {\n position: relative !important;\n}\n.-mx-2 {\n margin-left: -0.5rem !important;\n margin-right: -0.5rem !important;\n}\n.-my-2 {\n margin-top: -0.5rem !important;\n margin-bottom: -0.5rem !important;\n}\n.block {\n display: block !important;\n}\n.inline {\n display: inline !important;\n}\n.flex {\n display: flex !important;\n}\n.table {\n display: table !important;\n}\n.grid {\n display: grid !important;\n}\n.contents {\n display: contents !important;\n}\n.\\\\!hidden {\n display: none !important;\n}\n.hidden {\n display: none !important;\n}\n.w-20 {\n width: 5rem !important;\n}\n.flex-shrink {\n flex-shrink: 1 !important;\n}\n.shrink {\n flex-shrink: 1 !important;\n}\n.flex-grow {\n flex-grow: 1 !important;\n}\n.grow {\n flex-grow: 1 !important;\n}\n.border-collapse {\n border-collapse: collapse !important;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)) !important;\n}\n.resize {\n resize: both !important;\n}\n.place-items-end {\n align-items: end !important;\n justify-items: end !important;\n place-items: end !important;\n}\n.place-items-center {\n align-items: center !important;\n justify-items: center !important;\n place-items: center !important;\n}\n.justify-end {\n justify-content: flex-end !important;\n}\n.justify-center {\n justify-content: center !important;\n}\n.overflow-hidden {\n overflow: hidden !important;\n}\n.text-ellipsis {\n text-overflow: ellipsis !important;\n}\n.rounded-full {\n border-radius: 9999px !important;\n}\n.rounded-md {\n border-radius: 0.375rem !important;\n}\n.border {\n border-width: 1px !important;\n}\n.border-2 {\n border-width: 2px !important;\n}\n.border-gray-500 {\n --tw-border-opacity: 1 !important;\n border-color: rgba(107, 114, 128, 1) !important;\n border-color: rgba(107, 114, 128, var(--tw-border-opacity)) !important;\n}\n.bg-blue {\n --tw-bg-opacity: 1 !important;\n background-color: rgba(147, 197, 253, 1) !important;\n background-color: rgba(147, 197, 253, var(--tw-bg-opacity)) !important;\n}\n.bg-orange {\n --tw-bg-opacity: 1 !important;\n background-color: rgba(253, 186, 116, 1) !important;\n background-color: rgba(253, 186, 116, var(--tw-bg-opacity)) !important;\n}\n.bg-slate-50 {\n --tw-bg-opacity: 1 !important;\n background-color: rgba(248, 250, 252, 1) !important;\n background-color: rgba(248, 250, 252, var(--tw-bg-opacity)) !important;\n}\n.px-9 {\n padding-left: 2.25rem !important;\n padding-right: 2.25rem !important;\n}\n.py-2 {\n padding-top: 0.5rem !important;\n padding-bottom: 0.5rem !important;\n}\n.pb-2 {\n padding-bottom: 0.5rem !important;\n}\n.pl-2 {\n padding-left: 0.5rem !important;\n}\n.pr-2 {\n padding-right: 0.5rem !important;\n}\n.text-base {\n font-size: 1rem !important;\n line-height: 1.5rem !important;\n}\n.text-sm {\n font-size: 0.875rem !important;\n line-height: 1.25rem !important;\n}\n.font-medium {\n font-weight: 500 !important;\n}\n.uppercase {\n text-transform: uppercase !important;\n}\n.lowercase {\n text-transform: lowercase !important;\n}\n.capitalize {\n text-transform: capitalize !important;\n}\n.text-black {\n --tw-text-opacity: 1 !important;\n color: rgba(0, 0, 0, 1) !important;\n color: rgba(0, 0, 0, var(--tw-text-opacity)) !important;\n}\n.text-transparent {\n color: transparent !important;\n}\n.underline {\n text-decoration-line: underline !important;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important;\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color) !important;\n box-shadow: 0 0 rgba(0,0,0,0), 0 0 rgba(0,0,0,0), 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1) !important;\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0,0,0,0)), var(--tw-ring-shadow, 0 0 rgba(0,0,0,0)), var(--tw-shadow) !important;\n}\n.shadow-lg {\n --tw-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1) !important;\n --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;\n box-shadow: 0 0 rgba(0,0,0,0), 0 0 rgba(0,0,0,0), 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1) !important;\n box-shadow: var(--tw-ring-offset-shadow, 0 0 rgba(0,0,0,0)), var(--tw-ring-shadow, 0 0 rgba(0,0,0,0)), var(--tw-shadow) !important;\n}\n.outline {\n outline-style: solid !important;\n}\n.blur {\n --tw-blur: blur(8px) !important;\n filter: blur(8px) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n}\n.invert {\n --tw-invert: invert(100%) !important;\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) invert(100%) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n}\n.\\\\!filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow) !important;\n}\n.backdrop-filter {\n -webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia) !important;\n backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia) !important;\n}\n.\\\\!transition {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter !important;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter !important;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important;\n transition-duration: 150ms !important;\n}\n.transition {\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, -webkit-backdrop-filter !important;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter !important;\n transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-backdrop-filter !important;\n transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) !important;\n transition-duration: 150ms !important;\n}\n\nhtml,\nbody,\n#root,\n.App {\n height: 100%;\n}\n\n.App {\n font-family: sans-serif;\n text-align: center;\n}\n`, \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://react-labyrinth/./src/webview/style.css?./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/dist/cjs.js"); + +/***/ }), + +/***/ "./node_modules/css-loader/dist/runtime/api.js": +/*!*****************************************************!*\ + !*** ./node_modules/css-loader/dist/runtime/api.js ***! + \*****************************************************/ +/***/ ((module) => { + +"use strict"; +eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n//# sourceURL=webpack://react-labyrinth/./node_modules/css-loader/dist/runtime/api.js?"); + +/***/ }), + +/***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js": +/*!**************************************************************!*\ + !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***! + \**************************************************************/ +/***/ ((module) => { + +"use strict"; +eval("\n\nmodule.exports = function (i) {\n return i[1];\n};\n\n//# sourceURL=webpack://react-labyrinth/./node_modules/css-loader/dist/runtime/noSourceMaps.js?"); + +/***/ }), + +/***/ "./node_modules/react-dom/cjs/react-dom.development.js": +/*!*************************************************************!*\ + !*** ./node_modules/react-dom/cjs/react-dom.development.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, exports, __webpack_require__) => { + +"use strict"; +eval("/**\n * @license React\n * react-dom.development.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\n\nif (true) {\n (function() {\n\n 'use strict';\n\n/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\nif (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===\n 'function'\n) {\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());\n}\n var React = __webpack_require__(/*! react */ \"./node_modules/react/index.js\");\nvar Scheduler = __webpack_require__(/*! scheduler */ \"./node_modules/scheduler/index.js\");\n\nvar ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;\n\nvar suppressWarning = false;\nfunction setSuppressWarning(newSuppressWarning) {\n {\n suppressWarning = newSuppressWarning;\n }\n} // In DEV, calls to console.warn and console.error get replaced\n// by calls to these methods by a Babel plugin.\n//\n// In PROD (or in packages without access to React internals),\n// they are left as they are instead.\n\nfunction warn(format) {\n {\n if (!suppressWarning) {\n for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n args[_key - 1] = arguments[_key];\n }\n\n printWarning('warn', format, args);\n }\n }\n}\nfunction error(format) {\n {\n if (!suppressWarning) {\n for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {\n args[_key2 - 1] = arguments[_key2];\n }\n\n printWarning('error', format, args);\n }\n }\n}\n\nfunction printWarning(level, format, args) {\n // When changing this logic, you might want to also\n // update consoleWithStackDev.www.js as well.\n {\n var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;\n var stack = ReactDebugCurrentFrame.getStackAddendum();\n\n if (stack !== '') {\n format += '%s';\n args = args.concat([stack]);\n } // eslint-disable-next-line react-internal/safe-string-coercion\n\n\n var argsWithFormat = args.map(function (item) {\n return String(item);\n }); // Careful: RN currently depends on this prefix\n\n argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it\n // breaks IE9: https://github.com/facebook/react/issues/13610\n // eslint-disable-next-line react-internal/no-production-logging\n\n Function.prototype.apply.call(console[level], console, argsWithFormat);\n }\n}\n\nvar FunctionComponent = 0;\nvar ClassComponent = 1;\nvar IndeterminateComponent = 2; // Before we know whether it is function or class\n\nvar HostRoot = 3; // Root of a host tree. Could be nested inside another node.\n\nvar HostPortal = 4; // A subtree. Could be an entry point to a different renderer.\n\nvar HostComponent = 5;\nvar HostText = 6;\nvar Fragment = 7;\nvar Mode = 8;\nvar ContextConsumer = 9;\nvar ContextProvider = 10;\nvar ForwardRef = 11;\nvar Profiler = 12;\nvar SuspenseComponent = 13;\nvar MemoComponent = 14;\nvar SimpleMemoComponent = 15;\nvar LazyComponent = 16;\nvar IncompleteClassComponent = 17;\nvar DehydratedFragment = 18;\nvar SuspenseListComponent = 19;\nvar ScopeComponent = 21;\nvar OffscreenComponent = 22;\nvar LegacyHiddenComponent = 23;\nvar CacheComponent = 24;\nvar TracingMarkerComponent = 25;\n\n// -----------------------------------------------------------------------------\n\nvar enableClientRenderFallbackOnTextMismatch = true; // TODO: Need to review this code one more time before landing\n// the react-reconciler package.\n\nvar enableNewReconciler = false; // Support legacy Primer support on internal FB www\n\nvar enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.\n\nvar enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber\n\nvar enableSuspenseAvoidThisFallback = false; // Enables unstable_avoidThisFallback feature in Fizz\n// React DOM Chopping Block\n//\n// Similar to main Chopping Block but only flags related to React DOM. These are\n// grouped because we will likely batch all of them into a single major release.\n// -----------------------------------------------------------------------------\n// Disable support for comment nodes as React DOM containers. Already disabled\n// in open source, but www codebase still relies on it. Need to remove.\n\nvar disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection.\n// and client rendering, mostly to allow JSX attributes to apply to the custom\n// element's object properties instead of only HTML attributes.\n// https://github.com/facebook/react/issues/11347\n\nvar enableCustomElementPropertySupport = false; // Disables children for