diff --git a/.github/DISCUSSION_TEMPLATE/design-ideas.yaml b/.github/DISCUSSION_TEMPLATE/design-ideas.yaml deleted file mode 100644 index 52c5d412..00000000 --- a/.github/DISCUSSION_TEMPLATE/design-ideas.yaml +++ /dev/null @@ -1,45 +0,0 @@ -title: "" -body: - - type: markdown - attributes: - value: > - Thank you for proposing a design idea! - Please provide the details below to help us understand the context and rationale behind this idea. - Make sure to link this design idea to a user story to showcase the need for this design. - - - type: input - id: user-story-link - attributes: - label: Link to User Story - placeholder: "URL to the related user story" - validations: - required: false - - - type: textarea - id: current-approach-problem - attributes: - label: Problem with Current Approach - description: "Describe the problem with the current approach, if any. Explain what's lacking or why it's not satisfactory." - placeholder: "Explain the problem..." - validations: - required: true - - - type: textarea - id: design-solution - attributes: - label: Proposed Design Solution - description: "Explain how your design idea solves the problem. Describe the design changes in detail." - placeholder: "Describe your design solution..." - validations: - required: true - - - type: markdown - attributes: - value: | - If possible, please attach an image representing a mockup or sketch of your design idea. Visual representations can help communicate your idea more clearly. - - - type: markdown - attributes: - value: | - Once again, thank you for your contribution. Our team will review your design idea and provide feedback. - diff --git a/.github/DISCUSSION_TEMPLATE/user-personas-and-stories.yaml b/.github/DISCUSSION_TEMPLATE/user-personas-and-stories.yaml index 488f3194..79dcd520 100644 --- a/.github/DISCUSSION_TEMPLATE/user-personas-and-stories.yaml +++ b/.github/DISCUSSION_TEMPLATE/user-personas-and-stories.yaml @@ -4,7 +4,7 @@ body: attributes: value: > Develop a user persona and a story to capture the goals and tasks your users want to accomplish with diracx-web. - We are interested in understanding your needs and goals. Please focus on what you want to achieve rather than how you think it should be achieved. + We are interested in understanding your needs and goals. Please, first focus on what you want to achieve rather than how you think it should be achieved first. All ideas are welcome, and there are no wrong answers. We appreciate your honest feedback as it helps us improve the system to better meet your needs. - type: textarea @@ -43,10 +43,27 @@ body: validations: required: true + - type: markdown + attributes: + value: | + From this point, you can optionally propose ideas of how it should be conceived, even if you technically do not know whether it is achievable. + - type: textarea - id: additional-comments + id: design-solution attributes: - label: Additional Comments or Suggestions - description: "Share any other feedback, ideas, or suggestions that can help us understand your needs better." - validations: - required: false + label: Proposed Design Solution + description: | + Design proposal(s) can be submitted here. + Explain how your design solves the problem. Describe the design changes in details. + placeholder: "Describe your design solution..." + + - type: markdown + attributes: + value: | + If possible, please attach an image representing a mockup or sketch of your design idea. Visual representations can help communicate your idea more clearly. + + - type: markdown + attributes: + value: | + Once again, thank you for your contribution. Our team will review your design proposal(s) and provide feedback. + diff --git a/.github/workflows/deployment.yml b/.github/workflows/deployment.yml index 63c87129..4d9da613 100644 --- a/.github/workflows/deployment.yml +++ b/.github/workflows/deployment.yml @@ -74,7 +74,7 @@ jobs: cache: 'npm' - name: Build documentation - run: npm ci && npm --prefix packages/diracx-web-components run build-storybook + run: npm ci && npm --prefix packages/diracx-web-components run build-doc - name: Upload artifact uses: actions/upload-pages-artifact@v3 diff --git a/.github/workflows/gubbins-test.yml b/.github/workflows/gubbins-test.yml index fbda2987..5bc070cb 100644 --- a/.github/workflows/gubbins-test.yml +++ b/.github/workflows/gubbins-test.yml @@ -41,9 +41,59 @@ jobs: run: npm --prefix packages/extensions run ts-lint # ============================================================================# - # WARNING: In your CI/CD pipeline, you should remove the following job # + # WARNING: In your CI/CD pipeline, you should remove the following jobs # # ----------------------------------------------------------------------------# - prepare-gubbins-as-a-standalone: + # By default, the gubbins extension is part of a monorepo and uses a local # + # version of `diracx-web-components`. This default setup is not # + # representative of a standalone extension configuration. Here we want to # + # closely mimic a standalone extension. To do so, we: # + # - Isolate the packages/extensions directory: Move its content to a new # + # repository or directory outside the monorepo. # + # - Update Configuration: Adjust relevant variables to align with a # + # standalone setup. # + prepare-gubbins-backend: + runs-on: ubuntu-latest + if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} + steps: + - name: Clone source + run: | + cd .. + git clone https://github.com/DIRACGrid/diracx.git + + - name: Where the magic happens (Move extensions to a temporary directory) + run: | + # We have to copy the code to another directory + # and make it a git repository by itself because otherwise the + # root in the pyproject to do not make sense once mounted + # in the containers. + cp -r ../diracx/extensions/gubbins /tmp/ + sed -i 's@../..@.@g' /tmp/gubbins/pyproject.toml + sed -i 's@../../@@g' /tmp/gubbins/gubbins-*/pyproject.toml + git init /tmp/gubbins/ + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: gubbins + path: /tmp/gubbins + + - name: Build and export service + uses: docker/build-push-action@v6 + with: + context: ../diracx/extensions/containers/services + tags: gubbins/services:dev + outputs: type=docker,dest=/tmp/gubbins_services_image.tar + build-args: | + EXTRA_PACKAGES_TO_INSTALL=git+https://github.com/DIRACGrid/DIRAC.git@integration + EXTENSION_CUSTOM_SOURCES_TO_INSTALL=/bindmount/gubbins_db*.whl,/bindmount/gubbins_routers*.whl,/bindmount/gubbins_client*.whl + + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: gubbins-services-img + path: /tmp/gubbins_services_image.tar + + prepare-gubbins-frontend-as-a-standalone: runs-on: ubuntu-latest if: ${{ github.event_name != 'push' || github.repository == 'DIRACGrid/diracx-web' }} steps: @@ -64,30 +114,32 @@ jobs: - name: Where the magic happens (Move extensions to a temporary directory) run: | - # Move the library package to the extensions directory - mv packages/diracx-web-components/*.tgz packages/extensions/diracx-web-components.tgz # Move the extensions to the temporary directory - mv packages/extensions /tmp/extensions + cp -r packages/extensions /tmp/gubbins-web + # Move the library package to the extensions directory + mv packages/diracx-web-components/*.tgz /tmp/gubbins-web/diracx-web-components.tgz # Update the package.json to point to the local diracx-web-components - jq '.dependencies["@dirac-grid/diracx-web-components"] = "file:./diracx-web-components.tgz"' /tmp/extensions/package.json > /tmp/extensions/package.temp.json - mv /tmp/extensions/package.temp.json /tmp/extensions/package.json + jq '.dependencies["@dirac-grid/diracx-web-components"] = "file:./diracx-web-components.tgz"' /tmp/gubbins-web/package.json > /tmp/gubbins-web/package.temp.json + mv /tmp/gubbins-web/package.temp.json /tmp/gubbins-web/package.json # Update the package.json to point to the correct postinstall script - jq '.scripts.postinstall = "node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public"' /tmp/extensions/package.json > /tmp/extensions/package.temp.json - mv /tmp/extensions/package.temp.json /tmp/extensions/package.json + jq '.scripts.postinstall = "node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public"' /tmp/gubbins-web/package.json > /tmp/gubbins-web/package.temp.json + mv /tmp/gubbins-web/package.temp.json /tmp/gubbins-web/package.json + # Update the next.config.js to prevent the standalone extension from searching a local version of diracx-web-components that does not exist + echo 'const nextConfig = { output: "export", images: { unoptimized: true }}; export default nextConfig;" > /tmp/gubbins-web/next.config.js - name: Install extensions dependencies - working-directory: /tmp/extensions + working-directory: /tmp/gubbins-web run: npm install - name: Upload the extensions directory uses: actions/upload-artifact@v4 with: - name: gubbins - path: /tmp/extensions + name: gubbins-web + path: /tmp/gubbins-web retention-days: 1 # ----------------------------------------------------------------------------# # In the following jobs, you should: # - # - Replace /tmp/extensions with the path to your extension source code # + # - Replace /tmp/gubbins-web with the path to your extension source code # # - Remove the `needs: prepare-gubbins-as-a-standalone` line # # ============================================================================# @@ -114,11 +166,11 @@ jobs: # ========================================================================# # WARNING: In your CI/CD pipeline, you should remove the following steps # # ------------------------------------------------------------------------# - - name: Download the extensions directory + - name: Download gubbins-web uses: actions/download-artifact@v4 with: - name: gubbins - path: /tmp/extensions + name: gubbins-web + path: /tmp/gubbins-web # ------------------------------------------------------------------------# # ========================================================================# @@ -126,12 +178,12 @@ jobs: - name: Build Docker image (extension example) uses: docker/build-push-action@v6 with: - context: /tmp/extensions + context: /tmp/gubbins-web push: false tags: ghcr.io/diracgrid/diracx-web/gubbins:dev platforms: linux/amd64,linux/arm64 - # Run the demo with the extension source code + # Run the demo with the extension source code (frontend and backend) run-demo: runs-on: ubuntu-latest needs: prepare-gubbins-as-a-standalone @@ -139,7 +191,7 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Clone source + - name: Clone source run: | cd .. git clone https://github.com/DIRACGrid/diracx-charts.git @@ -147,11 +199,31 @@ jobs: # ========================================================================# # WARNING: In your CI/CD pipeline, you should remove the following steps # # ------------------------------------------------------------------------# - - name: Download the extensions directory + - name: Download gubbins uses: actions/download-artifact@v4 with: name: gubbins - path: /tmp/extensions + path: /tmp/gubbins + + - name: Clone diracx source + run: | + cd .. + git clone https://github.com/DIRACGrid/diracx.git + + - name: Download gubbins:services image + uses: actions/download-artifact@v4 + with: + name: gubbins-services-img + path: /tmp/gubbins_services_image.tar + + - name: Load docker image + run: docker load --input /tmp/gubbins_services_image.tar + + - name: Download gubbins-web + uses: actions/download-artifact@v4 + with: + name: gubbins-web + path: /tmp/gubbins-web # ------------------------------------------------------------------------# # ========================================================================# @@ -159,7 +231,7 @@ jobs: - name: Start demo run: | cd .. - diracx-charts/run_demo.sh --exit-when-done /tmp/extensions/ + diracx-charts/run_demo.sh --exit-when-done --set-value developer.autoReload=false --ci-values ./diracx/extensions/gubbins_values.yaml --load-docker-image "gubbins/services:dev" diracx/ /tmp/gubbins/ /tmp/gubbins-web/ - name: Debugging information run: | @@ -194,4 +266,4 @@ jobs: with: browser: chrome config: baseUrl=${{ env.DIRACX_URL }} - project: /tmp/extensions + project: /tmp/gubbins-web diff --git a/.prettierignore b/.prettierignore index 3aa79bca..5a1924a2 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,8 @@ node_modules build +CONTRIBUTING.md dist +docs public .github jest.config.mjs @@ -19,4 +21,4 @@ packages/*/out **/release-please-config.json **/.release-please-manifest.json -**/CHANGELOG.md \ No newline at end of file +**/CHANGELOG.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74e22451..54d11e31 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,67 +1,17 @@ -# Contributing to This Project +# Contributing to DiracX-Web Thank you for your interest in contributing to our project! We appreciate all contributions, big and small. Below are some guidelines to help you get started. -## Bug reporting and discussions +- **Found a :bug: bug?** + - First if someone has already reported a similar [Issue](https://github.com/DIRACGrid/diracx-web/issues). + - If not, feel free to open a new one. -- Want to report a bug? - Open an [Issue](https://github.com/DIRACGrid/diracx-web/issues). -- Need technical support to configure `diracx-web`? - Start a [Support discussion](https://github.com/DIRACGrid/diracx-web/discussions/categories/support). +- **Need :hammer_and_wrench: technical support to configure DiracX-Web?** + - Start by reading the [:book: Admin Guide](docs/admin/index.md). + - Still stuck? Start a [:pray: Support discussion](https://github.com/DIRACGrid/diracx-web/discussions/categories/support). -- Want to make a general feedback about the [DIRAC web application](https://github.com/DIRACGrid/WebAppDIRAC)? - Answer to the [Survey](https://github.com/DIRACGrid/diracx-web/discussions/categories/surveys) by creating a new discussion. -- Want to request a feature? - Create a [User Story](https://github.com/DIRACGrid/diracx-web/discussions/categories/user-personas-and-stories) to describe your need. -- Want to discuss about UX/UI design? - Share your [Design idea](https://github.com/DIRACGrid/diracx-web/discussions/categories/design-ideas). +- **Have a :bulb: feature proposal?** + - Create a [:bust_in_silhouette: User Story](https://github.com/DIRACGrid/diracx-web/discussions/categories/user-personas-and-stories) to describe your need and share your design ideas if any. -## How to Contribute - -### 1. Opening an Issue - -- **Discuss Before Implementing:** Before making a pull request (PR), especially for non-trivial changes, please [open an issue](https://github.com/DIRACGrid/diracx-web/issues) to discuss your idea. This ensures that everyone is aligned on the proposed change. -- **Check for Existing Issues:** Before opening a new issue, please check if a similar issue already exists. If a similar issue exists, consider contributing to the discussion there instead. - -### 2. Making Changes - -- **Code Documentation:** Ensure that any code you write is well-documented. This includes: - - Inline comments where necessary to explain complex logic. - - Updating or creating Storybook documentation if you are contributing to the `diracx-web-components` library. -- **Writing/Updating Tests:** When you change or add new code, make sure to write or update tests accordingly. This helps maintain the reliability and stability of the codebase. -- **Helping with Existing Issues:** If you want to start contributing right away, check out the issues labeled with ["good first issue"](https://github.com/DIRACGrid/diracx-web/labels/good%20first%20issue). These are issues that are well-suited for newcomers to the project. - -### 3. Commit Messages - -- **Conventional Commits:** All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. This ensures that commit messages are structured and consistent, which is important for automation and versioning. - - **Examples:** - - `feat(ui): add new button component` - - `fix(api): handle null values in response` - - `docs(readme): update contributing guidelines` - - **Why?** If your commit messages do not follow this convention, the Continuous Integration (CI) process will fail, and your PR will not be merged. Please ensure your commit messages are properly formatted before pushing. - -### 4. How to Make a Pull Request (PR) - -- **Fork the Repository:** Start by forking the repository and creating a new branch for your work. Use a descriptive name for your branch that reflects the work you're doing. -- **Make Your Changes:** Commit your changes with clear and concise commit messages following the Conventional Commits format. -- **Update Documentation and Tests:** As mentioned, ensure all relevant documentation and tests are updated to reflect your changes. -- **Submit Your PR:** When you’re ready, submit your pull request. Please include a clear description of what your PR does and reference the issue number it addresses (if applicable). -- **Review Process:** Your PR will be reviewed by project maintainers. Please be patient and responsive to any feedback you receive. - -### 5. Updating Storybook Stories - -If your changes affect the `diracx-web-components` library, you may need to update or add new Storybook stories to ensure components are well-documented and tested visually. - -- **Add New Stories:** If you’ve created a new component, add a corresponding Storybook story in the appropriate directory. This story should be placed inside a `*.stories.tsx` file alongside your new component. -- **Update Existing Stories:** If your changes modify the behavior or appearance of an existing component, make sure to update its Storybook story accordingly. -- **Run Storybook Locally:** Before submitting your PR, run Storybook locally to ensure that your changes are reflected correctly. You can do this by running `npm run storybook` in the `packages/diracx-web-components` directory. - -You can check the existing stories and the [Storybook documentation](https://storybook.js.org/docs) for more details on how to use Storybook. - -### 6. Additional Notes - -- **Trivial Changes:** For minor changes like fixing typos, feel free to skip the issue creation step and go straight to making a PR. -- **Stay Up-to-Date:** Make sure your branch is up-to-date with the latest changes in the main branch before submitting your PR. Use `git rebase` if necessary. -- **Project Setup:** See the README for instructions on how to set up the project and run tests locally. - -Thank you again for your contributions! We look forward to working with you. +- **Want to contribute to the :computer: codebase?** + - Read the [:book: Developer Guide](docs/developer/index.md) to set up your environment and get started. diff --git a/README.md b/README.md index 2688cc0f..8d6f04b3 100644 --- a/README.md +++ b/README.md @@ -1,116 +1,24 @@ +<p align="center"> + <img alt="Extension Logo" src="packages/diracx-web/public/DIRAC-logo-minimal.png" width="200" > +</p> + +# DiracX-Web ![Basic tests](https://github.com/DIRACGrid/diracx-web/actions/workflows/basic.yml/badge.svg?branch=main) ![Unit tests](https://github.com/DIRACGrid/diracx-web/actions/workflows/test.yml/badge.svg?branch=main) ![Integration tests](https://github.com/DIRACGrid/diracx-web/actions/workflows/integration-test.yml/badge.svg?branch=main) ![Deployment](https://github.com/DIRACGrid/diracx-web/actions/workflows/deployment.yml/badge.svg?branch=main) -# DiracX-Web - -## Overview - -`diracx-web` is a web application that provides a user interface to interact with the [DiracX](https://github.com/DIRACGrid/diracx) service and is part of the [DIRAC](https://github.com/DIRACGrid) ecosystem. - -This repository is organized as a monorepo, with the following key packages: - -- [diracx-web](packages/diracx-web) -- [diracx-web-components](packages/diracx-web-components) -- [extensions](packages/extensions) - -```mermaid ---- -config: - layout: elk ---- -flowchart TD - subgraph monorep["Monorepo"] - monorep1["diracx-web-components"] - monorep2["diracx-web"] - monorep3["extension[gubbins]"] - end - monorep2 -- images deployed in --> docker[" "] - monorep2 -. uses .-> monorep1 - monorep3 -. uses .-> monorep1 - monorep1 -- documented on --> storybook[" "] - monorep1 -- published on --> npm[" "] - extension["diracx-community-extension"] -. uses .-> npm - docker@{ img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQLQKd_MRed_mZQlgrzQuUXVA3P39ssOVX8_g&s", h: 100, w: 100} - storybook@{ img: "https://miro.medium.com/v2/resize:fit:900/1*ZuBTYHXl6l3XzTb8d9Oi5Q.png", h: 100, w: 150, pos: "b"} - npm@{ img: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/2560px-Npm-logo.svg.png", h: 40, w: 100} - monorep1:::Ash - monorep1:::Cyan - monorep2:::Green - monorep3:::Green - extension:::Ash - classDef Cyan stroke-width:1px, stroke-dasharray:none, stroke:#00FFFF, fill:#9CFFFF - classDef Green stroke-width:1px, stroke-dasharray:none, stroke:#5BFF00, fill:#A4FF8E, color:#374D7C - classDef Ash stroke-width:1px, stroke-dasharray:none, stroke:#999999, fill:#EEEEEE, color:#000000 -``` - -### Packages - -- **DiracX-Web**: Vanilla Dirac web interface based on Next.js. Leverages components from `DiracX-Web-Components` to provide core functionalities. - -- **DiracX-Web-Components**: A library of reusable React components designed for integration within the `DiracX-Web` package and to facilitate the creation of custom DiracX web extensions. - -- **Extensions**: An illustrative example of a web extension demonstrating how to extend the functionality of `DiracX-Web` using the components from the `DiracX-Web-Components` package. - -### Project Management - -- [**npm**](https://docs.npmjs.com/): Used for dependency management. -- [**Release-Please**](https://github.com/googleapis/release-please): Automated release management for the project. - -The dependency management is further detailed in the [Package Management](docs/package-management.md) documentation. - -For more detailed and interactive documentation, visit our [Storybook](https://diracgrid.github.io/diracx-web) instance. - -## Getting started - -_Requirements: docker, internet_ - -This will allow you to run a demo setup: - -```bash -# Clone the diracx-chart repository -git clone git@github.com:DIRACGrid/diracx-charts.git - -# Run the demo -diracx-charts/run_demo.sh -``` - -You can also start the demo setup in development mode - code changes will be reflected in the demo in real time: - -```bash -# Clone the diracx-web repository -git clone git@github.com:DIRACGrid/diracx-web.git - -# Clone the diracx-chart repository -git clone git@github.com:DIRACGrid/diracx-charts.git - -# Run the demo -diracx-charts/run_demo.sh ./diracx-web -``` - -## Contributing - -See the [Contributing guidelines](/CONTRIBUTING.md) -## Testing +**DiracX-Web** is a web application that provides a user-friendly interface to interact with the [DiracX](https://github.com/DIRACGrid/diracx) services. It is part of the [DIRAC](https://github.com/DIRACGrid) ecosystem. -Unit tests can be started with: +## Get Started -```bash -npm test -``` -End-to-end tests are launched through `cypress` such as: +- **New user?** Learn how to use the application effectively in the [:book: User Guide](docs/user/index.md) +- **Developing a DiracX-Web extension?** Go straight to the [:page_facing_up: Extension README](packages/extensions/README.md) +- **Managing the repository?** Discover tips and tricks in the [:book: Ops Guide](docs/ops/index.md) -```bash -# diracx-charts/run_demo.sh is running -npx cypress open --config baseUrl=$DIRACX_URL -``` +- **Interested in contributing?** Read the [:star: Contributing Document](CONTRIBUTING.md) -## Learn More -To learn more about Next.js, take a look at the following resources: -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. diff --git a/docs/dependencies&commands.excalidraw b/docs/dependencies&commands.excalidraw deleted file mode 100644 index 846dbcbf..00000000 --- a/docs/dependencies&commands.excalidraw +++ /dev/null @@ -1,4796 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "sgAHzm6_jegP9Leo-D-JD", - "type": "arrow", - "x": -1295.2415295358703, - "y": 428.44712069099353, - "width": 359.0552799142966, - "height": 83.16131417356848, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b4c", - "roundness": { - "type": 2 - }, - "seed": 881986822, - "version": 1772, - "versionNonce": 1748695962, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "raGZwNZNxkgWyAHT9PGzS" - } - ], - "updated": 1731056012901, - "link": null, - "locked": false, - "points": [ - [ - 40.02977710994885, - 0 - ], - [ - -87.11961104821353, - 31.775923803751652 - ], - [ - -319.02550280434775, - 83.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9UasxBv_zw9sgDEo6rnSP", - "focus": -0.8038367396506971, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "tWiUojbB6PTh1owJD7ZTg", - "focus": -0.7939992155916968, - "gap": 2.9193429132158144, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "raGZwNZNxkgWyAHT9PGzS", - "type": "text", - "x": -1432.3612321368182, - "y": 430.2230444947452, - "width": 100.00018310546875, - "height": 60, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b4d", - "roundness": null, - "seed": 303463494, - "version": 56, - "versionNonce": 561548422, - "isDeleted": false, - "boundElements": [], - "updated": 1731056011661, - "link": null, - "locked": false, - "text": "\nwatches\n(next.config)", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "sgAHzm6_jegP9Leo-D-JD", - "originalText": "\nwatches\n(next.config)", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 489, - "versionNonce": 629053594, - "index": "b5R", - "isDeleted": false, - "id": "tRXQ69tMttBmt0uOnvG1B", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1690.3123177422422, - "y": 549.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "width": 230, - "height": 150, - "seed": 2104005658, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "SEf2tnxcrYL2R8FD7TXaT" - } - ], - "updated": 1731053498759, - "link": null, - "locked": false - }, - { - "id": "SEf2tnxcrYL2R8FD7TXaT", - "type": "text", - "x": -1631.272263420953, - "y": 599.5277777777778, - "width": 111.91989135742188, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5S", - "roundness": null, - "seed": 104005850, - "version": 136, - "versionNonce": 907310426, - "isDeleted": false, - "boundElements": [], - "updated": 1731053498760, - "link": null, - "locked": false, - "text": "diracx-web-\ncomponents", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "tRXQ69tMttBmt0uOnvG1B", - "originalText": "diracx-web-components", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 553, - "versionNonce": 424720922, - "index": "b5T", - "isDeleted": false, - "id": "Edw6B7UA5xY3ZwXGA1w7K", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1254.3123177422422, - "y": 550.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "width": 230, - "height": 150, - "seed": 2046192902, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "cAWsIQ6uNCxsNC13ftv4Y" - } - ], - "updated": 1731053498760, - "link": null, - "locked": false - }, - { - "id": "cAWsIQ6uNCxsNC13ftv4Y", - "type": "text", - "x": -1190.1922615898984, - "y": 613.0277777777778, - "width": 101.7598876953125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5U", - "roundness": null, - "seed": 1810816070, - "version": 212, - "versionNonce": 2116445914, - "isDeleted": false, - "boundElements": [], - "updated": 1731053498760, - "link": null, - "locked": false, - "text": "diracx-web", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Edw6B7UA5xY3ZwXGA1w7K", - "originalText": "diracx-web", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 879, - "versionNonce": 702171014, - "index": "b5V", - "isDeleted": false, - "id": "tn6DDDgEFflY4_vkFbEN0", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2091.312317742242, - "y": 550.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "width": 230, - "height": 150, - "seed": 1833052634, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "aPX7ryh2zibOfi9NYWmB2" - }, - { - "id": "BGbyQLUnJB7bMRbTZxG-l", - "type": "arrow" - } - ], - "updated": 1731054333439, - "link": null, - "locked": false - }, - { - "id": "aPX7ryh2zibOfi9NYWmB2", - "type": "text", - "x": -2011.6422890557187, - "y": 613.0277777777778, - "width": 70.65994262695312, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5W", - "roundness": null, - "seed": 2043928218, - "version": 540, - "versionNonce": 1467180742, - "isDeleted": false, - "boundElements": [], - "updated": 1731054333439, - "link": null, - "locked": false, - "text": "gubbins", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "tn6DDDgEFflY4_vkFbEN0", - "originalText": "gubbins", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 763, - "versionNonce": 1905956358, - "index": "b5Z", - "isDeleted": false, - "id": "tWiUojbB6PTh1owJD7ZTg", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1667.8123177422422, - "y": 514.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 1905545862, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "ZOahFZ8IW1VrbaAAp_w_s" - }, - { - "id": "DPwlqoHuPv3GVitvgwc1M", - "type": "arrow" - }, - { - "id": "n1wTa1lENuGHRCmAdKxUj", - "type": "arrow" - }, - { - "id": "QLiEWw7s-N1dUpDPKX0nY", - "type": "arrow" - }, - { - "id": "sgAHzm6_jegP9Leo-D-JD", - "type": "arrow" - } - ], - "updated": 1731055916947, - "link": null, - "locked": false - }, - { - "id": "ZOahFZ8IW1VrbaAAp_w_s", - "type": "text", - "x": -1654.5122918023008, - "y": 538.0277777777778, - "width": 40.39994812011719, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5a", - "roundness": null, - "seed": 1370755526, - "version": 424, - "versionNonce": 558631942, - "isDeleted": false, - "boundElements": [], - "updated": 1731055378310, - "link": null, - "locked": false, - "text": "/src", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "tWiUojbB6PTh1owJD7ZTg", - "originalText": "/src", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 727, - "versionNonce": 880138182, - "index": "b5b", - "isDeleted": false, - "id": "biIkmq6M1-AbYwC49DchU", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1222.8123177422422, - "y": 517.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 637054938, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "SvAgMJjSCecYOvANoG3dG" - }, - { - "id": "P8eXnQ0fWxPrXgingEdw3", - "type": "arrow" - }, - { - "id": "AnPGza7YvPH3xfSadx5Rg", - "type": "arrow" - } - ], - "updated": 1731055653369, - "link": null, - "locked": false - }, - { - "id": "SvAgMJjSCecYOvANoG3dG", - "type": "text", - "x": -1209.5122918023008, - "y": 541.0277777777778, - "width": 40.39994812011719, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5c", - "roundness": null, - "seed": 633971866, - "version": 387, - "versionNonce": 1112885658, - "isDeleted": false, - "boundElements": [], - "updated": 1731055204754, - "link": null, - "locked": false, - "text": "/src", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "biIkmq6M1-AbYwC49DchU", - "originalText": "/src", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 732, - "versionNonce": 13191238, - "index": "b5d", - "isDeleted": false, - "id": "fFKy5tObOynPedFPD2PRS", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1555.3123177422422, - "y": 515.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 737169242, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "-54m1gLA0AVIsP96PkIzv" - }, - { - "id": "DPwlqoHuPv3GVitvgwc1M", - "type": "arrow" - }, - { - "id": "_qbUPKxgjTbJSg7_LNG-b", - "type": "arrow" - }, - { - "id": "_hzTfAYCAbcXr7kXl1fvJ", - "type": "arrow" - }, - { - "id": "hblsohrbHKgg-lhiaxcqx", - "type": "arrow" - } - ], - "updated": 1731056055568, - "link": null, - "locked": false - }, - { - "id": "-54m1gLA0AVIsP96PkIzv", - "type": "text", - "x": -1546.3722847832578, - "y": 539.0277777777778, - "width": 49.11993408203125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5e", - "roundness": null, - "seed": 1520522266, - "version": 391, - "versionNonce": 369034330, - "isDeleted": false, - "boundElements": [], - "updated": 1731055368360, - "link": null, - "locked": false, - "text": "/dist", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "fFKy5tObOynPedFPD2PRS", - "originalText": "/dist", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 760, - "versionNonce": 624383066, - "index": "b5f", - "isDeleted": false, - "id": "4fkVXKqFv-NwpgFJJMsia", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1119.8123177422422, - "y": 517.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 2065081478, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "36uCbtB9PCQ32fYpQTMab" - }, - { - "id": "deOaqi_4KA4sN3rpUxOA3", - "type": "arrow" - } - ], - "updated": 1731055983548, - "link": null, - "locked": false - }, - { - "id": "36uCbtB9PCQ32fYpQTMab", - "type": "text", - "x": -1108.432289971246, - "y": 541.0277777777778, - "width": 44.23994445800781, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5g", - "roundness": null, - "seed": 1528570822, - "version": 441, - "versionNonce": 1481427802, - "isDeleted": false, - "boundElements": [], - "updated": 1731055216989, - "link": null, - "locked": false, - "text": "/out", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "4fkVXKqFv-NwpgFJJMsia", - "originalText": "/out", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "g4wNBx2RfVVjDDLEdKI8h", - "type": "ellipse", - "x": -1788.3123177422422, - "y": 747.5277777777778, - "width": 145, - "height": 135, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#b2f2bb", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5l", - "roundness": { - "type": 2 - }, - "seed": 337246106, - "version": 335, - "versionNonce": 31030810, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "OZq-IIAo615oS9zhot4E6" - }, - { - "id": "DPwlqoHuPv3GVitvgwc1M", - "type": "arrow" - }, - { - "id": "BGbyQLUnJB7bMRbTZxG-l", - "type": "arrow" - } - ], - "updated": 1731054182615, - "link": null, - "locked": false - }, - { - "id": "OZq-IIAo615oS9zhot4E6", - "type": "text", - "x": -1732.3455952669387, - "y": 804.7980700476859, - "width": 33.53607177734375, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5m", - "roundness": null, - "seed": 1145681862, - "version": 279, - "versionNonce": 1626778330, - "isDeleted": false, - "boundElements": null, - "updated": 1731054182615, - "link": null, - "locked": false, - "text": "NPM", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "g4wNBx2RfVVjDDLEdKI8h", - "originalText": "NPM", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "DPwlqoHuPv3GVitvgwc1M", - "type": "arrow", - "x": -1513.6650098713615, - "y": 588.5277777777778, - "width": 125.45923001299707, - "height": 232.34648527482761, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#b2f2bb", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5n", - "roundness": { - "type": 2 - }, - "seed": 1292688582, - "version": 635, - "versionNonce": 38295194, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "gDH8G_2XgqjZc0oGlKs1-" - } - ], - "updated": 1731055422318, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -1.6473078708806952, - 214 - ], - [ - -125.45923001299707, - 232.34648527482761 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "fFKy5tObOynPedFPD2PRS", - "focus": -0.24964009599253478, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "g4wNBx2RfVVjDDLEdKI8h", - "focus": 0.2517959719337037, - "gap": 4.442494778923731, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "gDH8G_2XgqjZc0oGlKs1-", - "type": "text", - "x": -1548.6884468926328, - "y": 475.5277777777778, - "width": 148.75225830078125, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#b2f2bb", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5o", - "roundness": null, - "seed": 1486480986, - "version": 32, - "versionNonce": 1025689498, - "isDeleted": false, - "boundElements": null, - "updated": 1731054181443, - "link": null, - "locked": false, - "text": "published when new\nrelease", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "DPwlqoHuPv3GVitvgwc1M", - "originalText": "published when new release", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "BGbyQLUnJB7bMRbTZxG-l", - "type": "arrow", - "x": -1970.434320338538, - "y": 703.5992689214761, - "width": 177.22773451011494, - "height": 115.26460826659184, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#b2f2bb", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5x", - "roundness": { - "type": 2 - }, - "seed": 1453154374, - "version": 1150, - "versionNonce": 1342245274, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "CEpJW8BAS2vdrvoU6tVfz" - } - ], - "updated": 1731055403154, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 13.122002596295943, - 101.92570409594919 - ], - [ - 177.22773451011494, - 115.26460826659184 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "tn6DDDgEFflY4_vkFbEN0", - "focus": 0.03347618995022481, - "gap": 3.0714911436982675, - "fixedPoint": null - }, - "endBinding": { - "elementId": "g4wNBx2RfVVjDDLEdKI8h", - "focus": -0.14945949492668423, - "gap": 5.002790562166368, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "CEpJW8BAS2vdrvoU6tVfz", - "type": "text", - "x": -1483.5403374565976, - "y": 788.5249730174253, - "width": 26.456039428710938, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#b2f2bb", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b5y", - "roundness": null, - "seed": 1440049030, - "version": 41, - "versionNonce": 496589894, - "isDeleted": false, - "boundElements": [], - "updated": 1730989097001, - "link": null, - "locked": false, - "text": "use", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "BGbyQLUnJB7bMRbTZxG-l", - "originalText": "use", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "50LGfz5dcPX3KTXrlb7FK", - "type": "ellipse", - "x": -1686.3123177422422, - "y": -51.47222222222217, - "width": 37, - "height": 35, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "4iLKe3g9M-gZa_0x8q5GB", - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b66V", - "roundness": { - "type": 2 - }, - "seed": 26621146, - "version": 116, - "versionNonce": 1508359450, - "isDeleted": false, - "boundElements": null, - "updated": 1731054243718, - "link": null, - "locked": false - }, - { - "id": "u__O-VFRmuEqXLhaBdYsK", - "type": "rectangle", - "x": -1692.3123177422422, - "y": -17.47222222222217, - "width": 50, - "height": 53, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "hachure", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "4iLKe3g9M-gZa_0x8q5GB", - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b67", - "roundness": { - "type": 3 - }, - "seed": 325273946, - "version": 119, - "versionNonce": 988088794, - "isDeleted": false, - "boundElements": null, - "updated": 1731054243718, - "link": null, - "locked": false - }, - { - "id": "nBECxhMYENhBkfYiXLf1L", - "type": "text", - "x": -1703.3123177422422, - "y": 61.52777777777783, - "width": 75.4481201171875, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b68", - "roundness": null, - "seed": 2028927622, - "version": 100, - "versionNonce": 2094927302, - "isDeleted": false, - "boundElements": [ - { - "id": "sJsyDMW30ryhniXGPCIRj", - "type": "arrow" - }, - { - "id": "HeQZTSM2Ti7H86Eztz-uR", - "type": "arrow" - } - ], - "updated": 1731054266098, - "link": null, - "locked": false, - "text": "Developer", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Developer", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "w6ugwEr_UbAe4sinf9F-F", - "type": "rectangle", - "x": -1550.3123177422422, - "y": 167.52777777777783, - "width": 350, - "height": 64, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6A", - "roundness": { - "type": 3 - }, - "seed": 2030206170, - "version": 77, - "versionNonce": 1951361414, - "isDeleted": false, - "boundElements": null, - "updated": 1731053663314, - "link": null, - "locked": false - }, - { - "type": "rectangle", - "version": 803, - "versionNonce": 971527002, - "index": "b6B", - "isDeleted": false, - "id": "9Zfx_Mh8FlcuveQMImHa6", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1350.8123177422422, - "y": 172.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 95366, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "zZBX33Frp5bsQw5CUHaGt" - }, - { - "id": "9Nj_wk1Af3ZeL0Mlkp7LC", - "type": "arrow" - } - ], - "updated": 1731054069036, - "link": null, - "locked": false - }, - { - "id": "zZBX33Frp5bsQw5CUHaGt", - "type": "text", - "x": -1334.232308281793, - "y": 186.02777777777783, - "width": 33.83998107910156, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6C", - "roundness": null, - "seed": 439153606, - "version": 453, - "versionNonce": 809189382, - "isDeleted": false, - "boundElements": [], - "updated": 1731053663314, - "link": null, - "locked": false, - "text": "dev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "9Zfx_Mh8FlcuveQMImHa6", - "originalText": "dev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 855, - "versionNonce": 1210142534, - "index": "b6D", - "isDeleted": false, - "id": "o5MF60iIlcVQkp8r8aYpc", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1275.8123177422422, - "y": 173.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 354819034, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "gDQGGCtNGSQ3rdoz5qp9t" - } - ], - "updated": 1731053663314, - "link": null, - "locked": false - }, - { - "id": "gDQGGCtNGSQ3rdoz5qp9t", - "type": "text", - "x": -1264.5323037041562, - "y": 187.02777777777783, - "width": 44.439971923828125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6E", - "roundness": null, - "seed": 1263138566, - "version": 509, - "versionNonce": 1862497926, - "isDeleted": false, - "boundElements": [], - "updated": 1731053663314, - "link": null, - "locked": false, - "text": "build", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "o5MF60iIlcVQkp8r8aYpc", - "originalText": "build", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 871, - "versionNonce": 2069689114, - "index": "b6F", - "isDeleted": false, - "id": "9hPRi42SjxVCwCZYmyXKQ", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1544.8123177422422, - "y": 171.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 87, - "height": 52, - "seed": 1006352538, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "_khljADWlZrSrKTBh_y57" - }, - { - "id": "tg_nIP1tVVhexNnfx-0Ue", - "type": "arrow" - } - ], - "updated": 1731053878318, - "link": null, - "locked": false - }, - { - "id": "_khljADWlZrSrKTBh_y57", - "type": "text", - "x": -1536.052277459039, - "y": 185.02777777777783, - "width": 69.47991943359375, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6G", - "roundness": null, - "seed": 1072534874, - "version": 539, - "versionNonce": 770427098, - "isDeleted": false, - "boundElements": [], - "updated": 1731053887606, - "link": null, - "locked": false, - "text": "test:lib", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "9hPRi42SjxVCwCZYmyXKQ", - "originalText": "test:lib", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 925, - "versionNonce": 1442482586, - "index": "b6H", - "isDeleted": false, - "id": "2kgnxcOUmgFerLgcp-3kO", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1448.8123177422422, - "y": 172.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 87, - "height": 49.99999999999999, - "seed": 1723586886, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "-smyNjoXdDvTDPXasoyns" - }, - { - "id": "sJsyDMW30ryhniXGPCIRj", - "type": "arrow" - }, - { - "id": "Hi65Vn3O32yFORZH81pTU", - "type": "arrow" - } - ], - "updated": 1731054035477, - "link": null, - "locked": false - }, - { - "id": "-smyNjoXdDvTDPXasoyns", - "type": "text", - "x": -1440.4122933281797, - "y": 185.02777777777783, - "width": 70.199951171875, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6I", - "roundness": null, - "seed": 767344774, - "version": 602, - "versionNonce": 690111770, - "isDeleted": false, - "boundElements": [], - "updated": 1731053892588, - "link": null, - "locked": false, - "text": "build:lib", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "2kgnxcOUmgFerLgcp-3kO", - "originalText": "build:lib", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "oX9S6SajjSwOYHQ9Df461", - "type": "rectangle", - "x": -1682.3123177422422, - "y": 311.5277777777778, - "width": 298.00000000000006, - "height": 64, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6J", - "roundness": { - "type": 3 - }, - "seed": 601731610, - "version": 115, - "versionNonce": 4638726, - "isDeleted": false, - "boundElements": [], - "updated": 1731053644958, - "link": null, - "locked": false - }, - { - "id": "Sh0Yb7oYu3-FXVpVN3BBF", - "type": "rectangle", - "x": -1369.3123177422422, - "y": 311.5277777777778, - "width": 298.00000000000006, - "height": 64, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6K", - "roundness": { - "type": 3 - }, - "seed": 1204616838, - "version": 162, - "versionNonce": 1336257178, - "isDeleted": false, - "boundElements": [], - "updated": 1731053653513, - "link": null, - "locked": false - }, - { - "id": "ROxdmyuURrBgvzllMF4cM", - "type": "text", - "x": -1243.036377800836, - "y": 149.52777777777783, - "width": 34.79205322265625, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6L", - "roundness": null, - "seed": 1746448730, - "version": 159, - "versionNonce": 2093205126, - "isDeleted": false, - "boundElements": [], - "updated": 1731054046278, - "link": null, - "locked": false, - "text": "root", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "root", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "hIjKdVb8nMm1BVMFcgUyk", - "type": "text", - "x": -1157.7083443535703, - "y": 293.5277777777778, - "width": 81.52815246582031, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6M", - "roundness": null, - "seed": 76236934, - "version": 224, - "versionNonce": 1872998938, - "isDeleted": false, - "boundElements": [], - "updated": 1731054049896, - "link": null, - "locked": false, - "text": "diracx-web", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "diracx-web", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "b6ruibTcdw1FCv1DpKkZR", - "type": "text", - "x": -1467.0763939751523, - "y": 292.5277777777778, - "width": 89.73614501953125, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6N", - "roundness": null, - "seed": 1743599686, - "version": 389, - "versionNonce": 1718106330, - "isDeleted": false, - "boundElements": [], - "updated": 1731055242795, - "link": null, - "locked": false, - "text": "components", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "components", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 908, - "versionNonce": 1020232154, - "index": "b6O", - "isDeleted": false, - "id": "b19-07rPQS5M0bpbFG5u0", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1287.3123177422422, - "y": 318.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 1309411398, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "U_2Y-8a2J6uJAFUE-NCBC" - }, - { - "id": "9Nj_wk1Af3ZeL0Mlkp7LC", - "type": "arrow" - } - ], - "updated": 1731054069035, - "link": null, - "locked": false - }, - { - "id": "U_2Y-8a2J6uJAFUE-NCBC", - "type": "text", - "x": -1270.732308281793, - "y": 331.5277777777778, - "width": 33.83998107910156, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6P", - "roundness": null, - "seed": 959385478, - "version": 558, - "versionNonce": 774429722, - "isDeleted": false, - "boundElements": [], - "updated": 1731053753748, - "link": null, - "locked": false, - "text": "dev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "b19-07rPQS5M0bpbFG5u0", - "originalText": "dev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 960, - "versionNonce": 1202342106, - "index": "b6Q", - "isDeleted": false, - "id": "cMnITXQIi4CesBZinEuBu", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1212.3123177422422, - "y": 319.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 820981446, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "CgeqJgVmKPUtDRj1DP4QG" - } - ], - "updated": 1731053753748, - "link": null, - "locked": false - }, - { - "id": "CgeqJgVmKPUtDRj1DP4QG", - "type": "text", - "x": -1201.0323037041562, - "y": 332.5277777777778, - "width": 44.439971923828125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6R", - "roundness": null, - "seed": 1374250502, - "version": 614, - "versionNonce": 803216794, - "isDeleted": false, - "boundElements": [], - "updated": 1731053753748, - "link": null, - "locked": false, - "text": "build", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "cMnITXQIi4CesBZinEuBu", - "originalText": "build", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1026, - "versionNonce": 1472649498, - "index": "b6S", - "isDeleted": false, - "id": "u704LShIOCjuUkPuoYlZk", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1363.3123177422422, - "y": 318.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 69, - "height": 49.99999999999999, - "seed": 488289606, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "NqHFNY1g2b6d05a777Fgq" - } - ], - "updated": 1731053744257, - "link": null, - "locked": false - }, - { - "id": "NqHFNY1g2b6d05a777Fgq", - "type": "text", - "x": -1350.6722878350156, - "y": 330.5277777777778, - "width": 43.719940185546875, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6T", - "roundness": null, - "seed": 1809849478, - "version": 700, - "versionNonce": 1719707098, - "isDeleted": false, - "boundElements": [], - "updated": 1731053744257, - "link": null, - "locked": false, - "text": "test", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "u704LShIOCjuUkPuoYlZk", - "originalText": "test", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 965, - "versionNonce": 1789477766, - "index": "b6V", - "isDeleted": false, - "id": "3TAR39TJzLe_fpnp6RfSp", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1601.3123177422422, - "y": 318.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 1809995270, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "oTH3wB-CsejySNABkzA15" - } - ], - "updated": 1731053833701, - "link": null, - "locked": false - }, - { - "id": "oTH3wB-CsejySNABkzA15", - "type": "text", - "x": -1584.732308281793, - "y": 331.5277777777778, - "width": 33.83998107910156, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6W", - "roundness": null, - "seed": 1786094918, - "version": 616, - "versionNonce": 486728390, - "isDeleted": false, - "boundElements": [], - "updated": 1731053833701, - "link": null, - "locked": false, - "text": "dev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "3TAR39TJzLe_fpnp6RfSp", - "originalText": "dev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1019, - "versionNonce": 2108573722, - "index": "b6X", - "isDeleted": false, - "id": "eiZCzGMr-QO2-vuoX9aOP", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1526.3123177422422, - "y": 319.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 811404422, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "Bpgssl8pxaWC46E8dORfo" - }, - { - "id": "Hi65Vn3O32yFORZH81pTU", - "type": "arrow" - } - ], - "updated": 1731054035477, - "link": null, - "locked": false - }, - { - "id": "Bpgssl8pxaWC46E8dORfo", - "type": "text", - "x": -1515.0323037041562, - "y": 332.5277777777778, - "width": 44.439971923828125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6Y", - "roundness": null, - "seed": 1800768454, - "version": 672, - "versionNonce": 919693638, - "isDeleted": false, - "boundElements": [], - "updated": 1731053833701, - "link": null, - "locked": false, - "text": "build", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "eiZCzGMr-QO2-vuoX9aOP", - "originalText": "build", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1085, - "versionNonce": 842691738, - "index": "b6Z", - "isDeleted": false, - "id": "pRiKEE-VOiDJOW3kWZkBJ", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1677.3123177422422, - "y": 318.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 69, - "height": 49.99999999999999, - "seed": 159130374, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "bebn0eQaU8472SN3P33y-" - }, - { - "id": "tg_nIP1tVVhexNnfx-0Ue", - "type": "arrow" - } - ], - "updated": 1731053878318, - "link": null, - "locked": false - }, - { - "id": "bebn0eQaU8472SN3P33y-", - "type": "text", - "x": -1664.6722878350156, - "y": 330.5277777777778, - "width": 43.719940185546875, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6a", - "roundness": null, - "seed": 760074822, - "version": 758, - "versionNonce": 1586515910, - "isDeleted": false, - "boundElements": [], - "updated": 1731053833701, - "link": null, - "locked": false, - "text": "test", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "pRiKEE-VOiDJOW3kWZkBJ", - "originalText": "test", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "sJsyDMW30ryhniXGPCIRj", - "type": "arrow", - "x": -1620.8641976250547, - "y": 89.75702931345339, - "width": 247.5518798828125, - "height": 78.77074846432444, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6b", - "roundness": { - "type": 2 - }, - "seed": 1537709638, - "version": 294, - "versionNonce": 923726342, - "isDeleted": false, - "boundElements": null, - "updated": 1731054588502, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 191.5518798828125, - 25.77074846432444 - ], - [ - 247.5518798828125, - 78.77074846432444 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "nBECxhMYENhBkfYiXLf1L", - "focus": 0.8100834881854987, - "gap": 8.229251535675559, - "fixedPoint": null - }, - "endBinding": { - "elementId": "2kgnxcOUmgFerLgcp-3kO", - "focus": 0.8959654567534745, - "gap": 4, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "tg_nIP1tVVhexNnfx-0Ue", - "type": "arrow", - "x": -1498.3123177422422, - "y": 222.52777777777783, - "width": 147, - "height": 95, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6c", - "roundness": { - "type": 2 - }, - "seed": 791920262, - "version": 251, - "versionNonce": 921421786, - "isDeleted": false, - "boundElements": null, - "updated": 1731054020962, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -147, - 95 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9hPRi42SjxVCwCZYmyXKQ", - "focus": -0.49783141617952104, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "pRiKEE-VOiDJOW3kWZkBJ", - "focus": -0.5733189500179792, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "Hi65Vn3O32yFORZH81pTU", - "type": "arrow", - "x": -1403.8123177422422, - "y": 222.02777777777783, - "width": 89, - "height": 96, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6d", - "roundness": { - "type": 2 - }, - "seed": 1891969158, - "version": 309, - "versionNonce": 1581542170, - "isDeleted": false, - "boundElements": [], - "updated": 1731054036703, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -89, - 96 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "2kgnxcOUmgFerLgcp-3kO", - "focus": -0.36314638337759725, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "eiZCzGMr-QO2-vuoX9aOP", - "focus": -0.4345388788426763, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "9Nj_wk1Af3ZeL0Mlkp7LC", - "type": "arrow", - "x": -1315.8123177422422, - "y": 223.52777777777783, - "width": 61, - "height": 95, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6e", - "roundness": { - "type": 2 - }, - "seed": 171021574, - "version": 412, - "versionNonce": 478389722, - "isDeleted": false, - "boundElements": [], - "updated": 1731054078346, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 61, - 95 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9Zfx_Mh8FlcuveQMImHa6", - "focus": 0.2899234560134214, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "b19-07rPQS5M0bpbFG5u0", - "focus": 0.30628080109048966, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "MhrOplKQaNCnFZRp9BgrH", - "type": "arrow", - "x": -1241.8123177422422, - "y": 223.02777777777783, - "width": 61, - "height": 95, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6f", - "roundness": { - "type": 2 - }, - "seed": 230015814, - "version": 456, - "versionNonce": 1894587290, - "isDeleted": false, - "boundElements": [], - "updated": 1731054088793, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 61, - 95 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "xXKOs-seOqtncQzCwURmw", - "type": "rectangle", - "x": -2103.312317742242, - "y": 164.52777777777783, - "width": 298.00000000000006, - "height": 66, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6g", - "roundness": { - "type": 3 - }, - "seed": 1847090182, - "version": 400, - "versionNonce": 2012231130, - "isDeleted": false, - "boundElements": [], - "updated": 1731054712244, - "link": null, - "locked": false - }, - { - "id": "SR0rFwiB9aSPHrhPLW6PX", - "type": "text", - "x": -1867.7083443535703, - "y": 146.52777777777783, - "width": 56.72810363769531, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6h", - "roundness": null, - "seed": 66775878, - "version": 373, - "versionNonce": 2091657370, - "isDeleted": false, - "boundElements": [], - "updated": 1731054303771, - "link": null, - "locked": false, - "text": "gubbins", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "gubbins", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1030, - "versionNonce": 604580422, - "index": "b6hV", - "isDeleted": false, - "id": "t0AGE6WyohgpIFBXS_HeO", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2021.3123177422422, - "y": 171.02777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 894014086, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "DDYUN0JBjnJfIlXkpw1Fg" - }, - { - "id": "HeQZTSM2Ti7H86Eztz-uR", - "type": "arrow" - } - ], - "updated": 1731054863487, - "link": null, - "locked": false - }, - { - "id": "DDYUN0JBjnJfIlXkpw1Fg", - "type": "text", - "x": -2004.732308281793, - "y": 184.52777777777783, - "width": 33.83998107910156, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6i", - "roundness": null, - "seed": 1824608710, - "version": 679, - "versionNonce": 1546257690, - "isDeleted": false, - "boundElements": [], - "updated": 1731054863487, - "link": null, - "locked": false, - "text": "dev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "t0AGE6WyohgpIFBXS_HeO", - "originalText": "dev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1079, - "versionNonce": 998110938, - "index": "b6k", - "isDeleted": false, - "id": "lF03HSD_XntvzBSp_We3A", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1946.3123177422422, - "y": 172.02777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 52, - "seed": 897526022, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "8IUdvaFBQ27JG_al7x3Wn" - }, - { - "id": "HeQZTSM2Ti7H86Eztz-uR", - "type": "arrow" - } - ], - "updated": 1731054303771, - "link": null, - "locked": false - }, - { - "id": "8IUdvaFBQ27JG_al7x3Wn", - "type": "text", - "x": -1935.0323037041562, - "y": 185.52777777777783, - "width": 44.439971923828125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6l", - "roundness": null, - "seed": 788535366, - "version": 732, - "versionNonce": 151915418, - "isDeleted": false, - "boundElements": [], - "updated": 1731054303771, - "link": null, - "locked": false, - "text": "build", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "lF03HSD_XntvzBSp_We3A", - "originalText": "build", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "HeQZTSM2Ti7H86Eztz-uR", - "type": "arrow", - "x": -1713.5882576836484, - "y": 88.14240354561562, - "width": 241.0587499464525, - "height": 70.16131417356846, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6o", - "roundness": { - "type": 2 - }, - "seed": 410455750, - "version": 484, - "versionNonce": 1463284102, - "isDeleted": false, - "boundElements": [], - "updated": 1731054863488, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -184.4481201171875, - 35.77074846432444 - ], - [ - -241.0587499464525, - 70.16131417356846 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "nBECxhMYENhBkfYiXLf1L", - "focus": -0.421910816777021, - "gap": 10.27593994140625, - "fixedPoint": null - }, - "endBinding": { - "elementId": "t0AGE6WyohgpIFBXS_HeO", - "focus": -0.4007757442196045, - "gap": 12.72406005859375, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "type": "rectangle", - "version": 805, - "versionNonce": 1642569350, - "index": "b6r", - "isDeleted": false, - "id": "keTYDQ3f38ozPSYyupcH5", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2064.812317742242, - "y": 513.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 1036357894, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "3asqEympqcOw5_5waImEL" - } - ], - "updated": 1731054542480, - "link": null, - "locked": false - }, - { - "id": "3asqEympqcOw5_5waImEL", - "type": "text", - "x": -2051.5122918023008, - "y": 537.0277777777778, - "width": 40.39994812011719, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6s", - "roundness": null, - "seed": 842629190, - "version": 469, - "versionNonce": 1908268486, - "isDeleted": false, - "boundElements": [], - "updated": 1731054542480, - "link": null, - "locked": false, - "text": "/src", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "keTYDQ3f38ozPSYyupcH5", - "originalText": "/src", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 812, - "versionNonce": 742995334, - "index": "b6t", - "isDeleted": false, - "id": "ZZUe4Odn-3_lwAoSoUWbS", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2064.812317742242, - "y": 513.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 832833114, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "tbFMb7NJrNFGiOlvonF9o" - }, - { - "id": "uEfEj64halCMaXY7lqSUC", - "type": "arrow" - }, - { - "id": "Tr-NjiGlVgICeQMaU8nni", - "type": "arrow" - }, - { - "id": "Y69YtsVpN0Wf7AY9Gay4L", - "type": "arrow" - } - ], - "updated": 1731054979871, - "link": null, - "locked": false - }, - { - "id": "tbFMb7NJrNFGiOlvonF9o", - "type": "text", - "x": -2051.5122918023008, - "y": 537.0277777777778, - "width": 40.39994812011719, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6u", - "roundness": null, - "seed": 2126916378, - "version": 471, - "versionNonce": 477481670, - "isDeleted": false, - "boundElements": [], - "updated": 1731054544882, - "link": null, - "locked": false, - "text": "/src", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "ZZUe4Odn-3_lwAoSoUWbS", - "originalText": "/src", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 853, - "versionNonce": 67085126, - "index": "b6v", - "isDeleted": false, - "id": "4jVyNLHW2mVA5L_Ao51CI", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1957.8123177422422, - "y": 514.5277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 67, - "height": 72, - "seed": 1193031814, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "jqNcwjkWjnnuI4iTdLY-z" - }, - { - "id": "Pi-5ePOlDA0bjITH8azwa", - "type": "arrow" - } - ], - "updated": 1731055059124, - "link": null, - "locked": false - }, - { - "id": "jqNcwjkWjnnuI4iTdLY-z", - "type": "text", - "x": -1946.432289971246, - "y": 538.0277777777778, - "width": 44.23994445800781, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6w", - "roundness": null, - "seed": 961492934, - "version": 522, - "versionNonce": 1844069082, - "isDeleted": false, - "boundElements": [], - "updated": 1731054558214, - "link": null, - "locked": false, - "text": "/out", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "4jVyNLHW2mVA5L_Ao51CI", - "originalText": "/out", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1126, - "versionNonce": 850808326, - "index": "b6z", - "isDeleted": false, - "id": "NRzryVpuz64_O4gz0UfCB", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2023.8123177422422, - "y": 209.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 466712198, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "XIY2d8yaitNYAd1mL9Rd6" - }, - { - "id": "uEfEj64halCMaXY7lqSUC", - "type": "arrow" - } - ], - "updated": 1731054896366, - "link": null, - "locked": false - }, - { - "id": "XIY2d8yaitNYAd1mL9Rd6", - "type": "text", - "x": -2010.8523033989804, - "y": 220.52777777777783, - "width": 45.07997131347656, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b70", - "roundness": null, - "seed": 11318726, - "version": 798, - "versionNonce": 290480474, - "isDeleted": false, - "boundElements": [], - "updated": 1731054845507, - "link": null, - "locked": false, - "text": "next\ndev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "NRzryVpuz64_O4gz0UfCB", - "originalText": "next\ndev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1167, - "versionNonce": 1291323846, - "index": "b71", - "isDeleted": false, - "id": "6l1eeATXcZ-vkygiKI8jW", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1947.8123177422422, - "y": 210.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 747466842, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "3s44d9xDUkhrPLsM1rEP3" - }, - { - "id": "Y69YtsVpN0Wf7AY9Gay4L", - "type": "arrow" - }, - { - "id": "Pi-5ePOlDA0bjITH8azwa", - "type": "arrow" - } - ], - "updated": 1731055059124, - "link": null, - "locked": false - }, - { - "id": "3s44d9xDUkhrPLsM1rEP3", - "type": "text", - "x": -1934.8523033989804, - "y": 221.52777777777783, - "width": 45.07997131347656, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b72", - "roundness": null, - "seed": 1827820826, - "version": 846, - "versionNonce": 21545114, - "isDeleted": false, - "boundElements": [], - "updated": 1731054849667, - "link": null, - "locked": false, - "text": "next\nbuild", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "6l1eeATXcZ-vkygiKI8jW", - "originalText": "next\nbuild", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "Tr-NjiGlVgICeQMaU8nni", - "type": "arrow", - "x": -2071.7810536542333, - "y": 282.44712069099353, - "width": 32.765095654791494, - "height": 230.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b73", - "roundness": { - "type": 2 - }, - "seed": 1123973658, - "version": 1239, - "versionNonce": 1841157958, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "Byi0VwoSdaufjF7q1uTQt" - } - ], - "updated": 1731055565687, - "link": null, - "locked": false, - "points": [ - [ - 1.7950304716238108, - 0 - ], - [ - -20.064453458373098, - 106.77074846432447 - ], - [ - 12.7006421964184, - 230.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "4n39BTYTgjG_l0RbuOnfu", - "focus": -0.02064125061960976, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "ZZUe4Odn-3_lwAoSoUWbS", - "focus": -0.4172034332028844, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "Byi0VwoSdaufjF7q1uTQt", - "type": "text", - "x": -2067.836342705621, - "y": 367.217869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b74", - "roundness": null, - "seed": 740042458, - "version": 11, - "versionNonce": 1962871066, - "isDeleted": false, - "boundElements": [], - "updated": 1731054913475, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Tr-NjiGlVgICeQMaU8nni", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1147, - "versionNonce": 1781238790, - "index": "b75", - "isDeleted": false, - "id": "bDZvJSkjTBN3sYJa7c6r4", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2097.312317742242, - "y": 171.02777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffc9c9", - "width": 69, - "height": 49.99999999999999, - "seed": 18947974, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "gEzpbKL83UnS6A18gt0eV" - } - ], - "updated": 1731054835128, - "link": null, - "locked": false - }, - { - "id": "gEzpbKL83UnS6A18gt0eV", - "type": "text", - "x": -2084.6722878350156, - "y": 183.52777777777783, - "width": 43.719940185546875, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b76", - "roundness": null, - "seed": 1344224966, - "version": 819, - "versionNonce": 1227333466, - "isDeleted": false, - "boundElements": [], - "updated": 1731054835128, - "link": null, - "locked": false, - "text": "test", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "bDZvJSkjTBN3sYJa7c6r4", - "originalText": "test", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1116, - "versionNonce": 1159767130, - "index": "b77", - "isDeleted": false, - "id": "4n39BTYTgjG_l0RbuOnfu", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -2098.812317742242, - "y": 209.52777777777783, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 541001222, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "ToxIVSSpl_6VH2R4R1Sq-" - }, - { - "id": "Tr-NjiGlVgICeQMaU8nni", - "type": "arrow" - } - ], - "updated": 1731054913474, - "link": null, - "locked": false - }, - { - "id": "ToxIVSSpl_6VH2R4R1Sq-", - "type": "text", - "x": -2088.442299736871, - "y": 220.52777777777783, - "width": 50.25996398925781, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b78", - "roundness": null, - "seed": 1337742662, - "version": 775, - "versionNonce": 1631789914, - "isDeleted": false, - "boundElements": [], - "updated": 1731054867929, - "link": null, - "locked": false, - "text": "cypre\nss", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "4n39BTYTgjG_l0RbuOnfu", - "originalText": "cypress", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "uEfEj64halCMaXY7lqSUC", - "type": "arrow", - "x": -1986.0793246649437, - "y": 280.94712069099353, - "width": 46.58693373782353, - "height": 231.5806570867843, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b79", - "roundness": { - "type": 2 - }, - "seed": 758014982, - "version": 1259, - "versionNonce": 1356553690, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "riGeD1OgWPwdTpaXKSZm1" - } - ], - "updated": 1731055571138, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -46.58693373782353, - 109.77074846432447 - ], - [ - -41.867467237523215, - 231.5806570867843 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "NRzryVpuz64_O4gz0UfCB", - "focus": -0.34000697881092595, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "ZZUe4Odn-3_lwAoSoUWbS", - "focus": 0.1375297385668849, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "riGeD1OgWPwdTpaXKSZm1", - "type": "text", - "x": -2043.190283366146, - "y": 380.717869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b79G", - "roundness": null, - "seed": 1388071130, - "version": 10, - "versionNonce": 789084506, - "isDeleted": false, - "boundElements": null, - "updated": 1731055330784, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "uEfEj64halCMaXY7lqSUC", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "Y69YtsVpN0Wf7AY9Gay4L", - "type": "arrow", - "x": -1933.2688508733304, - "y": 282.7374492343857, - "width": 69.86746723752321, - "height": 228.58065708678436, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7B", - "roundness": { - "type": 2 - }, - "seed": 1732037510, - "version": 1339, - "versionNonce": 24177882, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "ARB9gHROn46vAvet-MeBO" - } - ], - "updated": 1731056035348, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -12.586933737823529, - 108.77074846432447 - ], - [ - -69.86746723752321, - 228.58065708678436 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "6l1eeATXcZ-vkygiKI8jW", - "focus": 0.42268925358207843, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "ZZUe4Odn-3_lwAoSoUWbS", - "focus": 0.19538283492156297, - "gap": 2.2096714566077935, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "ARB9gHROn46vAvet-MeBO", - "type": "text", - "x": -1976.9958145183805, - "y": 382.50819769871015, - "width": 44.280059814453125, - "height": 20, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7C", - "roundness": null, - "seed": 1306880710, - "version": 15, - "versionNonce": 1006921158, - "isDeleted": false, - "boundElements": [], - "updated": 1731056035348, - "link": null, - "locked": false, - "text": "needs", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Y69YtsVpN0Wf7AY9Gay4L", - "originalText": "needs", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "Pi-5ePOlDA0bjITH8azwa", - "type": "arrow", - "x": -1913.7253840044186, - "y": 281.44712069099353, - "width": 37.76809371557101, - "height": 228.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7D", - "roundness": { - "type": 2 - }, - "seed": 533168326, - "version": 1274, - "versionNonce": 1589994650, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "JJO3wxwcEQaaVlZCNSgjm" - } - ], - "updated": 1731055575219, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 31.41306626217647, - 110.77074846432447 - ], - [ - -6.355027453394541, - 228.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "6l1eeATXcZ-vkygiKI8jW", - "focus": 0.24755927659791802, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "4jVyNLHW2mVA5L_Ao51CI", - "focus": -0.19815061892855054, - "gap": 4.919342913215814, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "JJO3wxwcEQaaVlZCNSgjm", - "type": "text", - "x": -1941.2283562554258, - "y": 381.217869155318, - "width": 43.83207702636719, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7E", - "roundness": null, - "seed": 635926534, - "version": 22, - "versionNonce": 1646036038, - "isDeleted": false, - "boundElements": [], - "updated": 1731055064025, - "link": null, - "locked": false, - "text": "builds", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Pi-5ePOlDA0bjITH8azwa", - "originalText": "builds", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1194, - "versionNonce": 1426410630, - "index": "b7F", - "isDeleted": false, - "id": "9UasxBv_zw9sgDEo6rnSP", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1289.3123177422422, - "y": 356.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 512121498, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "pFGNsPGVJb-NyoquDgXHy" - }, - { - "id": "AnPGza7YvPH3xfSadx5Rg", - "type": "arrow" - }, - { - "id": "sgAHzm6_jegP9Leo-D-JD", - "type": "arrow" - } - ], - "updated": 1731055916948, - "link": null, - "locked": false - }, - { - "id": "pFGNsPGVJb-NyoquDgXHy", - "type": "text", - "x": -1276.3523033989804, - "y": 367.0277777777778, - "width": 45.07997131347656, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7G", - "roundness": null, - "seed": 2094266202, - "version": 864, - "versionNonce": 674636614, - "isDeleted": false, - "boundElements": [], - "updated": 1731055184232, - "link": null, - "locked": false, - "text": "next\ndev", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "9UasxBv_zw9sgDEo6rnSP", - "originalText": "next\ndev", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1235, - "versionNonce": 1423454554, - "index": "b7H", - "isDeleted": false, - "id": "AT88pV1DqabMR0SbCuGQS", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1213.3123177422422, - "y": 357.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 550501402, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "K9zebPMmlO3hslY7CR8eE" - }, - { - "id": "deOaqi_4KA4sN3rpUxOA3", - "type": "arrow" - }, - { - "id": "hblsohrbHKgg-lhiaxcqx", - "type": "arrow" - } - ], - "updated": 1731056058818, - "link": null, - "locked": false - }, - { - "id": "K9zebPMmlO3hslY7CR8eE", - "type": "text", - "x": -1200.3523033989804, - "y": 368.0277777777778, - "width": 45.07997131347656, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7I", - "roundness": null, - "seed": 409823450, - "version": 912, - "versionNonce": 898533830, - "isDeleted": false, - "boundElements": [], - "updated": 1731055184232, - "link": null, - "locked": false, - "text": "next\nbuild", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "AT88pV1DqabMR0SbCuGQS", - "originalText": "next\nbuild", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1183, - "versionNonce": 1019050394, - "index": "b7J", - "isDeleted": false, - "id": "F-HeMY1ASMbERXj1bw9Wf", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1364.3123177422422, - "y": 356.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 994000282, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "Wfyix6XOcNTCvx5iBDcMW" - }, - { - "id": "P8eXnQ0fWxPrXgingEdw3", - "type": "arrow" - } - ], - "updated": 1731055633982, - "link": null, - "locked": false - }, - { - "id": "Wfyix6XOcNTCvx5iBDcMW", - "type": "text", - "x": -1353.942299736871, - "y": 367.0277777777778, - "width": 50.25996398925781, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7K", - "roundness": null, - "seed": 1987607130, - "version": 841, - "versionNonce": 534728774, - "isDeleted": false, - "boundElements": [], - "updated": 1731055184232, - "link": null, - "locked": false, - "text": "cypre\nss", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "F-HeMY1ASMbERXj1bw9Wf", - "originalText": "cypress", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1306, - "versionNonce": 523114650, - "index": "b7L", - "isDeleted": false, - "id": "izwxgiHZgqo3FN4PUYsZF", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1603.3123177422422, - "y": 356.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72.00000000000001, - "seed": 905773766, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "cFyc1GgESnlanNBK_AQhM" - }, - { - "id": "QLiEWw7s-N1dUpDPKX0nY", - "type": "arrow" - }, - { - "id": "_qbUPKxgjTbJSg7_LNG-b", - "type": "arrow" - } - ], - "updated": 1731055508195, - "link": null, - "locked": false - }, - { - "id": "cFyc1GgESnlanNBK_AQhM", - "type": "text", - "x": -1596.442284478082, - "y": 367.0277777777778, - "width": 57.25993347167969, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7M", - "roundness": null, - "seed": 505199110, - "version": 1001, - "versionNonce": 86788378, - "isDeleted": false, - "boundElements": [], - "updated": 1731055294739, - "link": null, - "locked": false, - "text": "tsup\nwatch", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "izwxgiHZgqo3FN4PUYsZF", - "originalText": "tsup\nwatch", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1330, - "versionNonce": 1885787290, - "index": "b7N", - "isDeleted": false, - "id": "yb05I4bvgXWlsP0dzN_fL", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1527.3123177422422, - "y": 357.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 801343814, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "7282rO11KXUdM6iynlIJa" - }, - { - "id": "_hzTfAYCAbcXr7kXl1fvJ", - "type": "arrow" - } - ], - "updated": 1731055527723, - "link": null, - "locked": false - }, - { - "id": "7282rO11KXUdM6iynlIJa", - "type": "text", - "x": -1513.7522972954648, - "y": 380.5277777777778, - "width": 43.87995910644531, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7O", - "roundness": null, - "seed": 1515090054, - "version": 1013, - "versionNonce": 685512090, - "isDeleted": false, - "boundElements": [], - "updated": 1731055287982, - "link": null, - "locked": false, - "text": "tsup", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "yb05I4bvgXWlsP0dzN_fL", - "originalText": "tsup", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1279, - "versionNonce": 1682511066, - "index": "b7P", - "isDeleted": false, - "id": "MUmDcI6YveP7TP8bGnZft", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1678.3123177422422, - "y": 356.0277777777778, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "width": 71, - "height": 72, - "seed": 427454406, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "Va6S-zmRQXcWZFyltsn4g" - }, - { - "id": "n1wTa1lENuGHRCmAdKxUj", - "type": "arrow" - } - ], - "updated": 1731055461310, - "link": null, - "locked": false - }, - { - "id": "Va6S-zmRQXcWZFyltsn4g", - "type": "text", - "x": -1663.3923043145078, - "y": 379.5277777777778, - "width": 41.15997314453125, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7Q", - "roundness": null, - "seed": 1768195846, - "version": 942, - "versionNonce": 1042786630, - "isDeleted": false, - "boundElements": [], - "updated": 1731055262804, - "link": null, - "locked": false, - "text": "jest", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "MUmDcI6YveP7TP8bGnZft", - "originalText": "jest", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "n1wTa1lENuGHRCmAdKxUj", - "type": "arrow", - "x": -1642.9303535327945, - "y": 428.44712069099353, - "width": 28.381964209447233, - "height": 81.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7R", - "roundness": { - "type": 2 - }, - "seed": 690021594, - "version": 1365, - "versionNonce": 1560755738, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "Qwi_j8P-s5-W40zOq6nO0" - } - ], - "updated": 1731055548874, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -28.381964209447233, - 35.77074846432447 - ], - [ - -11.965948584447233, - 81.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "MUmDcI6YveP7TP8bGnZft", - "focus": -0.4492165915657408, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "tWiUojbB6PTh1owJD7ZTg", - "focus": -0.12435642786094984, - "gap": 4.919342913215814, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "Qwi_j8P-s5-W40zOq6nO0", - "type": "text", - "x": -2085.8363427056206, - "y": 324.217869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7S", - "roundness": null, - "seed": 1612921242, - "version": 15, - "versionNonce": 1451572102, - "isDeleted": false, - "boundElements": [], - "updated": 1731055454511, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "n1wTa1lENuGHRCmAdKxUj", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "QLiEWw7s-N1dUpDPKX0nY", - "type": "arrow", - "x": -1568.930353532795, - "y": 428.94712069099353, - "width": 47.96594858444723, - "height": 82.16131417356848, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7T", - "roundness": { - "type": 2 - }, - "seed": 1734437786, - "version": 1453, - "versionNonce": 1870244314, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "jjo3qu1YqzGJvJ8igJV-S" - } - ], - "updated": 1731056023726, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -46.38196420944723, - 33.77074846432447 - ], - [ - -47.96594858444723, - 82.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "izwxgiHZgqo3FN4PUYsZF", - "focus": -0.5837786955994152, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "tWiUojbB6PTh1owJD7ZTg", - "focus": 0.46500672750403754, - "gap": 3.4193429132158144, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "jjo3qu1YqzGJvJ8igJV-S", - "type": "text", - "x": -1624.0123757256406, - "y": 453.717869155318, - "width": 63.400115966796875, - "height": 20, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7U", - "roundness": null, - "seed": 2049239130, - "version": 31, - "versionNonce": 498202822, - "isDeleted": false, - "boundElements": [], - "updated": 1731056023726, - "link": null, - "locked": false, - "text": "watches", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "QLiEWw7s-N1dUpDPKX0nY", - "originalText": "watches", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "_qbUPKxgjTbJSg7_LNG-b", - "type": "arrow", - "x": -1567.930353532795, - "y": 429.94712069099353, - "width": 52.61803579055277, - "height": 86.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7V", - "roundness": { - "type": 2 - }, - "seed": 264713050, - "version": 1486, - "versionNonce": 27497606, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "8v0m3exNT9xdAjsSUrNsZ" - } - ], - "updated": 1731055541252, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 52.61803579055277, - 31.77074846432447 - ], - [ - 46.03405141555277, - 86.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "izwxgiHZgqo3FN4PUYsZF", - "focus": 0.6614553605992297, - "gap": 1.9193429132157007, - "fixedPoint": null - }, - "endBinding": { - "elementId": "fFKy5tObOynPedFPD2PRS", - "focus": -0.11547156757258278, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "8v0m3exNT9xdAjsSUrNsZ", - "type": "text", - "x": -1555.2283562554258, - "y": 452.717869155318, - "width": 43.83207702636719, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7W", - "roundness": null, - "seed": 1778104346, - "version": 26, - "versionNonce": 52786842, - "isDeleted": false, - "boundElements": [], - "updated": 1731055515977, - "link": null, - "locked": false, - "text": "builds", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "_qbUPKxgjTbJSg7_LNG-b", - "originalText": "builds", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "_hzTfAYCAbcXr7kXl1fvJ", - "type": "arrow", - "x": -1491.5793548941106, - "y": 426.44712069099353, - "width": 38.583984375, - "height": 90.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7X", - "roundness": { - "type": 2 - }, - "seed": 2037406106, - "version": 1558, - "versionNonce": 1298161242, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "2lktIsI4qJN2IbdOhaVRU" - } - ], - "updated": 1731055536506, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 32.61803579055277, - 34.77074846432447 - ], - [ - -5.965948584447233, - 90.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "yb05I4bvgXWlsP0dzN_fL", - "focus": 0.4492103930481892, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "fFKy5tObOynPedFPD2PRS", - "focus": -0.0009750742786248954, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "2lktIsI4qJN2IbdOhaVRU", - "type": "text", - "x": -1537.8773576167414, - "y": 478.217869155318, - "width": 43.83207702636719, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7Y", - "roundness": null, - "seed": 136713818, - "version": 30, - "versionNonce": 1507900102, - "isDeleted": false, - "boundElements": [], - "updated": 1731055521789, - "link": null, - "locked": false, - "text": "builds", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "_hzTfAYCAbcXr7kXl1fvJ", - "originalText": "builds", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "P8eXnQ0fWxPrXgingEdw3", - "type": "arrow", - "x": -1327.3593231558293, - "y": 429.94712069099353, - "width": 109.03405141555277, - "height": 90.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7Z", - "roundness": { - "type": 2 - }, - "seed": 155739802, - "version": 1462, - "versionNonce": 1560372102, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "xZBcZKDmTRR2hN5n37-4r" - } - ], - "updated": 1731055639650, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 32.61803579055277, - 29.77074846432447 - ], - [ - 109.03405141555277, - 90.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "F-HeMY1ASMbERXj1bw9Wf", - "focus": 0.5349791307593924, - "gap": 1.9193429132157007, - "fixedPoint": null - }, - "endBinding": { - "elementId": "biIkmq6M1-AbYwC49DchU", - "focus": 0.1679208554406519, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "xZBcZKDmTRR2hN5n37-4r", - "type": "text", - "x": -1692.2653123286555, - "y": 464.717869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7a", - "roundness": null, - "seed": 1534362458, - "version": 19, - "versionNonce": 899603910, - "isDeleted": false, - "boundElements": [], - "updated": 1731055626114, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "P8eXnQ0fWxPrXgingEdw3", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "AnPGza7YvPH3xfSadx5Rg", - "type": "arrow", - "x": -1252.8293434500188, - "y": 429.44712069099353, - "width": 58.03405141555277, - "height": 85.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7b", - "roundness": { - "type": 2 - }, - "seed": 983402822, - "version": 1577, - "versionNonce": 1080250182, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "iXNRvPfcKni_FpDn2zSRl" - } - ], - "updated": 1731055663523, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 20.618035790552767, - 31.77074846432447 - ], - [ - 58.03405141555277, - 85.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "9UasxBv_zw9sgDEo6rnSP", - "focus": 0.395850074298146, - "gap": 1.4193429132157007, - "fixedPoint": null - }, - "endBinding": { - "elementId": "biIkmq6M1-AbYwC49DchU", - "focus": 0.3710557133944434, - "gap": 2.9193429132158144, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "iXNRvPfcKni_FpDn2zSRl", - "type": "text", - "x": -1306.735332622845, - "y": 455.217869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7c", - "roundness": null, - "seed": 2045276294, - "version": 23, - "versionNonce": 1742066778, - "isDeleted": false, - "boundElements": [], - "updated": 1731055648496, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "AnPGza7YvPH3xfSadx5Rg", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "deOaqi_4KA4sN3rpUxOA3", - "type": "arrow", - "x": -1173.3293434500188, - "y": 427.94712069099353, - "width": 90.03405141555277, - "height": 90.16131417356848, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7d", - "roundness": { - "type": 2 - }, - "seed": 1115531866, - "version": 1654, - "versionNonce": 1263160198, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "nYLKHKBB8hUn_GAHrioee" - } - ], - "updated": 1731055990423, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 39.61803579055277, - 35.77074846432447 - ], - [ - 90.03405141555277, - 90.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "AT88pV1DqabMR0SbCuGQS", - "focus": 0.4536447110407476, - "gap": 1, - "fixedPoint": null - }, - "endBinding": { - "elementId": "4fkVXKqFv-NwpgFJJMsia", - "focus": 0.5360922298017161, - "gap": 1, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "nYLKHKBB8hUn_GAHrioee", - "type": "text", - "x": -1233.235332622845, - "y": 469.717869155318, - "width": 35.04804992675781, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7e", - "roundness": null, - "seed": 214650650, - "version": 27, - "versionNonce": 963943942, - "isDeleted": false, - "boundElements": [], - "updated": 1731055975580, - "link": null, - "locked": false, - "text": "uses", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "deOaqi_4KA4sN3rpUxOA3", - "originalText": "uses", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "hblsohrbHKgg-lhiaxcqx", - "type": "arrow", - "x": -1174.7846777850937, - "y": 430.94712069099353, - "width": 310.05527991429653, - "height": 116.16131417356848, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 1, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7f", - "roundness": { - "type": 2 - }, - "seed": 2016325594, - "version": 1961, - "versionNonce": 1573491354, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "xeM7s4-p0r3WOgjSZaYay" - } - ], - "updated": 1731056105734, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -208.1493881581623, - 80.77592380375165 - ], - [ - -310.05527991429653, - 116.16131417356848 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "AT88pV1DqabMR0SbCuGQS", - "focus": -0.7853980026848522, - "gap": 1.9193429132157007, - "fixedPoint": null - }, - "endBinding": { - "elementId": "fFKy5tObOynPedFPD2PRS", - "focus": 0.17674501519934474, - "gap": 3.4723600428519603, - "fixedPoint": null - }, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "xeM7s4-p0r3WOgjSZaYay", - "type": "text", - "x": -1374.0740958504825, - "y": 513.7230444947452, - "width": 44.280059814453125, - "height": 20, - "angle": 0, - "strokeColor": "#868e96", - "backgroundColor": "#ffec99", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7g", - "roundness": null, - "seed": 1094689946, - "version": 91, - "versionNonce": 2094358810, - "isDeleted": false, - "boundElements": [], - "updated": 1731056087292, - "link": null, - "locked": false, - "text": "needs", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "hblsohrbHKgg-lhiaxcqx", - "originalText": "needs", - "autoResize": true, - "lineHeight": 1.25 - } - ], - "appState": { - "gridSize": 20, - "gridStep": 5, - "gridModeEnabled": false, - "viewBackgroundColor": "#ffffff" - }, - "files": {} -} \ No newline at end of file diff --git a/docs/dependencies&commands.png b/docs/dependencies&commands.png deleted file mode 100644 index 1e95dd6b..00000000 Binary files a/docs/dependencies&commands.png and /dev/null differ diff --git a/docs/developer/contribute.md b/docs/developer/contribute.md new file mode 100644 index 00000000..801b8c60 --- /dev/null +++ b/docs/developer/contribute.md @@ -0,0 +1,43 @@ +# Contributing to DiracX-Web + +### 1. Open an Issue + +- **Discuss Before Implementing:** Before making a pull request (PR), especially for non-trivial changes, please [open an issue](https://github.com/DIRACGrid/diracx-web/issues) to discuss your idea. This ensures that everyone is aligned on the proposed change. +- **Check for Existing Issues:** Before opening a new issue, please check if a similar issue already exists. If a similar issue exists, consider contributing to the discussion there instead. + +**Good to know:** If you want to start contributing right away, check out the issues labeled with ["good first issue"](https://github.com/DIRACGrid/diracx-web/labels/good%20first%20issue). These are issues that - in principle - are well-suited for newcomers to the project. + +### 2. Make Changes + +*Requirements: [Getting Started](get_started.md)* + +- **Fork the Repository:** Start by forking the repository and creating a new branch for your work. Use a descriptive name for your branch that reflects the work you are doing. + +- **Code Documentation:** Ensure that any code you write is well-documented. This includes: + - Inline comments where necessary to explain complex logic. + - Updating or creating Storybook documentation if you are contributing to the `diracx-web-components` library. +- **Writing/Updating Tests:** When you change or add new code, make sure to write or update tests accordingly. This helps maintain the reliability and stability of the codebase. + +**Note:** Don't forget to update the `extensions` code if you integrate breaking changes in the `diracx-web-components` library. See [Managing the extension](manage_extension.md) for further details. + +### 3. Commit + +- **Conventional Commits:** All commits must follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. This ensures that commit messages are structured and consistent, which is important for automation and versioning. + - **Examples:** + - `feat(ui): add new button component` + - `fix(api): handle null values in response` + - `docs(readme): update contributing guidelines` + - **Why?** If your commit messages do not follow this convention, the Continuous Integration (CI) process will fail, and your PR will not be merged. Please ensure your commit messages are properly formatted before pushing. + +- **Note**: `Husky` is configured to run as a pre-commit script, executing tasks such as linting staged files to maintain code consistency with the codebase. + + +### 4. Make a Pull Request (PR) + +- **Submit Your PR:** When you’re ready, submit your pull request. Please include a clear description of what your PR does and reference the issue number it addresses (if applicable). +- **Review Process:** Your PR will be reviewed by project maintainers. Please be patient and responsive to any feedback you receive. + +### 5. Additional Notes + +- **Trivial Changes:** For minor changes like fixing typos, feel free to skip the issue creation step and go straight to making a PR. +- **Stay Up-to-Date:** Make sure your branch is up-to-date with the latest changes in the main branch before submitting your PR. Use `git rebase` if necessary. \ No newline at end of file diff --git a/docs/developer/index.md b/docs/developer/index.md new file mode 100644 index 00000000..c6223efa --- /dev/null +++ b/docs/developer/index.md @@ -0,0 +1,54 @@ + +# Developer Guide + +Welcome to the DiracX-Web Developer Guide! This guide will help you navigate and ramp you up. Adding features, fixing the code in a consistent manner with tests and documentation will become a second nature. + + +## Architecture Overview + +```mermaid +--- +config: + layout: elk +--- +flowchart TD + subgraph monorep["Monorepo"] + monorep1["diracx-web-components"] + monorep2["diracx-web"] + monorep3["extension[gubbins]"] + end + monorep2 -- images deployed in --> docker[" "] + monorep2 -. uses .-> monorep1 + monorep3 -. uses .-> monorep1 + monorep1 -- documented on --> storybook[" "] + monorep1 -- published on --> npm[" "] + extension["diracx-community-extension"] -. uses .-> npm + docker@{ img: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQLQKd_MRed_mZQlgrzQuUXVA3P39ssOVX8_g&s", h: 100, w: 100} + storybook@{ img: "https://miro.medium.com/v2/resize:fit:900/1*ZuBTYHXl6l3XzTb8d9Oi5Q.png", h: 100, w: 150, pos: "b"} + npm@{ img: "https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Npm-logo.svg/2560px-Npm-logo.svg.png", h: 40, w: 100} + monorep1:::Ash + monorep1:::Cyan + monorep2:::Green + monorep3:::Green + extension:::Ash + classDef Cyan stroke-width:1px, stroke-dasharray:none, stroke:#00FFFF, fill:#9CFFFF + classDef Green stroke-width:1px, stroke-dasharray:none, stroke:#5BFF00, fill:#A4FF8E, color:#374D7C + classDef Ash stroke-width:1px, stroke-dasharray:none, stroke:#999999, fill:#EEEEEE, color:#000000 +``` + +This repository is organized as a monorepo, with the following key packages: + +- [**DiracX-Web-Components**](packages/diracx-web-components): A library of reusable React components designed for integration within the `DiracX-Web` package and to facilitate the creation of custom DiracX web extensions. + +- [**DiracX-Web**](packages/diracx-web): Vanilla Dirac web interface based on Next.js. Leverages components from `DiracX-Web-Components` to provide core functionalities. + +- [**Extensions**](packages/extensions): An illustrative example of a web extension, also based on Next.js, demonstrating how to extend the functionality of `DiracX-Web` using the components from the `DiracX-Web-Components` package. + + +The monorepo structure is based on *npm workspaces* to ensure that related packages ([DiracX-Web-Components](packages/diracx-web-components)) are automatically used from their local versions instead of fetching them from the npm registry. + +## Ramping up + +- [Set up a development environment](setup_environment.md) +- [Manage the extension](manage_extension.md) +- [Contribute to the effort](contribute.md) diff --git a/docs/developer/manage_extension.md b/docs/developer/manage_extension.md new file mode 100644 index 00000000..be82b526 --- /dev/null +++ b/docs/developer/manage_extension.md @@ -0,0 +1,92 @@ +# Dealing with an extension + +## Modifying the `gubbins` extension + +This implies setting up the backend as well as the frontend. + +### `gubbins-web` (frontend) + +```mermaid +--- +config: + layout: elk +--- +flowchart TD + subgraph root-cmds["root package.json"] + root:dev["dev"] + end + subgraph gubbins-cmds["extensions[gubbins] package.json"] + nextdev["next dev"] + gubbins:dev["dev"] + cypress["cypress"] + gubbins:test["test"] + next["next build"] + gubbins:build["build"] + end + subgraph ext["extensions[gubbins]"] + diracx-src["/src"] + diracx-out["/out"] + end + subgraph lib["diracx-web-components"] + lib-src["/src"] + lib-out["/dist"] + end + user["Developer"] --> root-cmds + gubbins:dev -.-> nextdev + gubbins:test -.-> cypress + gubbins:build -.-> next + root:dev -- calls --> gubbins:dev + root:dev ----x diracx-web-cmds["diracx-web package.json"] + cypress -- uses --> diracx-src + nextdev -- uses --> diracx-src + next -- builds --> diracx-out + next -. needs .-> lib-out + root:dev:::Ash + nextdev:::Rose + gubbins:dev:::Ash + cypress:::Rose + gubbins:test:::Ash + next:::Rose + gubbins:build:::Ash + diracx-src:::Peach + diracx-out:::Peach + lib-src:::Peach + lib-out:::Peach + classDef Ash stroke-width:1px, stroke-dasharray:none, stroke:#999999, fill:#EEEEEE, color:#000000 + classDef Peach stroke-width:1px, stroke-dasharray:none, stroke:#FBB35A, fill:#FFEFDB, color:#8F632D + classDef Rose stroke-width:1px, stroke-dasharray:none, stroke:#FF5978, fill:#FFDFE5, color:#8E2236 + style user stroke:#000000 + style root-cmds fill:#FFFFFF,stroke:#424242,color:#000000 + style diracx-web-cmds fill:#FFFFFF,stroke:#424242,color:#000000 + style gubbins-cmds fill:#FFFFFF,stroke:#424242,color:#000000 + style lib fill:#d99fe3,stroke:#FFCDD2,color:#000000 + style ext fill:#d99fe3,stroke:#FFCDD2,color:#000000 +``` + +You can simply, and temporarily modify `package.json` by replacing the `dev` command such as: + +```bash +jq '.scripts.dev["@dirac-grid/diracx-web-components"] = "npm --prefix packages/extensions run dev"' diracx-web/package.json > diracx-web/package.temp.json +mv diracx-web/package.temp.json diracx-web/package.json +``` + +And you would provide the `./diracx-web` directory to `diracx-charts/run_demo.sh` as usual: + +```bash +# Run the demo +diracx-charts/run_demo.sh ./diracx-web ...[backend params] + +# We use the test command from packages/extensions though +export DIRACX_URL=<diracX installation> +npm run --prefix packages/extensions test +``` + +### `gubbins` (backend) + +Follow the instructions from the [Gubbins extension README](https://github.com/DIRACGrid/diracx/tree/main/extensions#work-on-gubbins). + +:bulb: Like `diracx-web`, `gubbins-web` does automatically reflect changes made in `diracx-web-components`. This means that while running `gubbins` using `diracx-charts/run_demo.sh`, any modifications to `diracx-web-components` will also be applied to `gubbins`. + +## Creating a new extension + +More details available in the [**extensions** README](/packages/extensions/README.md) \ No newline at end of file diff --git a/docs/developer/setup_environment.md b/docs/developer/setup_environment.md new file mode 100644 index 00000000..0f0e2321 --- /dev/null +++ b/docs/developer/setup_environment.md @@ -0,0 +1,155 @@ +# Setting up your Development Environment + +```mermaid +--- +config: + layout: elk +--- +flowchart TD + subgraph root-cmds["root package.json"] + root:dev["dev"] + root:test["test"] + root:build["build"] + root:test:lib["test:diracx-web-components"] + root:build:lib["build:diracx-web-components"] + root:doc:lib["doc:diracx-web-components"] + end + subgraph lib-cmds["diracx-web-components package.json"] + tsup:watch["tsup --watch"] + lib:dev["dev"] + jest["jest"] + lib:test["test"] + tsup:build["tsup"] + lib:build["build"] + storybook["storybook dev"] + lib:storybook["doc"] + end + subgraph diracx-web-cmds["diracx-web package.json"] + nextdev["next dev"] + diracx-web:dev["dev"] + cypress["cypress"] + diracx-web:test["test"] + next["next build"] + diracx-web:build["build"] + end + subgraph diracx-web["diracx-web"] + diracx-src["/src"] + diracx-out["/out"] + end + subgraph lib["diracx-web-components"] + lib-src["/src"] + lib-out["/dist"] + end + lib:dev --> tsup:watch + lib:test --> jest + lib:build --> tsup:build + lib:storybook --> storybook + diracx-web:dev -.-> nextdev + diracx-web:test -.-> cypress + diracx-web:build -.-> next + user["Developer"] --> root-cmds + root:test:lib -- calls --> lib:test + root:build:lib -- calls --> lib:build + root:doc:lib -- calls --> lib:storybook + root:dev -- calls --> diracx-web:dev + root:build -- calls --> diracx-web:build + root:test -- calls --> diracx-web:test + root:test ~~~ gubbins-cmds["**extensions[gubbins] package.json**"] + cypress -- uses --> diracx-src + nextdev -- uses --> diracx-src + nextdev -. watches(next config) .-> lib-src + next -- builds --> diracx-out + next -. needs .-> lib-out + tsup:watch -- builds --> lib-out + tsup:watch -. watches .-> lib-src + jest -- uses --> lib-src + tsup:build -- builds --> lib-src + storybook -- uses --> lib-src + root:dev:::Ash + root:test:::Ash + root:build:::Ash + root:test:lib:::Ash + root:build:lib:::Ash + root:doc:lib:::Ash + tsup:watch:::Rose + lib:dev:::Ash + jest:::Rose + lib:test:::Ash + tsup:build:::Rose + lib:build:::Ash + storybook:::Rose + lib:storybook:::Ash + nextdev:::Rose + diracx-web:dev:::Ash + cypress:::Rose + diracx-web:test:::Ash + next:::Rose + diracx-web:build:::Ash + diracx-src:::Peach + diracx-out:::Peach + lib-src:::Peach + lib-out:::Peach + classDef Ash stroke-width:1px, stroke-dasharray:none, stroke:#999999, fill:#EEEEEE, color:#000000 + classDef Peach stroke-width:1px, stroke-dasharray:none, stroke:#FBB35A, fill:#FFEFDB, color:#8F632D + classDef Rose stroke-width:1px, stroke-dasharray:none, stroke:#FF5978, fill:#FFDFE5, color:#8E2236 + style user stroke:#000000 + style lib fill:#d99fe3,stroke:#FFCDD2,color:#000000 + style diracx-web fill:#d99fe3,stroke:#FFCDD2,color:#000000 +``` + +## Running DiracX-Web in development mode + +_Requirements: docker, internet, node_ + +This will allow you to run a demo setup: + +```bash +# Clone the diracx-chart repository +git clone git@github.com:DIRACGrid/diracx-charts.git + +# Run the demo +diracx-charts/run_demo.sh +``` + +You can also start the demo setup in development mode - code changes will be reflected in the demo in real time: + +```bash +# Clone the diracx-web repository +git clone git@github.com:DIRACGrid/diracx-web.git + +# Clone the diracx-chart repository +git clone git@github.com:DIRACGrid/diracx-charts.git + +# Run the demo +diracx-charts/run_demo.sh ./diracx-web +``` + +:bulb: Any change made in `diracx-web-components` are automatically reflected into the development environment. We rely on the [NextJS transpile option](https://nextjs.org/docs/app/api-reference/config/next-config-js/transpilePackages). Further details are available in the [`diracx-web` NextJS configuration](../../packages/diracx-web/next.config.js) + +## Testing + +[Jest](https://jestjs.io/) unit tests can be started with: + +```bash +npm run test:diracx-web-components +``` + +End-to-end tests are launched through [Cypress](https://www.cypress.io/) such as: + +```bash +# diracx-charts/run_demo.sh is running +export DIRACX_URL=<diracX installation> +npm run --prefix packages/diracx-web test +``` + +## Documenting + +[Storybook]((https://storybook.js.org/docs)) can be started with: + +```bash +npm run doc:diracx-web-components +``` + +## Contributing + +See the [Contributing guidelines](/CONTRIBUTING.md) \ No newline at end of file diff --git a/docs/ops/deploy_instance.md b/docs/ops/deploy_instance.md new file mode 100644 index 00000000..adfb627e --- /dev/null +++ b/docs/ops/deploy_instance.md @@ -0,0 +1,43 @@ +# Deploying the web interface +## DiracX-Web + +### Development mode + +Refer to the [Developer Guide: Setting up you Development Environment](../developer/setup_environment.md) for instructions on running `diracx-web` in development mode. + +### Production mode + +To deploy `diracx-web` in a production environment, you need to customize the [`diracx` Helm Chart](https://github.com/DIRACGrid/diracx-charts) values. Key parameters include: + +```yaml +global.images.web.tag: <latest diracx-web version, docker tag> +global.images.web.repository: <diracx-web docker image> +``` + +:bulb: Make sure to update these values to point to the appropriate Docker image and version for your deployment. + +### Integrating new features/hotfixes + +To hotfix `diracx-web`, test new features, you can provide a specific PR within [`diracx` Helm Chart](https://github.com/DIRACGrid/diracx-charts) values, such as: + +```yaml +diracxWeb.repoURL: <repository hosting the branch you want to apply> +diracxWeb.branch: <branch hosting the changes you want to apply> +``` + +:bulb: Make sure to update these values to point to the appropriate Docker image and version for your deployment. + +## Extension + + +### `gubbins` extension in development mode + +For managing the `gubbins` extension in development mode, refer to the [Developer Guide: Managing an extension](../developer/manage_extension.md). + +### `gubbins` extension in development mode, as a standalone + +By default, the `gubbins` extension is part of a monorepo and uses a local version of `diracx-web-components`. This setup is not representative of a standalone extension configuration. + +To deploy gubbins as a standalone package: +- **Isolate the `packages/extensions` directory:** Copy the content of `packages/extensions` to a new repository or directory outside the monorepo. +- **Update Configuration:** Adjust relevant variables to align with a standalone setup. Review the required changes in the [gubbins-test Github Action workflow](../../.github/workflows/gubbins-test.yml). diff --git a/docs/ops/index.md b/docs/ops/index.md new file mode 100644 index 00000000..af816531 --- /dev/null +++ b/docs/ops/index.md @@ -0,0 +1,60 @@ +# Administrator Guide + +Welcome to the DiracX-Web Administrator Guide! This comprehensive resource is designed to assist you in effectively managing, deploying, and maintaining the DiracX-Web repository. Whether you're overseeing releases, handling dependencies, or configuring the system, this guide provides the necessary insights and instructions. + +The following graph gives you an overview of the [Github Action Workflows](../../.github/workflows/): + +```mermaid +--- +config: + layout: elk +--- +flowchart TD + subgraph basic-checks["Basic Checks"] + checks["Linting and Commit format checking"] + end + subgraph lib-test["DiracX-Web-Components Tests"] + unit-tests["Unit Tests"] + end + subgraph diracx-web-test["DiracX-Web Tests"] + integration-tests["Integration Tests"] + end + subgraph gubbins-test["Extensions[Gubbins] Tests"] + lint["Linting"] + standalone["Prepare Gubbins as a standalone"] + ext-docker["Build docker dev image"] + ext-integration-tests["Integration Tests"] + end + subgraph deployment["Deployment"] + main:release-please["Release Please: Create/Update PR"] + rel:release-please["Release Please: Push tags & releases"] + main:build-deploy-lib["Build diracx-web-components"] + docker-dev["Build & Push dev image"] + storybook["Build Storybook"] + rel:deploy-storybook["Deploy Storybook"] + rel:build-deploy-lib["Publish diracx-web-components on NPM"] + rel:docker-release["Push release image"] + end + standalone -- is needed for --> ext-docker & ext-integration-tests + basic-checks ~~~ lib-test + lib-test ~~~ diracx-web-test & gubbins-test + diracx-web-test ~~~ deployment + gubbins-test ~~~ deployment + main:release-please -- is needed for --> main:build-deploy-lib + rel:release-please -- is needed for --> rel:build-deploy-lib & rel:deploy-storybook & rel:docker-release + storybook -- is needed for --> rel:deploy-storybook + main:build-deploy-lib -- is needed for --> rel:build-deploy-lib + rel:release-please:::Rose + rel:deploy-storybook:::Rose + rel:build-deploy-lib:::Rose + rel:docker-release:::Rose + classDef Rose stroke-width:1px, stroke-dasharray:none, stroke:#FF5978, fill:#FFDFE5, color:#8E2236 + +``` + + +## Content + +- [Deploy DiracX-Web](./deploy_instance.md) +- [Manage dependencies](./manage_dependencies.md) +- [Manage releases](./manage_release.md) \ No newline at end of file diff --git a/docs/ops/manage_dependencies.md b/docs/ops/manage_dependencies.md new file mode 100644 index 00000000..b41a18d0 --- /dev/null +++ b/docs/ops/manage_dependencies.md @@ -0,0 +1,29 @@ +# Managing dependencies + +## Updating dependencies + +[Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/managing-pull-requests-for-dependency-updates) is a GitHub-integrated tool that automates dependency management by regularly checking for updates and creating pull requests (PRs) to keep your project's dependencies current. In the `diracx-web` repository, Dependabot is configured to run weekly, generating PRs for any outdated or vulnerable dependencies. + +1. **Review Dependabot PRs:** + - **Access PRs:** Navigate to the repository's "Pull Requests" section to view Dependabot's submissions. + - **Examine Changes:** Assess the proposed updates, paying close attention to any major version changes that might introduce breaking changes. + +2. **Verify Test Results:** + - **Automated Tests:** Ensure that all continuous integration (CI) checks and automated tests pass successfully for each Dependabot PR. + - **Handle Failures:** If tests fail, investigate the cause by reviewing the dependency's changelog or release notes to identify any breaking changes or incompatibilities. + +3. **Adapt Code if Necessary:** + - **Local Checkout:** Check out the PR branch locally. + - **Implement Fixes:** Modify the codebase to address any issues introduced by the dependency update. + - **Test Changes:** Run the test suite locally to confirm that your changes resolve the issues. + - **Push Updates:** After making the necessary adjustments, commit and push your changes to the Dependabot branch. + +4. **Merge PRs:** + - **Final Review:** Once tests pass and the codebase is stable, proceed to merge the PR into the main branch. + - **Post-Merge Actions:** Monitor the application post-deployment to ensure that the update does not introduce any unforeseen issues. + +## Managing Security Vulnerabilities + +Dependabot also helps in identifying and addressing security vulnerabilities in your project's dependencies. When a vulnerability is detected, Dependabot generates alerts and can automatically create PRs to update the affected dependencies. + +Navigate to the repository's "Security" tab and select "Dependabot alerts" to view any security vulnerabilities identified in the dependencies. diff --git a/docs/ops/manage_release.md b/docs/ops/manage_release.md new file mode 100644 index 00000000..614d5b3a --- /dev/null +++ b/docs/ops/manage_release.md @@ -0,0 +1,26 @@ +# Release Management + +```mermaid +sequenceDiagram + Actor Developer + Actor RepoAdmin as Repo Admin + participant GHPRs as Github PRs + participant GHRelBranch as Github Release Branch + participant RPlease as Release Please + participant Docker as Docker Registry + participant NPM as NPM registry + participant GHPage as Github Pages + loop N times + Developer ->>+ GHPRs: Submit new PR + RepoAdmin ->>+ GHPRs: Review & Merge PR + GHPRs ->>+ GHRelBranch: Push changes + GHPRs ->>+ Docker: Build & Push dev image + RPlease -->> GHRelBranch: Detect changes + RPlease ->>+ GHPRs: Submit new PR to bump version + end + RepoAdmin ->>+ GHPRs: Review & Merge Release Please PR + GHPRs ->>+ GHRelBranch: Push changes + GHPRs ->>+ Docker: Build & Push dev + release image + GHPRs ->>+ NPM: Build & Push diracx-web-components + GHPRs ->>+ GHPage: Build & Deploy Storybook +``` diff --git a/docs/package-management.md b/docs/package-management.md deleted file mode 100644 index 50c71227..00000000 --- a/docs/package-management.md +++ /dev/null @@ -1,28 +0,0 @@ -# Package Management in the Monorepo - -## Using Local Packages - -When working on `diracx-web`, the monorepo configuration ensures that related packages (`diracx-web-components`) are automatically used from their local versions instead of fetching them from the npm registry. This setup allows developers to see the latest changes in real-time, so that any updates or modifications to these packages are immediately reflected in the `diracx-web` application during development. - -This approach streamlines the development process, reduces the need for frequent publishing to npm, and ensures consistency across the project. - -### Configuration - -Our monorepo is configured to use npm workspaces, which allows us to specify the projects and packages that should be linked locally. - -From the [npm documentation](https://docs.npmjs.com/cli/v10/using-npm/workspaces): - -> Workspaces is a generic term that refers to the set of features in the npm cli that provides support for managing multiple packages from your local file system from within a singular top-level, root package. -> -> This set of features makes up for a much more streamlined workflow handling linked packages from the local file system. It automates the linking process as part of npm install and removes the need to manually use npm link in order to add references to packages that should be symlinked into the current node_modules folder. - -**Example `package.json` Configuration:** - -```json -{ - "workspaces": ["packages/diracx-web-components", "packages/diracx-web"] -} -``` - -Note that any packages not listed in the `workspaces` (i.e. `extensions` here) array are not considered workspaces. They will not be managed from the root of the monorepo and will not have access to the linked packages in the root `node_modules`, hence they will fetch them from the npm registry. -Additionally, these packages will have their own `node_modules` folder. diff --git a/docs/release_management.excalidraw b/docs/release_management.excalidraw deleted file mode 100644 index 51c46a5a..00000000 --- a/docs/release_management.excalidraw +++ /dev/null @@ -1,2089 +0,0 @@ -{ - "type": "excalidraw", - "version": 2, - "source": "https://excalidraw.com", - "elements": [ - { - "id": "LZoqJnIu1sw_cUCLsS-3a", - "type": "rectangle", - "x": -1703.3123177422422, - "y": -66.47222222222217, - "width": 1512, - "height": 801, - "angle": 0, - "strokeColor": "transparent", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b4a", - "roundness": { - "type": 3 - }, - "seed": 1069310086, - "version": 216, - "versionNonce": 398264474, - "isDeleted": false, - "boundElements": null, - "updated": 1731058585809, - "link": null, - "locked": false - }, - { - "id": "50LGfz5dcPX3KTXrlb7FK", - "type": "ellipse", - "x": -1686.3123177422422, - "y": -51.47222222222217, - "width": 37, - "height": 35, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "hachure", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "4iLKe3g9M-gZa_0x8q5GB", - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b66V", - "roundness": { - "type": 2 - }, - "seed": 26621146, - "version": 116, - "versionNonce": 1508359450, - "isDeleted": false, - "boundElements": null, - "updated": 1731054243718, - "link": null, - "locked": false - }, - { - "id": "u__O-VFRmuEqXLhaBdYsK", - "type": "rectangle", - "x": -1692.3123177422422, - "y": -17.47222222222217, - "width": 50, - "height": 53, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "hachure", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "4iLKe3g9M-gZa_0x8q5GB", - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b67", - "roundness": { - "type": 3 - }, - "seed": 325273946, - "version": 119, - "versionNonce": 988088794, - "isDeleted": false, - "boundElements": null, - "updated": 1731054243718, - "link": null, - "locked": false - }, - { - "id": "nBECxhMYENhBkfYiXLf1L", - "type": "text", - "x": -1703.3123177422422, - "y": 61.52777777777783, - "width": 75.4481201171875, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#1e1e1e", - "fillStyle": "solid", - "strokeWidth": 4, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [ - "XnKIrvpoqs0tjFcAfgdHE" - ], - "frameId": null, - "index": "b68", - "roundness": null, - "seed": 2028927622, - "version": 105, - "versionNonce": 748429338, - "isDeleted": false, - "boundElements": [ - { - "id": "sJsyDMW30ryhniXGPCIRj", - "type": "arrow" - } - ], - "updated": 1731057700485, - "link": null, - "locked": false, - "text": "Developer", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "Developer", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "sJsyDMW30ryhniXGPCIRj", - "type": "arrow", - "x": -1666.8641976250549, - "y": 91.88678834677484, - "width": 1.4481201171872726, - "height": 644.6409894310029, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6b", - "roundness": { - "type": 2 - }, - "seed": 1537709638, - "version": 678, - "versionNonce": 1094515546, - "isDeleted": false, - "boundElements": null, - "updated": 1731057715016, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.4481201171872726, - 329.82182507063254 - ], - [ - -1.4481201171872726, - 644.6409894310029 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "nBECxhMYENhBkfYiXLf1L", - "focus": 0.0330778096370633, - "gap": 10.359010568997007, - "fixedPoint": null - }, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null, - "elbowed": false - }, - { - "id": "tg_nIP1tVVhexNnfx-0Ue", - "type": "arrow", - "x": -1663.3123177422422, - "y": 178.52777777777783, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6c", - "roundness": { - "type": 2 - }, - "seed": 791920262, - "version": 621, - "versionNonce": 1003151258, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "1JljsFZXpzxM_9tGxqVhd" - } - ], - "updated": 1731056929944, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "1JljsFZXpzxM_9tGxqVhd", - "type": "text", - "x": -1546.9443901909726, - "y": 168.52777777777783, - "width": 79.26414489746094, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b6cV", - "roundness": null, - "seed": 122768390, - "version": 67, - "versionNonce": 57665670, - "isDeleted": false, - "boundElements": null, - "updated": 1731056928885, - "link": null, - "locked": false, - "text": "submit PR", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "tg_nIP1tVVhexNnfx-0Ue", - "originalText": "submit PR", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1095, - "versionNonce": 886313542, - "index": "b7i", - "isDeleted": false, - "id": "VD0KhbmOLbgijSO8xEaI6", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1146.3123177422422, - "y": -66.47222222222217, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "width": 230, - "height": 150, - "seed": 1651239174, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "nPnxWfl-lEXZuZnMQrWUQ" - } - ], - "updated": 1731056992322, - "link": null, - "locked": false - }, - { - "id": "nPnxWfl-lEXZuZnMQrWUQ", - "type": "text", - "x": -1136.9122933281797, - "y": -16.47222222222217, - "width": 211.199951171875, - "height": 50, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7j", - "roundness": null, - "seed": 1783998234, - "version": 783, - "versionNonce": 1945312070, - "isDeleted": false, - "boundElements": [], - "updated": 1731058451211, - "link": null, - "locked": false, - "text": " release\n branch", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "VD0KhbmOLbgijSO8xEaI6", - "originalText": " release\n branch", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1250, - "versionNonce": 494594310, - "index": "b7k", - "isDeleted": false, - "id": "ON1RL0C2FDTb-9KB4IUDI", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -834.3123177422422, - "y": -67.47222222222217, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "width": 230, - "height": 150, - "seed": 571558362, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "kwsRMRXdYCu8NkPBlPjAd" - } - ], - "updated": 1731058369671, - "link": null, - "locked": false - }, - { - "id": "kwsRMRXdYCu8NkPBlPjAd", - "type": "text", - "x": -773.2203987969297, - "y": -22.47222222222217, - "width": 107.816162109375, - "height": 60, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7kV", - "roundness": null, - "seed": 229791130, - "version": 20, - "versionNonce": 1497646234, - "isDeleted": false, - "boundElements": null, - "updated": 1731058374295, - "link": null, - "locked": false, - "text": "\n\nplease-release", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "ON1RL0C2FDTb-9KB4IUDI", - "originalText": "\n\nplease-release", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1318, - "versionNonce": 528261574, - "index": "b7m", - "isDeleted": false, - "id": "HI0X8_iVvpGlrMLY_2GB0", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -520.3123177422422, - "y": -69.47222222222217, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "width": 230, - "height": 150, - "seed": 546860614, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [], - "updated": 1731058269317, - "link": null, - "locked": false - }, - { - "id": "Gz61oAld7AVzW-zPoiyNC", - "type": "arrow", - "x": -1033.5882576836484, - "y": 90.46611809250268, - "width": 1.4481201171875, - "height": 644.6409894310029, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7o", - "roundness": { - "type": 2 - }, - "seed": 94193094, - "version": 1151, - "versionNonce": 1196743962, - "isDeleted": false, - "boundElements": [], - "updated": 1731057714786, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.4481201171875, - 329.82182507063254 - ], - [ - -1.4481201171875, - 644.6409894310029 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null, - "elbowed": false - }, - { - "id": "bgT0kJfyuaLBC89CX8i9w", - "type": "arrow", - "x": -717.5882576836484, - "y": 90.46611809250268, - "width": 1.4481201171875, - "height": 644.6409894310029, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7p", - "roundness": { - "type": 2 - }, - "seed": 1459317082, - "version": 1302, - "versionNonce": 717658502, - "isDeleted": false, - "boundElements": [], - "updated": 1731057714786, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.4481201171875, - 329.82182507063254 - ], - [ - -1.4481201171875, - 644.6409894310029 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null, - "elbowed": false - }, - { - "id": "nV7QXW6vqf4nBX-2mf8mO", - "type": "arrow", - "x": -403.5882576836484, - "y": 86.6424035456156, - "width": 1.4481201171875, - "height": 644.6409894310029, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7q", - "roundness": { - "type": 2 - }, - "seed": 173438278, - "version": 1390, - "versionNonce": 1034824154, - "isDeleted": false, - "boundElements": [], - "updated": 1731057714786, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.4481201171875, - 329.82182507063254 - ], - [ - -1.4481201171875, - 644.6409894310029 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null, - "elbowed": false - }, - { - "id": "_8fSwNEU1HlF4dhQ5Qat_", - "type": "arrow", - "x": -719.8123177422422, - "y": 319.0277777777778, - "width": 312, - "height": 1, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7r", - "roundness": { - "type": 2 - }, - "seed": 1180202886, - "version": 1442, - "versionNonce": 519788698, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "xUaQs1XBrATR-q_bAtdqx" - } - ], - "updated": 1731057472867, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -312, - 1 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "xUaQs1XBrATR-q_bAtdqx", - "type": "text", - "x": -900.9444207085508, - "y": 310.5277777777778, - "width": 120.26420593261719, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7s", - "roundness": null, - "seed": 615225030, - "version": 683, - "versionNonce": 1643722074, - "isDeleted": false, - "boundElements": [], - "updated": 1731057472867, - "link": null, - "locked": false, - "text": "detect changes", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "_8fSwNEU1HlF4dhQ5Qat_", - "originalText": "detect changes", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "type": "rectangle", - "version": 1104, - "versionNonce": 768716422, - "index": "b7t", - "isDeleted": false, - "id": "uZHwiGs36GY5A1gzAWz4z", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "angle": 0, - "x": -1463.3123177422422, - "y": -65.47222222222217, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "width": 230, - "height": 150, - "seed": 429861338, - "groupIds": [], - "frameId": null, - "roundness": { - "type": 3 - }, - "boundElements": [ - { - "type": "text", - "id": "oD056o-0eYMV90Q8r8twM" - } - ], - "updated": 1731056894691, - "link": null, - "locked": false - }, - { - "id": "oD056o-0eYMV90Q8r8twM", - "type": "text", - "x": -1456.6523064507383, - "y": -2.9722222222221717, - "width": 216.6799774169922, - "height": 25, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#ffffff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7u", - "roundness": null, - "seed": 311484058, - "version": 786, - "versionNonce": 2006540442, - "isDeleted": false, - "boundElements": [], - "updated": 1731058460665, - "link": null, - "locked": false, - "text": " PRs", - "fontSize": 20, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "uZHwiGs36GY5A1gzAWz4z", - "originalText": " PRs", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "tujN8vbmo0Q4Rn7Vnz2Bl", - "type": "arrow", - "x": -1349.5882576836484, - "y": 90.46611809250268, - "width": 1.4481201171875, - "height": 644.6409894310029, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7v", - "roundness": { - "type": 2 - }, - "seed": 493558554, - "version": 1154, - "versionNonce": 1527085254, - "isDeleted": false, - "boundElements": [], - "updated": 1731057714786, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -0.4481201171875, - 329.82182507063254 - ], - [ - -1.4481201171875, - 644.6409894310029 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": null, - "elbowed": false - }, - { - "id": "cpfZlkqEPHXVE8RE5ACal", - "type": "arrow", - "x": -1664.3123177422422, - "y": 208.52777777777783, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7w", - "roundness": { - "type": 2 - }, - "seed": 1061805914, - "version": 720, - "versionNonce": 2047077338, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "K_twhHZgrObVaRLBZyDvQ" - } - ], - "updated": 1731057240357, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "K_twhHZgrObVaRLBZyDvQ", - "type": "text", - "x": -1544.4083718193906, - "y": 198.52777777777783, - "width": 72.19210815429688, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7x", - "roundness": null, - "seed": 1816716314, - "version": 113, - "versionNonce": 1292722330, - "isDeleted": false, - "boundElements": [], - "updated": 1731057240357, - "link": null, - "locked": false, - "text": "merge PR", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "cpfZlkqEPHXVE8RE5ACal", - "originalText": "merge PR", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "Ber_nF55Kj7b5NAhzixJU", - "type": "arrow", - "x": -1348.3123177422422, - "y": 231.52777777777783, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7y", - "roundness": { - "type": 2 - }, - "seed": 32374426, - "version": 794, - "versionNonce": 62662426, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "QD79wXXDxVsnP3Ug8d7J3" - } - ], - "updated": 1731057246507, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "QD79wXXDxVsnP3Ug8d7J3", - "type": "text", - "x": -1286.1404808892148, - "y": 211.52777777777783, - "width": 187.6563262939453, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b7z", - "roundness": null, - "seed": 1537678170, - "version": 177, - "versionNonce": 1117533146, - "isDeleted": false, - "boundElements": [], - "updated": 1731057246508, - "link": null, - "locked": false, - "text": "push changes to release\nbranch", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "Ber_nF55Kj7b5NAhzixJU", - "originalText": "push changes to release branch", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "brpq8T3nVjMKupGGpKuHS", - "type": "arrow", - "x": -723.3123177422422, - "y": 364.0277777777778, - "width": 627, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b84", - "roundness": { - "type": 2 - }, - "seed": 940002074, - "version": 1602, - "versionNonce": 1754670042, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "gx1JJ_s-0Y1WTuntUF_hr" - } - ], - "updated": 1731058151057, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -627, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "gx1JJ_s-0Y1WTuntUF_hr", - "type": "text", - "x": -1253.6207283867734, - "y": 344.0277777777778, - "width": 433.6168212890625, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b85", - "roundness": null, - "seed": 165861338, - "version": 862, - "versionNonce": 2051733574, - "isDeleted": false, - "boundElements": [], - "updated": 1731058149384, - "link": null, - "locked": false, - "text": "submit/update PR to bump versions of all packages\n(except gubbin's dependency to diracx-web-components)", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "brpq8T3nVjMKupGGpKuHS", - "originalText": "submit/update PR to bump versions of all packages\n(except gubbin's dependency to diracx-web-components)", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "-cLP8_Z0HpBhUs-25A6kj", - "type": "arrow", - "x": -1665.3123177422422, - "y": 417.5277777777778, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b86", - "roundness": { - "type": 2 - }, - "seed": 1961436102, - "version": 871, - "versionNonce": 184466374, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "BEZJfaMLQDOtyltEtrHOs" - } - ], - "updated": 1731058107952, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "BEZJfaMLQDOtyltEtrHOs", - "type": "text", - "x": -1602.3124627007383, - "y": 407.5277777777778, - "width": 186.0002899169922, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b87", - "roundness": null, - "seed": 1289534214, - "version": 232, - "versionNonce": 1014977286, - "isDeleted": false, - "boundElements": [], - "updated": 1731058107952, - "link": null, - "locked": false, - "text": "merge please-release PR", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "-cLP8_Z0HpBhUs-25A6kj", - "originalText": "merge please-release PR", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "kphf_23skSkM6-VRFE0Sh", - "type": "arrow", - "x": -1348.3123177422422, - "y": 430.5277777777778, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b88", - "roundness": { - "type": 2 - }, - "seed": 218577606, - "version": 953, - "versionNonce": 688561434, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "RaIrpkrEN7xhy2yVOdAKY" - } - ], - "updated": 1731057472867, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "RaIrpkrEN7xhy2yVOdAKY", - "type": "text", - "x": -1374.1404808892148, - "y": 272.5277777777778, - "width": 187.6563262939453, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b89", - "roundness": null, - "seed": 119534086, - "version": 251, - "versionNonce": 1655433690, - "isDeleted": false, - "boundElements": [], - "updated": 1731057472867, - "link": null, - "locked": false, - "text": "push changes to release\nbranch", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "kphf_23skSkM6-VRFE0Sh", - "originalText": "push changes to release branch", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "KH9AETNmC_h8ta9yyc99s", - "type": "arrow", - "x": -722.3123177422422, - "y": 454.0277777777778, - "width": 312, - "height": 1, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dashed", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8A", - "roundness": { - "type": 2 - }, - "seed": 145738970, - "version": 1492, - "versionNonce": 470130330, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "7l0MSxurDRA3163gacpgf" - } - ], - "updated": 1731057472867, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -312, - 1 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "7l0MSxurDRA3163gacpgf", - "type": "text", - "x": -1035.4444207085508, - "y": 304.5277777777778, - "width": 120.26420593261719, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8B", - "roundness": null, - "seed": 1033183642, - "version": 696, - "versionNonce": 298498906, - "isDeleted": false, - "boundElements": [], - "updated": 1731057472867, - "link": null, - "locked": false, - "text": "detect changes", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "KH9AETNmC_h8ta9yyc99s", - "originalText": "detect changes", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "7TtZRh56eqG5y4Jcv_Hrm", - "type": "arrow", - "x": -723.3123177422422, - "y": 529.0277777777778, - "width": 312, - "height": 1, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8C", - "roundness": { - "type": 2 - }, - "seed": 714495430, - "version": 1553, - "versionNonce": 661688582, - "isDeleted": false, - "boundElements": [], - "updated": 1731057633479, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -312, - 1 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "kd2GJA4Ii6_slsthvaRiM", - "type": "arrow", - "x": -1032.3123177422422, - "y": 259.5277777777778, - "width": 80, - "height": 42, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8E", - "roundness": { - "type": 2 - }, - "seed": 1730700058, - "version": 1053, - "versionNonce": 44767898, - "isDeleted": false, - "boundElements": [], - "updated": 1731057568450, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 80, - 3 - ], - [ - 1, - 42 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "-9isSKb34B1VRPQzqBLqQ", - "type": "text", - "x": -945.3123177422422, - "y": 215.52777777777783, - "width": 159.73631286621094, - "height": 60, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8G", - "roundness": null, - "seed": 514622278, - "version": 46, - "versionNonce": 881056602, - "isDeleted": false, - "boundElements": null, - "updated": 1731057583509, - "link": null, - "locked": false, - "text": "deploy \ndev docker images:\ndiracx-web + gubbins", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "deploy \ndev docker images:\ndiracx-web + gubbins", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "VIMiFfPMnLwk6f3uolGIh", - "type": "text", - "x": -991.3123177422422, - "y": 482.5277777777778, - "width": 226.46438598632812, - "height": 100, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8H", - "roundness": null, - "seed": 1675134854, - "version": 80, - "versionNonce": 474460486, - "isDeleted": false, - "boundElements": null, - "updated": 1731057660078, - "link": null, - "locked": false, - "text": "tag + release new version\npublish npm\n\ndeploy release docker images:\ndiracx-web + gubbins", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "tag + release new version\npublish npm\n\ndeploy release docker images:\ndiracx-web + gubbins", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "YjLC2CfW7ZiIQTQB5YfHF", - "type": "arrow", - "x": -402.31231774224216, - "y": 538.0277777777778, - "width": 75, - "height": 46, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8I", - "roundness": { - "type": 2 - }, - "seed": 1281572102, - "version": 1701, - "versionNonce": 331626650, - "isDeleted": false, - "boundElements": [], - "updated": 1731058007865, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 75, - 3.5 - ], - [ - 1, - 46 - ] - ], - "lastCommittedPoint": null, - "startBinding": { - "elementId": "K6tqzcWpm4f4Y9wl5O6l9", - "focus": 1.1761330655599316, - "gap": 13.131843566894531, - "fixedPoint": null - }, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "K6tqzcWpm4f4Y9wl5O6l9", - "type": "text", - "x": -389.1804741753476, - "y": 472.5277777777778, - "width": 201.67237854003906, - "height": 60, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8K", - "roundness": null, - "seed": 126936198, - "version": 217, - "versionNonce": 768063258, - "isDeleted": false, - "boundElements": [ - { - "id": "YjLC2CfW7ZiIQTQB5YfHF", - "type": "arrow" - } - ], - "updated": 1731057998401, - "link": null, - "locked": false, - "text": "detect new versions\nof diracx-web-components\non npm", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "detect new versions\nof diracx-web-components\non npm", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "pXKgNjPMcGjjJ7cIex2_2", - "type": "arrow", - "x": -406.81231774224216, - "y": 619.5277777777778, - "width": 943, - "height": 2, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8L", - "roundness": { - "type": 2 - }, - "seed": 1634088710, - "version": 1754, - "versionNonce": 128048646, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "bjVu1xhHBVGy6k-n6j0iM" - } - ], - "updated": 1731057859968, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - -943, - -2 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "bjVu1xhHBVGy6k-n6j0iM", - "type": "text", - "x": -1007.9405678643125, - "y": 598.5277777777778, - "width": 259.2565002441406, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8M", - "roundness": null, - "seed": 651519558, - "version": 954, - "versionNonce": 1417485274, - "isDeleted": false, - "boundElements": [], - "updated": 1731057858404, - "link": null, - "locked": false, - "text": "submit PR to bump version of\ndiracx-web-components in gubbins", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "pXKgNjPMcGjjJ7cIex2_2", - "originalText": "submit PR to bump version of\ndiracx-web-components in gubbins", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "mXkMOnK6iRS5Cmzt6M3Cy", - "type": "arrow", - "x": -1664.3123177422422, - "y": 665.5277777777778, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8N", - "roundness": { - "type": 2 - }, - "seed": 2016108250, - "version": 673, - "versionNonce": 28254278, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "fMW_ox1z-0edwpIExN136" - } - ], - "updated": 1731057941039, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "fMW_ox1z-0edwpIExN136", - "type": "text", - "x": -1594.5604790581601, - "y": 625.5277777777778, - "width": 172.49632263183594, - "height": 80, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8O", - "roundness": null, - "seed": 466514842, - "version": 138, - "versionNonce": 2049805722, - "isDeleted": false, - "boundElements": [], - "updated": 1731057940044, - "link": null, - "locked": false, - "text": "adapt gubbins' code if\nnecessary\n&\nmerge dependabot PR", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "mXkMOnK6iRS5Cmzt6M3Cy", - "originalText": "adapt gubbins' code if necessary\n&\nmerge dependabot PR", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "SgEaFGX1BXKFoljsTAxuE", - "type": "arrow", - "x": -1349.3123177422422, - "y": 699.5277777777778, - "width": 312, - "height": 0, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8P", - "roundness": { - "type": 2 - }, - "seed": 1815408794, - "version": 718, - "versionNonce": 998084506, - "isDeleted": false, - "boundElements": [ - { - "type": "text", - "id": "_L6X2XlaRCnbRmp5UeQw1" - } - ], - "updated": 1731057962706, - "link": null, - "locked": false, - "points": [ - [ - 0, - 0 - ], - [ - 312, - 0 - ] - ], - "lastCommittedPoint": null, - "startBinding": null, - "endBinding": null, - "startArrowhead": null, - "endArrowhead": "arrow", - "elbowed": false - }, - { - "id": "_L6X2XlaRCnbRmp5UeQw1", - "type": "text", - "x": -1307.1404808892148, - "y": 690.5277777777778, - "width": 187.6563262939453, - "height": 40, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "dotted", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8Q", - "roundness": null, - "seed": 71290202, - "version": 177, - "versionNonce": 1009761690, - "isDeleted": false, - "boundElements": [], - "updated": 1731057957399, - "link": null, - "locked": false, - "text": "push changes to release\nbranch", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "center", - "verticalAlign": "middle", - "containerId": "SgEaFGX1BXKFoljsTAxuE", - "originalText": "push changes to release branch", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "2fkpuXR2QMnv_u8FdcaM-", - "type": "text", - "x": -1522.3123177422422, - "y": 372.5277777777778, - "width": 13.76800537109375, - "height": 20, - "angle": 0, - "strokeColor": "#1e1e1e", - "backgroundColor": "#a5d8ff", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8R", - "roundness": null, - "seed": 1500622106, - "version": 22, - "versionNonce": 2028228314, - "isDeleted": false, - "boundElements": null, - "updated": 1731058131628, - "link": null, - "locked": false, - "text": "...", - "fontSize": 16, - "fontFamily": 5, - "textAlign": "left", - "verticalAlign": "top", - "containerId": null, - "originalText": "...", - "autoResize": true, - "lineHeight": 1.25 - }, - { - "id": "0MjF4yxer8QVeyLDh6YW9", - "type": "image", - "x": -517.3123177422422, - "y": -27.47222222222217, - "width": 224, - "height": 64, - "angle": 0, - "strokeColor": "transparent", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8T", - "roundness": null, - "seed": 254194650, - "version": 70, - "versionNonce": 1771354202, - "isDeleted": false, - "boundElements": null, - "updated": 1731058310173, - "link": null, - "locked": false, - "status": "saved", - "fileId": "bf255f2de99c0ba85430755d90ecd73d17c28050", - "scale": [ - 1, - 1 - ], - "crop": null - }, - { - "id": "iQ55_u2sHk-1f9wchWIWT", - "type": "image", - "x": -757.8123177422422, - "y": -55.97222222222217, - "width": 70, - "height": 70, - "angle": 0, - "strokeColor": "transparent", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8U", - "roundness": null, - "seed": 1629337798, - "version": 115, - "versionNonce": 1898204954, - "isDeleted": false, - "boundElements": null, - "updated": 1731058384965, - "link": null, - "locked": false, - "status": "saved", - "fileId": "73a9d67676b532233e4c32a4e7778b8148134f38", - "scale": [ - 1, - 1 - ], - "crop": null - }, - { - "id": "hKEnHuyshiI_PhjAtyOw_", - "type": "image", - "x": -1411.3123177422422, - "y": -38.47222222222216, - "width": 80.99999999999999, - "height": 80.99999999999999, - "angle": 0, - "strokeColor": "transparent", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8V", - "roundness": null, - "seed": 1932111194, - "version": 130, - "versionNonce": 1615680390, - "isDeleted": false, - "boundElements": null, - "updated": 1731058466553, - "link": null, - "locked": false, - "status": "saved", - "fileId": "e9fd360a0147670300bfe62d3f524fe4311838d4", - "scale": [ - 1, - 1 - ], - "crop": null - }, - { - "id": "vl93kfJA1sdSuilKkkntW", - "type": "image", - "x": -1116.8123177422422, - "y": -35.97222222222216, - "width": 80.99999999999999, - "height": 80.99999999999999, - "angle": 0, - "strokeColor": "transparent", - "backgroundColor": "transparent", - "fillStyle": "solid", - "strokeWidth": 2, - "strokeStyle": "solid", - "roughness": 0, - "opacity": 100, - "groupIds": [], - "frameId": null, - "index": "b8W", - "roundness": null, - "seed": 1771597658, - "version": 156, - "versionNonce": 451158746, - "isDeleted": false, - "boundElements": [], - "updated": 1731058455912, - "link": null, - "locked": false, - "status": "saved", - "fileId": "e9fd360a0147670300bfe62d3f524fe4311838d4", - "scale": [ - 1, - 1 - ], - "crop": null - } - ], - "appState": { - "gridSize": 20, - "gridStep": 5, - "gridModeEnabled": false, - "viewBackgroundColor": "#ffffff" - }, - "files": { - "bf255f2de99c0ba85430755d90ecd73d17c28050": { - "mimeType": "image/png", - "id": "bf255f2de99c0ba85430755d90ecd73d17c28050", - "dataURL": "data:image/png;base64,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", - "created": 1731058301415, - "lastRetrieved": 1731058301415 - }, - "73a9d67676b532233e4c32a4e7778b8148134f38": { - "mimeType": "image/png", - "id": "73a9d67676b532233e4c32a4e7778b8148134f38", - "dataURL": "data:image/png;base64,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", - "created": 1731058350506, - "lastRetrieved": 1731058350506 - }, - "e9fd360a0147670300bfe62d3f524fe4311838d4": { - "mimeType": "image/png", - "id": "e9fd360a0147670300bfe62d3f524fe4311838d4", - "dataURL": "data:image/png;base64,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", - "created": 1731058423262, - "lastRetrieved": 1731058423262 - } - } -} \ No newline at end of file diff --git a/docs/user/index.md b/docs/user/index.md new file mode 100644 index 00000000..d8e8fb47 --- /dev/null +++ b/docs/user/index.md @@ -0,0 +1,9 @@ +# User Guide + +Welcome to the DiracX-Web User Guide! This guide will help you navigate and make the most of the DiracX-Web application. Whether you are logging in for the first time, or managing various application instances, this guide provides step-by-step instructions to simplify your experience. + +## Content + +- [How to Log In and Log Out?](login_out.md) +- [How to Interact with my Jobs?](monitor_jobs.md) +- [How to Manage various Application Instances and share them?](list_and_share_applications.md) diff --git a/docs/user/list_and_share_applications.md b/docs/user/list_and_share_applications.md new file mode 100644 index 00000000..22d7d8f6 --- /dev/null +++ b/docs/user/list_and_share_applications.md @@ -0,0 +1,92 @@ +# Managing Application Instances + +An *application instance* is a graphical web interface that allows users to interact with DiracX services. DiracX-Web is essentially a collection of such applications, and users can "spawn" instances to interact with them. + +By default, a few application instances are displayed (e.g., `My Jobs`, an instance of `Job Monitor`). This guide will help you manage, organize, and share application instances effectively. + +## Basics + +### Accessing More Applications + +1. Click the **Add Application** button at the bottom of the sidebar. + - :bulb: On mobile devices, first open the sidebar by clicking the **menu icon** (☰) at the top-left corner. +2. Select an application from the list in the dialog box. + - :bulb: The selected application will appear in the sidebar. + +### Opening Multiple Instances of the Same Application + +- Repeat the steps above to open additional instances of the same application. + - :bulb: Each instance has its own state, making it ideal for monitoring different job groups with specific criteria for instance. + +### Renaming an Application Instance + +1. **Right-click** on the instance name in the sidebar. + - :bulb: A context menu will appear. +2. Select **Rename**. + - :bulb: The instance name will change to an input field. +3. Enter a new name and press **Enter** to save it. + +### Moving an Application Instance + +1. Locate the **handle icon** next to the instance name. +2. Click and hold the handle to select the instance. +3. Drag it to the desired position within the sidebar. +4. Release the mouse button to place the instance. + +### Deleting an Application Instance + +1. **Right-click** on the instance name in the sidebar. + - :bulb: A context menu will appear. +2. Select **Delete**. + - :bulb: The application instance will disappear from the sidebar. + +### Sharing Your Dashboard + +1. Copy the URL from your browser. + - :bulb: The URL encodes the current state of your dashboard. +2. Share it with others. + - :warning: The recipient will see a similar dashboard layout but may not see identical content if: + - They belong to a different VO or group. + - Time-sensitive data has changed since sharing. + - :warning: Encoding too many application instances may create discrepancies as the URL has a theoretical limit of 8000 characters based on [RFC9110](https://www.rfc-editor.org/rfc/rfc9110#section-4.1-5) + +## Advanced Features + +When managing multiple instances of the same application, grouping can help you organize your dashboard efficiently. + +### Creating a New Group + +1. **Right-click** anywhere in the sidebar. + - :bulb: A context menu will appear. +2. Select **New Group**. + - :bulb: A new group with a default name will appear in the sidebar. +3. Add new application instances to the group using the **Add Application** button. + - :bulb: By default, new instances will be placed in the most recently created group. + +### Renaming a Group + +1. **Right-click** on the group name in the sidebar. + - :bulb: A context menu will appear. +2. Select **Rename**. + - :bulb: The group name will change to an input field. +3. Enter a new name and press **Enter** to save it. + +### Moving a Group + +1. Locate the **handle icon** next to the group name. +2. Click and hold the handle to select the group. +3. Drag the group to the desired position within the sidebar. + - :bulb: All application instances within the group will move together. +4. Release the mouse button to place the group. + +### Moving Instances Between Groups + +1. Drag an application instance from one group. +2. Drop it into another group using the same drag-and-drop process as moving instances within a group. + +### Deleting a Group + +1. **Right-click** on the group name in the sidebar. + - :bulb: A context menu will appear. +2. Select **Delete**. + - :bulb: The group and all its application instances will disappear from the sidebar. diff --git a/docs/user/login_out.md b/docs/user/login_out.md new file mode 100644 index 00000000..559c8ed1 --- /dev/null +++ b/docs/user/login_out.md @@ -0,0 +1,27 @@ +# Logging in & out + +## Basics +### Logging in + +1. Go to the DiracX-Web instance homepage. + - 💡 You should end up on an authentication page. +2. Authenticate you as a user of a given VO/group: + - If your instance supports multiple VOs, select your VO in the list box. + - Select your Group in the list box below. +3. Click the **Login** button. + - 💡 You should be redirected to the VO login page. +4. Enter your credentials (e.g., Username/Password, X509 certificates). + - 💡 You should see a page asking for permission to access your profile. +5. Accept the permissions to access your DiracX dashboard. + - 💡 You should be redirected to the DiracX-Web instance as a logged-in user, and the dashboard should appear. + +### Logging out + +1. Click on your profile icon in the top-right corner of the dashboard. + - :bulb: A dropdown menu should appear +2. Select **Logout** from the dropdown menu. + +## Advanced +### Logging in with specific properties + +TODO diff --git a/docs/user/monitor_jobs.md b/docs/user/monitor_jobs.md new file mode 100644 index 00000000..be6b997f --- /dev/null +++ b/docs/user/monitor_jobs.md @@ -0,0 +1,9 @@ +# Managing your jobs + +## Basics + +### + + +## Advanced + diff --git a/package.json b/package.json index 52653697..6ff21ba3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "build": "npm --prefix packages/diracx-web-components run build && npm --prefix packages/diracx-web run build && mv -f packages/diracx-web/out ./out", "test:diracx-web-components": "npm --prefix packages/diracx-web-components run test", "build:diracx-web-components": "npm --prefix packages/diracx-web-components run build", + "doc:diracx-web-components": "npm --prefix packages/diracx-web-components run doc", "lint": "npm --prefix packages/diracx-web-components run lint && npm --prefix packages/diracx-web run lint", "ts-lint": "npm --prefix packages/diracx-web-components run ts-lint && npm --prefix packages/diracx-web run ts-lint", "prepare": "husky" diff --git a/packages/diracx-web-components/package.json b/packages/diracx-web-components/package.json index 21020aaa..5d3ca998 100644 --- a/packages/diracx-web-components/package.json +++ b/packages/diracx-web-components/package.json @@ -14,8 +14,8 @@ "lint-staged": "lint-staged", "ts-lint": "tsc -noEmit -incremental", "prepack": "rm -rf dist && npm run build", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "doc": "storybook dev -p 6006", + "build-doc": "storybook build" }, "license": "GPL-3.0", "type": "module", diff --git a/packages/extensions/README.md b/packages/extensions/README.md index 65faa4c7..b4ea1bed 100644 --- a/packages/extensions/README.md +++ b/packages/extensions/README.md @@ -2,7 +2,7 @@ <img alt="Extension Logo" src="public/robot.png" width="300" > </p> -# Creating a Next.js DiracX Web Extension +# Creating a DiracX Web Extension This project aims to provide an example for creating a basic Next.js web extension for DiracX. It includes the necessary configuration and setup to get you started quickly. @@ -22,20 +22,34 @@ And ensure you have basic knowledge of: ## Getting Started -You can either create a new repository or fork this repository to build your DiracX extension. Follow one of the methods below: +You can either create a new repository or start from this one to build your DiracX extension. Follow one of the methods below: ### Method 1: Fork the Repository -1. **Fork this repository** on GitHub. -2. **Clone the forked repository** to your local machine: +1. **Clone this repository** on GitHub, move and rename the `diracx-web/packages/extensions` directory: ```bash - git clone https://github.com/YOUR_USERNAME/diracx-web.git - cd diracx-web/packages/extensions - npm install + git clone https://github.com/DIRACGrid/diracx-web.git + mv diracx-web/packages/extensions </path/to/different/location> + cd </path/to/different/location> ``` -3. **Modify the app pages** to use components from the `diracx-components` library (e.g., providers, apps). +2. **Slightly modify the `package.json` file** + + From `</path/to/different/location>`, execute the following command: + + ```bash + # Adapt the path of the copy-service-worker-files script + jq '.scripts.postinstall = "node ./node_modules/@axa-fr/react-oidc/bin/copy-service-worker-files.mjs public"' ./package.json > ./package.temp.json + mv ./package.temp.json ./package.json + # Adapt the package name and version + jq '.name = "<YOUR EXTENSION NAME>"' ./package.json > ./package.temp.json + mv ./package.temp.json ./package.json + jq '.version = "0.1.0-a0"' ./package.json > ./package.temp.json + mv ./package.temp.json ./package.json + ``` + +3. **Remove `CHANGELOG.md`** ### Method 2: Create a New Next.js Project @@ -123,7 +137,7 @@ We strongly recommend following the directory structure below to keep your proje ### Running the Extension with DiracX Charts -To start your DiracX extension follow these steps: +To start your DiracX extension in development mode follow these steps: 1. **Clone the `diracx-charts` repository** in a parent directory: @@ -137,7 +151,12 @@ To start your DiracX extension follow these steps: ./diracx-charts/run_demo.sh path/to/your-extension ``` -This will run the DiracX Demo with your extension. +To run your extension in a production environment, you need to customize the [`diracx` Helm Chart](https://github.com/DIRACGrid/diracx-charts) values, such as: + +```yaml +global.images.web.tag: <your extension version, docker tag> +global.images.web.repository: <your extension docker image> +``` ## Customizing the Extension diff --git a/packages/extensions/next.config.js b/packages/extensions/next.config.js index 5ebb0009..f6ee364c 100644 --- a/packages/extensions/next.config.js +++ b/packages/extensions/next.config.js @@ -1,9 +1,25 @@ -/** @type {import('next').NextConfig} */ -const nextConfig = { - output: "export", - images: { - unoptimized: true, - }, -}; +import path from "path"; +import { fileURLToPath } from "url"; +import { PHASE_DEVELOPMENT_SERVER } from "next/constants.js"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); -export default nextConfig; +export default (phase) => { + const isDev = phase === PHASE_DEVELOPMENT_SERVER; + + return { + transpilePackages: ["@dirac-grid/diracx-web-components"], + ...(isDev && { + webpack: (config) => { + config.resolve.alias["@dirac-grid/diracx-web-components"] = + path.resolve(__dirname, "../diracx-web-components/src"); + return config; + }, + }), + output: "export", + images: { + unoptimized: true, + }, + }; +}; diff --git a/packages/extensions/package.json b/packages/extensions/package.json index 3a58fd6e..061360e0 100644 --- a/packages/extensions/package.json +++ b/packages/extensions/package.json @@ -5,7 +5,7 @@ "type": "module", "license": "GPL-3.0-only", "scripts": { - "dev": "next dev --turbopack", + "dev": "next dev", "build": "next build", "test": "cypress open --config baseUrl=$DIRACX_URL", "start": "next start",