├── .devcontainer ├── default.sh └── devcontainer.json ├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── build-linux.yml │ ├── build-mac.yml │ ├── build-win.yml │ ├── container-publish.yml │ ├── install_arm.sh │ ├── test-update.yml │ └── test.yml ├── .gitignore ├── .vscode └── settings.json ├── Assets ├── Fonts │ ├── DejaVuSansCode.ttf │ ├── Hasklig-Regular.otf │ ├── Monoid Regular.ttf │ └── SFMonoRegular.woff ├── Styles │ ├── Custom.css │ ├── Optimized.css │ ├── Tailwind.css │ └── Tailwind.js ├── WL │ └── FMO.wl └── textures │ ├── water.jpg │ ├── waterdudv.jpg │ └── waternormals.jpg ├── COC.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Common └── LPM │ └── LPM.wl ├── Components ├── Alert.wlx ├── ElectronAppBinds.wlx ├── ExtendedTopbar.wlx ├── FakeMenu.wlx ├── FakeMenuBrowser.wlx ├── Head.wlx ├── IframeAPI.wlx ├── Kernel │ ├── Item.wlx │ ├── Kernel.wlx │ └── Minimal.wlx ├── MinimalElectronAppBinds.wlx ├── Modals │ ├── Components │ │ ├── Custom.wlx │ │ ├── Generic.wlx │ │ ├── Initcells.wlx │ │ ├── PickAFile.wlx │ │ ├── RequestPathToSave.wlx │ │ ├── Select.wlx │ │ ├── SuggestKernel.wlx │ │ └── TextField.wlx │ └── Modals.wlx ├── Mode.wlx ├── Notifications │ ├── Components │ │ ├── Custom.wlx │ │ ├── Dialog.wlx │ │ ├── Generic.wlx │ │ ├── MessagesList.wlx │ │ ├── Spinner.wlx │ │ └── Types.wl │ └── Notifications.wlx ├── PromptTools.wlx ├── Settings.wlx ├── Sidebar │ ├── Body.wlx │ ├── Components │ │ ├── Dropdown.wlx │ │ ├── ItemDirectory.wlx │ │ ├── ItemFile.wlx │ │ ├── ItemList.wlx │ │ └── ItemParent.wlx │ └── Sidebar.wlx ├── Topbar.wlx └── Topbar │ └── Breadcrumbs.wlx ├── Electron ├── build │ ├── 256x256.ico │ ├── 256x256.png │ ├── 256x256_new.ico │ ├── 4x-logo.png │ ├── 512x512.ai │ ├── 512x512.icns │ ├── 512x512.ico │ ├── 512x512.png │ ├── 512x512_ico_transparent.png │ ├── 512x512_ico_transparent_light.png │ ├── 512x512_new.ai │ ├── 512x512_new.png │ ├── Orig.png │ ├── cli_unix.sh │ ├── cli_unix_remove.sh │ ├── cli_win.bat │ ├── cli_win_remove.bat │ ├── entitlements.mac.plist │ ├── file │ │ ├── 512x512-2.icns │ │ ├── 512x512-2.ico │ │ ├── 512x512-2.png │ │ ├── 512x512.icns │ │ ├── 512x512.ico │ │ ├── 512x512.png │ │ ├── File.ai │ │ └── Widget.ai │ ├── hook.js │ ├── orig_new.png │ ├── windows.ico │ └── windows.png ├── bundle │ └── log.js ├── device.html ├── device.js ├── electron.css ├── log.html ├── log.js ├── log_padded.html ├── main.js ├── pdfjs │ ├── pdf.js │ ├── pdf.js.map │ ├── pdf.min.js │ ├── pdf.worker.entry.js │ ├── pdf.worker.js │ ├── pdf.worker.js.map │ └── pdf.worker.min.js ├── preload_device.js ├── preload_log.js ├── preload_main.js ├── rollup.config.mjs ├── rollup.config_preload.mjs ├── shortcuts.json ├── sign.js ├── tailwind.config.js └── tailwind.css ├── Frontend ├── App.wlx ├── Autolaunch.wl ├── Downloader.wl ├── ExtendedApp.wlx ├── IframeApp.wlx ├── KernelUtils.wl ├── Loader.wl ├── PromptWindow.wlx ├── Protocol.wlx ├── ServerError.wlx ├── Settings.wl ├── Settings.wlx ├── Sponsors.wlx ├── Test.wlx ├── Views.wl └── Window.wlx ├── Kernel ├── AppExtensions.wl ├── Cells.wl ├── Evaluator.wl ├── Extensions.wl ├── Kernel.wl ├── LTP.wl ├── LTPEvents.wl ├── LocalKernel.wl ├── Notebook.wl ├── Transactions.wl ├── Utils.wl └── Windows.wl ├── LICENSE ├── PacletInfo.wl ├── README.md ├── Scripts ├── bundle.wls ├── link.wls ├── purge.wls ├── start.wls └── update.wls ├── Views ├── Directories │ ├── Components │ │ ├── Label.wlx │ │ └── List.wlx │ └── Main.wlx ├── Empty.wlx ├── Image.wlx ├── None.wlx ├── Notebook │ ├── Assets │ │ └── JSCells.js │ ├── CellGenerator.wlx │ ├── Components │ │ ├── Border.wlx │ │ ├── CellFrame.wlx │ │ ├── CellGroup.wlx │ │ ├── CellSubgroup.wlx │ │ ├── CellWrapper.wlx │ │ ├── CellsContainer.wlx │ │ ├── Children.wlx │ │ ├── Console.wlx │ │ ├── Controls.wlx │ │ ├── Dropdown.wlx │ │ ├── ElectronBinds.wlx │ │ ├── EvaluationBar.wlx │ │ ├── Hr.wlx │ │ ├── KernelIndicator.wlx │ │ └── TopBar.wlx │ ├── Failure.wlx │ ├── Message.wlx │ └── Notebook.wlx ├── Settings │ ├── Components │ │ ├── Dev.wlx │ │ ├── Extensions.wlx │ │ ├── General.wlx │ │ └── UI │ │ │ ├── Button.wlx │ │ │ ├── Checkbox.wlx │ │ │ └── Radio.wlx │ └── Settings.wlx ├── Text.wlx └── Window │ ├── Assets │ └── JSCells.js │ ├── Components │ ├── Container.wlx │ ├── Group.wlx │ └── Wrapper.wlx │ ├── Window.wlx │ └── WindowGenerator.wlx ├── container ├── Containerfile ├── README.md ├── proxy-snippet.conf ├── run.sh └── wljs-routes ├── imgs ├── ASKAI optimizer.gif ├── Bubbles video to gif-e6769380f627f9aeca39fa8709b4461c.gif ├── DynamicsFast-ezgif.com-optimize.gif ├── Isingspins-ezgif.com-optipng.png ├── Screenshot 2023-08-27 at 10.47.41.png ├── Screenshot 2023-08-27 at 10.49.06.png ├── Screenshot 2023-11-07 at 22.19.14.png ├── Screenshot 2023-11-07 at 22.19.22.png ├── Screenshot 2023-11-07 at 22.19.30.png ├── Screenshot 2023-12-17 at 18.11.10.png ├── Screenshot 2024-04-14 at 21.26.51.png ├── Shorter-ezgif.com-optimize.gif ├── Toster.png ├── dark.png ├── ezgif.com-math-1.gif ├── ezgif.com-math-2.gif ├── ezgif.com-optimize-15.gif ├── ezgif.com-optimize-5-55576aef6756b65dcc582b2f19964fa0.gif ├── ezgif.com-optimize-8-ab1e9c4b2859b664554ba69bdd2cce07.gif ├── flowerPot-ezgif.com-video-to-gif-converter.gif ├── fuid.webp ├── libJS-ezgif.com-optimize.gif ├── light.png ├── logo.png ├── manipulate.gif ├── manipulatePlot-ezgif.com-optimize.gif ├── morph-ezgif.com-video-to-gif-converter.gif ├── nice0animation-ezgif.com-video-to-gif-converter-79bc0c7f8a4ee716eba6da5840c45688.gif └── rerer-ezgif.com-video-to-gif-converter.gif ├── package-lock.json ├── package.json ├── playwright.config.js ├── tailwind.config.js ├── tests ├── __screenshots__ │ └── integration │ │ ├── bars.show.spec.js │ │ └── screenshorts │ │ │ ├── anuualsector.png │ │ │ ├── bar.png │ │ │ ├── barlegened.png │ │ │ ├── bubble.png │ │ │ ├── histogram.png │ │ │ ├── histogramstyle.png │ │ │ ├── multibar.png │ │ │ ├── piechart.png │ │ │ ├── piechartChartLegends.png │ │ │ ├── sector.png │ │ │ └── windRadial.png │ │ ├── basic.sugar.spec.js │ │ └── screenshorts │ │ │ ├── 1p1.png │ │ │ ├── 2bornot2b.png │ │ │ ├── ConjugateTranspose.png │ │ │ ├── Fraction.png │ │ │ ├── Grid1.png │ │ │ ├── Grid2.png │ │ │ ├── Indexed.png │ │ │ ├── Integrate1.png │ │ │ ├── Integrate2.png │ │ │ ├── Integrate3.png │ │ │ ├── Integrate4.png │ │ │ ├── NeuralNetImageOut.png │ │ │ ├── Piecewise.png │ │ │ ├── Subscript.png │ │ │ ├── Sum1.png │ │ │ ├── Sum2.png │ │ │ ├── Superscript.png │ │ │ ├── Transpose.png │ │ │ ├── bytearray.png │ │ │ ├── colorFunction.png │ │ │ ├── ctable.png │ │ │ ├── dataset.png │ │ │ ├── deriv.png │ │ │ ├── entity.png │ │ │ ├── geo.png │ │ │ ├── image.png │ │ │ ├── interpolationBox.png │ │ │ ├── interpretation.png │ │ │ ├── linearyLayerNet.png │ │ │ ├── listplay.png │ │ │ ├── modelFit.png │ │ │ ├── moon.png │ │ │ ├── now.png │ │ │ ├── plot.png │ │ │ ├── quantity.png │ │ │ ├── sphere.png │ │ │ ├── texform.png │ │ │ ├── texform_back.png │ │ │ ├── texform_markdown.png │ │ │ └── xyz.png │ │ ├── cells.show.spec.js │ │ └── screenshorts │ │ │ ├── jscell.png │ │ │ ├── markdownBasic.png │ │ │ ├── slideBasic.png │ │ │ └── wlxcell.png │ │ ├── graph.show.spec.js │ │ └── screenshorts │ │ │ ├── annotatedgraph.png │ │ │ ├── graph.png │ │ │ ├── graph3d.png │ │ │ ├── graph3dAnoot.png │ │ │ ├── graphStyle1.png │ │ │ ├── graphStyle2.png │ │ │ └── graphshape.png │ │ ├── import.show.spec.js │ │ └── screenshorts │ │ │ ├── html.png │ │ │ ├── markdown.png │ │ │ └── mathematica.png │ │ ├── plot1d.show.spec.js │ │ └── screenshorts │ │ │ ├── BinomialDistribution.png │ │ │ ├── dateplot.png │ │ │ ├── legendedPrime.png │ │ │ ├── legendedaccplot.png │ │ │ ├── lineplot.png │ │ │ ├── markdownplot.png │ │ │ ├── placedSwatch.png │ │ │ ├── placedSwatch2.png │ │ │ ├── plot.png │ │ │ ├── plotfilling.png │ │ │ ├── plotmultifilling.png │ │ │ ├── pointlegend.png │ │ │ └── swatchplot.png │ │ ├── plot2d.show.spec.js │ │ └── screenshorts │ │ │ ├── annulus.png │ │ │ ├── arrayPlot.png │ │ │ ├── complexplot.png │ │ │ ├── countour.png │ │ │ ├── densityplot.png │ │ │ ├── diskregionmesh.png │ │ │ ├── gencellular.png │ │ │ ├── graphicsBasic2.png │ │ │ ├── graphicsRegularPoly.png │ │ │ ├── imagefeatures.png │ │ │ ├── imagenegate.png │ │ │ ├── listcontour.png │ │ │ ├── matrix.png │ │ │ ├── raster.png │ │ │ ├── regionmesh.png │ │ │ └── vector.png │ │ ├── plot3d.show.spec.js │ │ └── screenshorts │ │ │ ├── glass.png │ │ │ ├── graphicsBasic2.png │ │ │ ├── graphicsBasic3.png │ │ │ ├── graphicsBasic4.png │ │ │ ├── graphicsDodecahedron.png │ │ │ ├── imagenegate.png │ │ │ ├── materials.png │ │ │ ├── plot3d.png │ │ │ ├── plot3d2.png │ │ │ ├── spherical.png │ │ │ └── vector.png │ │ ├── style.sugar.spec.js │ │ └── screenshorts │ │ │ ├── Squiggled.png │ │ │ ├── boldString1.png │ │ │ ├── boldString2.png │ │ │ ├── boldString3.png │ │ │ ├── column.png │ │ │ ├── framedWl.png │ │ │ ├── grid.png │ │ │ ├── gridItem.png │ │ │ ├── highlightedWl.png │ │ │ ├── invisibleFrame.png │ │ │ ├── labeled.png │ │ │ ├── labeledGraphics.png │ │ │ ├── largeWl.png │ │ │ ├── largeWlback.png │ │ │ ├── magnify.png │ │ │ ├── matrixFormWithItem.png │ │ │ ├── pane.png │ │ │ ├── panelSlider.png │ │ │ ├── rotate.png │ │ │ ├── row.png │ │ │ ├── rowText.png │ │ │ ├── rowTextWithArrow.png │ │ │ ├── short.png │ │ │ ├── spacer.png │ │ │ ├── style1000.png │ │ │ ├── style1000string.png │ │ │ ├── styleScaled100.png │ │ │ └── tableFormHeadingItem.png │ │ └── userio.show.spec.js │ │ └── screenshorts │ │ ├── InputButton.png │ │ ├── cellview.png │ │ ├── editor.png │ │ ├── html.png │ │ ├── inputgroup.png │ │ ├── inputrange.png │ │ ├── manipulateBasic1.png │ │ ├── manipulateBasic2.png │ │ ├── manipulatePlot1.png │ │ └── soundNote.png └── integration │ ├── attachments │ ├── flower.png │ └── tstballs-d08.png │ ├── bars.show.spec.js │ ├── basic.sugar.spec.js │ ├── cells.show.spec.js │ ├── common.js │ ├── graph.show.spec.js │ ├── import.html │ ├── import.md │ ├── import.nb │ ├── import.show.spec.js │ ├── notebook.wln │ ├── plot1d.show.spec.js │ ├── plot2d.show.spec.js │ ├── plot3d.show.spec.js │ ├── style.sugar.spec.js │ └── userio.show.spec.js └── wolfram-js-frontend-dev.code-workspace /.devcontainer/default.sh: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu 3 | { 4 | "name": "Ubuntu", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "wolframresearch/wolframengine:14.1", 7 | "features": { 8 | "ghcr.io/devcontainers/features/node:1": {} 9 | }, 10 | 11 | // Features to add to the dev container. More info: https://containers.dev/features. 12 | // "features": {}, 13 | 14 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 15 | "forwardPorts": [8080, 8081, 8082, 8085], 16 | 17 | // Use 'postCreateCommand' to run commands after the container is created. 18 | "postCreateCommand": "bash ./.devcontainer/default.sh" 19 | 20 | // Configure tool-specific properties. 21 | // "customizations": {}, 22 | 23 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 24 | // "remoteUser": "root" 25 | } 26 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.js] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | end_of_line = lf 10 | # editorconfig-tools is unable to ignore longs strings or urls 11 | max_line_length = off 12 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.wls linguist-language=Mathematica 2 | *.wl linguist-language=Mathematica 3 | *.wsp linguist-language=HTML -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [JerryI, KirillBelovTest] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | custom: ["https://opencollective.com/wljs-notebook", "https://www.paypal.com/donate/?hosted_button_id=BN9LWUUUJGW54"] 5 | -------------------------------------------------------------------------------- /.github/workflows/container-publish.yml: -------------------------------------------------------------------------------- 1 | name: Container image 2 | 3 | on: 4 | workflow_dispatch: 5 | release: 6 | types: [published] 7 | 8 | env: 9 | REGISTRY: ghcr.io 10 | IMAGE_NAME: ${{ github.repository }} 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest # Run on host machine with Docker installed 16 | permissions: 17 | contents: read 18 | packages: write 19 | 20 | steps: 21 | - name: Checkout repository 22 | uses: actions/checkout@v4 23 | with: 24 | fetch-depth: 0 25 | 26 | - name: Set up Docker Buildx 27 | uses: docker/setup-buildx-action@v3 28 | 29 | - name: Log into registry ${{ env.REGISTRY }} 30 | uses: docker/login-action@v3 31 | with: 32 | registry: ${{ env.REGISTRY }} 33 | username: ${{ github.actor }} 34 | password: ${{ secrets.GITHUB_TOKEN }} 35 | 36 | - name: Start Wolfram Engine Container 37 | run: | 38 | docker run -d --name wolfram \ 39 | -v $GITHUB_WORKSPACE:/workspace \ 40 | -w /workspace \ 41 | wolframresearch/wolframengine:14.2 tail -f /dev/null 42 | 43 | - name: Fix permissions for /workspace directory at host level 44 | run: | 45 | sudo chmod -R 777 $GITHUB_WORKSPACE 46 | 47 | - name: Fetch all dependencies inside Wolfram container 48 | run: | 49 | docker exec -e WOLFRAMSCRIPT_ENTITLEMENTID=${{ secrets.WOLFRAM_LICENSE_ENTITLEMENT_ID }} wolfram \ 50 | wolframscript -script ./Scripts/update.wls 51 | 52 | - name: Extract Docker metadata 53 | id: meta 54 | uses: docker/metadata-action@v5 55 | with: 56 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 57 | 58 | - name: Build and push Docker image 59 | id: build-and-push 60 | uses: docker/build-push-action@v5 61 | with: 62 | context: . 63 | file: "./container/Containerfile" 64 | tags: ${{ steps.meta.outputs.tags }} 65 | labels: ${{ steps.meta.outputs.labels }} 66 | push: true 67 | cache-from: type=gha 68 | cache-to: type=gha,mode=max -------------------------------------------------------------------------------- /.github/workflows/install_arm.sh: -------------------------------------------------------------------------------- 1 | set -eux -o pipefail #Exit right after any command fails. 2 | 3 | link_name="/usr/bin/wolfram" 4 | 5 | if [[ $WE_MODE == "install" ]]; then 6 | 7 | #Define variables { 8 | 9 | #You can set actual version numbers (e.g. "12.0") or an asterisk "*". 10 | #In the latter case, there should be no wolfram-engine installed already. 11 | wolfram_version="*" 12 | 13 | install_script_name="$(mktemp --suffix=.sh --dry-run /tmp/install_wolfram_XXXX)" 14 | 15 | wget "https://archive.raspberrypi.org/debian/pool/main/w/wolfram-engine/wolfram-engine_14.1.0+202408191410_arm64.deb" 16 | 17 | 18 | #The value must be the same as that of `TEMPDIR` variable in the `wget`-ed script. 19 | working_directory="/tmp/wolfram-engine-install" 20 | 21 | #} Define variables 22 | 23 | echo "[2/5] Preparing..." 24 | 25 | install -vDm644 *engine*.deb -t ${working_directory}/wolfram_engine 26 | 27 | pushd "${working_directory}" > /dev/null 28 | cd wolfram_engine/ 29 | ar x *engine*.deb 30 | mkdir data 31 | 32 | echo "[3/5] Extracting..." 33 | tar -C data -xf data.tar.* 34 | 35 | echo "[4/5] Installing..." 36 | sudo cp -r data/opt/* /opt 37 | sudo ln -s /opt/Wolfram/WolframEngine/${wolfram_version}/Executables/wolfram "${link_name}" 38 | 39 | echo "[5/5] Exiting..." 40 | # popd > /dev/null #This is not needed because this script is intended to be executed on a sub-shell. 41 | rm -rf "${working_directory}" "${install_script_name}" 42 | 43 | echo "Done." 44 | 45 | elif [[ $WE_MODE == "uninstall" ]]; then 46 | 47 | echo "Uninstalling..." 48 | sudo rm -rf /opt/Wolfram "${link_name}" #Note this uninstalls all versions of wolfram engines. 49 | echo "Done." 50 | 51 | else 52 | 53 | #`WE_MODE` is named after "Wolfram Engine". 54 | echo "The value of \$WE_MODE [ $WE_MODE ] is illegal." 55 | echo 56 | echo "Usage" 57 | echo " WE_MODE=install bash " 58 | echo " WE_MODE=uninstall bash " 59 | 60 | fi -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | Temp/ 3 | __backups/*.wln 4 | __ntemp/*.wln 5 | __localkernel/* 6 | _settings.wl 7 | shipped/* 8 | *.DS_STORE 9 | public/.DS_STORE 10 | wljs_packages_legacy 11 | .obsidian 12 | Debug/* 13 | .lastpath 14 | wljs_packages 15 | .wl_timestamp 16 | .wljs_timestamp 17 | wl_packages_version.wl 18 | wljs_packages_version.wl 19 | .settings 20 | .theme 21 | .gcss 22 | .env 23 | wl_packages 24 | package-lock.json 25 | wl_packages_lock.wl 26 | wljs_packages_lock.wl 27 | wljs_packages_users.wl 28 | .packages 29 | .env 30 | /LPM.wl 31 | /LPM2.wl 32 | .thumbnails 33 | Kernel/.lastpath 34 | Demo/*.wl 35 | Demo/*.html 36 | Packages/* 37 | 2minutesLog.txt 38 | dist 39 | shipped 40 | bundle 41 | null 42 | log.txt 43 | configuration.ini 44 | dist 45 | wljs_packages_backup 46 | /test-results/ 47 | /playwright-report/ 48 | /blob-report/ 49 | /playwright/.cache/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.wsp": "php", 4 | "*.wls": "wolfram", 5 | "*.wl": "wolfram", 6 | "__bit_reference": "c", 7 | "__bits": "c", 8 | "__config": "c", 9 | "__debug": "c", 10 | "__errc": "c", 11 | "__hash_table": "c", 12 | "__locale": "c", 13 | "__mutex_base": "c", 14 | "__node_handle": "c", 15 | "__nullptr": "c", 16 | "__split_buffer": "c", 17 | "__string": "c", 18 | "__threading_support": "c", 19 | "__tuple": "c", 20 | "array": "c", 21 | "atomic": "c", 22 | "bit": "c", 23 | "bitset": "c", 24 | "cctype": "c", 25 | "charconv": "c", 26 | "chrono": "c", 27 | "clocale": "c", 28 | "cmath": "c", 29 | "compare": "c", 30 | "complex": "c", 31 | "concepts": "c", 32 | "condition_variable": "c", 33 | "cstdarg": "c", 34 | "cstddef": "c", 35 | "cstdint": "c", 36 | "cstdio": "c", 37 | "cstdlib": "c", 38 | "cstring": "c", 39 | "ctime": "c", 40 | "cwchar": "c", 41 | "cwctype": "c", 42 | "deque": "c", 43 | "exception": "c", 44 | "format": "c", 45 | "initializer_list": "c", 46 | "iomanip": "c", 47 | "ios": "c", 48 | "iosfwd": "c", 49 | "iostream": "c", 50 | "istream": "c", 51 | "limits": "c", 52 | "locale": "c", 53 | "memory": "c", 54 | "mutex": "c", 55 | "new": "c", 56 | "numbers": "c", 57 | "numeric": "c", 58 | "optional": "c", 59 | "ostream": "c", 60 | "queue": "c", 61 | "random": "c", 62 | "ratio": "c", 63 | "semaphore": "c", 64 | "span": "c", 65 | "sstream": "c", 66 | "stdexcept": "c", 67 | "streambuf": "c", 68 | "string": "c", 69 | "string_view": "c", 70 | "system_error": "c", 71 | "tuple": "c", 72 | "type_traits": "c", 73 | "typeinfo": "c", 74 | "unordered_map": "c", 75 | "variant": "c", 76 | "vector": "c", 77 | "algorithm": "c", 78 | "*.tcc": "c", 79 | "functional": "c", 80 | "iterator": "c", 81 | "memory_resource": "c", 82 | "utility": "c", 83 | "stop_token": "c", 84 | "thread": "c", 85 | "cinttypes": "c" 86 | } 87 | } -------------------------------------------------------------------------------- /Assets/Fonts/DejaVuSansCode.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/Fonts/DejaVuSansCode.ttf -------------------------------------------------------------------------------- /Assets/Fonts/Hasklig-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/Fonts/Hasklig-Regular.otf -------------------------------------------------------------------------------- /Assets/Fonts/Monoid Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/Fonts/Monoid Regular.ttf -------------------------------------------------------------------------------- /Assets/Fonts/SFMonoRegular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/Fonts/SFMonoRegular.woff -------------------------------------------------------------------------------- /Assets/Styles/Tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | h1 { 7 | @apply text-2xl; 8 | } 9 | 10 | h2 { 11 | @apply text-xl; 12 | } 13 | 14 | h3 { 15 | @apply text-lg; 16 | } 17 | 18 | h4 { 19 | @apply text-base; 20 | } 21 | 22 | ul { 23 | @apply pl-6; 24 | @apply pb-2; 25 | } 26 | 27 | li { 28 | @apply list-disc; 29 | } 30 | 31 | ol { 32 | @apply list-decimal; 33 | } 34 | 35 | 36 | 37 | } -------------------------------------------------------------------------------- /Assets/textures/water.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/textures/water.jpg -------------------------------------------------------------------------------- /Assets/textures/waterdudv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/textures/waterdudv.jpg -------------------------------------------------------------------------------- /Assets/textures/waternormals.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Assets/textures/waternormals.jpg -------------------------------------------------------------------------------- /COC.md: -------------------------------------------------------------------------------- 1 | Be kind to others. Do not insult or put down others. Behave professionally. Remember that harassment and sexist, racist, or exclusionary jokes are not appropriate for NumFOCUS. 2 | 3 | All communication should be appropriate for a professional audience including people of many different backgrounds. Sexual language and imagery is not appropriate. 4 | 5 | NumFOCUS is dedicated to providing a harassment-free community for everyone, regardless of gender, sexual orientation, gender identity and expression, disability, physical appearance, body size, race, or religion. We do not tolerate harassment of community members in any form. 6 | 7 | Thank you for helping make this a welcoming, friendly community for all. -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How you can help this project 2 | WLJS Notebook is modular project. 3 | 4 | **Please, contact @JerryI before working on code and etc.** 5 | 6 | Here is some to-do list grouped by repos 7 | 8 | ## wolfram-js-frontend 9 | *server, IO, UI, cells manager, render process and client app* 10 | ### Primary 11 | - [x] Electron app auto-updater. Use Github releases to update client app automatically (probably won't work for linux) 12 | - [ ] tutorials/examples for new users (no WL background) on Wolfram Language 13 | - [ ] more example on differnet topics (for data-scientists, scientists, students, ...) 14 | 15 | *Main repo is stable and there are no urget needs in any refactoring* 16 | 17 | ## wljs-graphics-d3 18 | ### Primary 19 | - [x] `Inset` works incorrectly on `Image` and other `Graphics` objects. 20 | - [x] `PlotLegends` are not rendered inside a `Graphics` object (acts like a wrapper). Exported figures do not show legends. 21 | 22 | ### Secondary 23 | - [x] misssing implementations for `FilledCurve`, ... 24 | - [x] `GraphicsComplex` with many `Polygon` is too slow. Especially it can be seen on `ContourPlot`, since it produces tons of SVG paths. 25 | 26 | 27 | ## wljs-graphics3d-threejs 28 | ### Primary 29 | - [ ] `AxesLabel`, `Ticks`, does not have any effect. `PlotRange` is absent. 30 | - [x] `Text` is not implemented in the context of `Graphics3D` 31 | 32 | ### Secondary 33 | - [x] `RTX` feature shows incorrect faces of polygons (black triangles) on OSX (probably also depends on a browser) 34 | 35 | ## wljs-inputs 36 | ### Primary 37 | - [x] `TableForm` does not support styling 38 | - [ ] `Dataset` does not support nested sets with asscoiations or other datasets inside. 39 | - [x] `Entity` is not supported 40 | 41 | 42 | ## wljs-markdown 43 | ### Primary 44 | - [x] get rid of double backslashes from LaTeX somehow (single backslash causes problems with encoding) 45 | 46 | ## wljs-slides 47 | ### Primary 48 | - [x] get rid of double backslashes from LaTeX somehow (single backslash causes problems with encoding) 49 | 50 | ## wljs-video 51 | ### Primary 52 | - [x] video preview is extremely slow, decoding from video to a set of images is a main bottleneck. 53 | - [ ] no sound (need to be used together with PCM streamer from wljs-audio) 54 | 55 | ## wljs-sound 56 | ### Primary 57 | - [ ] `Sound` does not works with nested list of `SoundNote` 58 | - [ ] `Sound[SoundNote[...]]` needs a proper syntax sugar for showing piano roll and possible note names 59 | 60 | 61 | ## Mics 62 | - [ ] **Wolfram Language Documentation** (frontend agnostic and in a Markdown format) 63 | - [x] support for syntax sugar for `NeuralNetwork` package of Wolfram Language. For now it is not clear, how to clean up Mathematica's `MakeBoxes` definitons for various neural network object. There is a possibility to use wrapper function, see more in [Issue](https://github.com/JerryI/wolfram-js-frontend/issues/186). 64 | - [x] write a fast implementation of parser/encoder of [WXF](https://github.com/JerryI/wolfram-js-frontend/issues/196) in Javascript. For now we use `ExpressionJSON` for communication, which does not use features of `NumericArray` and `ByteArray` and adds a large overhead in serializaing/deserializing on WL's and JS's sides. There is a [preliminaly work](https://github.com/xndc/uncompress) posted already. 65 | -------------------------------------------------------------------------------- /Components/ElectronAppBinds.wlx: -------------------------------------------------------------------------------- 1 | Controls = $Options["Controls"]; 2 | 3 | -------------------------------------------------------------------------------- /Components/Head.wlx: -------------------------------------------------------------------------------- 1 | With[{Title = $Options["Title"], CSSJit = If[KeyExistsQ[$Options["Settings"], "CSSPreview"], $Options["Settings", "CSSPreview"], False]}, 2 | If[CSSJit, 3 | 4 | <Title/> 5 | 6 | 7 | 8 | <$Children/> 9 | 10 | , 11 | 12 | <Title/> 13 | 14 | 15 | <$Children/> 16 | 17 | ] 18 | ] -------------------------------------------------------------------------------- /Components/IframeAPI.wlx: -------------------------------------------------------------------------------- 1 | 153 | -------------------------------------------------------------------------------- /Components/MinimalElectronAppBinds.wlx: -------------------------------------------------------------------------------- 1 | Controls = $Options["Controls"]; 2 | 3 | -------------------------------------------------------------------------------- /Components/Modals/Components/Custom.wlx: -------------------------------------------------------------------------------- 1 | Window[OptionsPattern[]] := With[{ 2 | promise = OptionValue["Data"]["Promise"], 3 | Content = OptionValue["Data"]["Content"], 4 | loader = OptionValue["Data"]["LazyLoad"], 5 | client = OptionValue["Data"]["Client"], 6 | data = OptionValue["Data"]["Data"] 7 | }, 8 | With[{ 9 | Uid = CreateUUID[] 10 | }, 11 | 12 | EventHandler[Uid, { 13 | "Close" -> Function[Null, 14 | EventFire[loader, "Remove", <|"Client" -> client|>]; 15 | ] 16 | }]; 17 | 18 | 26 | ] 27 | ]; 28 | 29 | Options[Window] = {"Channel" -> "", "Data" -> <| |>}; 30 | 31 | Component[OptionsPattern[]] := With[{Event = OptionValue["Events"], Channel = CreateUUID[], LazyLoad = CreateUUID[]}, Module[{loaded = False}, 32 | EventHandler[Event, { 33 | "CustomModal" -> Function[data, 34 | EventFire[LazyLoad, "Load", Join[data, <|"Client" -> data["Client"], "LazyLoad" -> LazyLoad|>]]; 35 | ] 36 | }]; 37 | 38 | 39 | 40 | 41 | ]]; 42 | 43 | Options[Component] = {"Events" -> ""} 44 | 45 | Component -------------------------------------------------------------------------------- /Components/Modals/Components/RequestPathToSave.wlx: -------------------------------------------------------------------------------- 1 | Component[OptionsPattern[]] := With[{Event = OptionValue["Events"], Channel = CreateUUID[], LazyLoad = CreateUUID[]}, Module[{loaded = False}, 2 | EventHandler[Event, { 3 | "RequestPathToSave" -> Function[data, 4 | With[{p = Promise[]}, 5 | EventFire[Channel, "Ask", Join[data, <|"Client" -> data["Client"], "Promise" -> First[p]|>]]; 6 | Then[p, 7 | Function[result, 8 | Echo["RequestFileToSave >> Resolved!"]; 9 | EventFire[data["Promise"], Resolve, URLDecode @ result]; 10 | ], 11 | 12 | Function[reject, 13 | Echo["RequestFileToSave >> Rejected!"]; 14 | If[reject === "NoElectron", 15 | (*/* spawn another modal to cover needs... if there is no electron wrapper */*) 16 | 17 | With[{temp = CreateUUID[]}, 18 | EventHandler[temp, { 19 | "Cancelled" -> Function[Null, 20 | EventRemove[temp]; 21 | EventFire[data["Promise"], Reject, "Cancelled"]; 22 | ], 23 | 24 | "Success" -> Function[result, 25 | EventRemove[temp]; 26 | EventFire[data["Promise"], Resolve, result]; 27 | ] 28 | }]; 29 | EventFire[Event, "TextField", <|"Client"->data["Client"], "Title"->data["Title"], "String" -> StringJoin["untitled.", data["Ext"]], "Callback"->temp|>]; 30 | ]; 31 | , 32 | EventFire[data["Promise"], Reject, reject]; 33 | ]; 34 | ] 35 | ]; 36 | ] 37 | ] 38 | }]; 39 | 40 | 41 | 42 | this.on('Ask', async (data) => { 43 | const assoc = await interpretate(data, {hold:true}); 44 | const promise = await interpretate(assoc.Promise, {}); 45 | const title = await interpretate(assoc.Title, {}); 46 | const ext = await interpretate(assoc.Ext, {}); 47 | 48 | let targetAPI = window.electronAPI; 49 | 50 | if (!window.electronAPI && !window.iframeAPI) { 51 | server._emitt(promise, '"NoElectron"', 'Reject'); 52 | console.warn('No ElectronJS found'); 53 | return; 54 | } else if (!window.electronAPI) { 55 | targetAPI = window.iframeAPI; 56 | } 57 | 58 | targetAPI.requestFileWindow({title:title, extension:[ext]}, (result) => { 59 | if (!result) { 60 | console.log('Cancelled'); 61 | server._emitt(promise, '"Cancel"', 'Reject'); 62 | return; 63 | } 64 | 65 | console.log(result); 66 | server._emitt(promise, '"'+result+'"', 'Resolve'); 67 | 68 | }); 69 | 70 | }); 71 | 72 | ]]; 73 | 74 | Options[Component] = {"Events" -> ""} 75 | 76 | Component -------------------------------------------------------------------------------- /Components/Modals/Modals.wlx: -------------------------------------------------------------------------------- 1 | SuggestKernel = ImportComponent["Components/SuggestKernel.wlx"]; 2 | TextField = ImportComponent["Components/TextField.wlx"]; 3 | PickAFile = ImportComponent["Components/PickAFile.wlx"]; 4 | Initcells = ImportComponent["Components/Initcells.wlx"]; 5 | Generic = ImportComponent["Components/Generic.wlx"]; 6 | Custom = ImportComponent["Components/Custom.wlx"]; 7 | Selector = ImportComponent["Components/Select.wlx"]; 8 | RequestPathToSave.wlx = ImportComponent["Components/RequestPathToSave.wlx"]; 9 | 10 | Component[OptionsPattern[]] := With[{port = OptionValue["ModalsPort"]}, 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | ] 22 | 23 | Options[Component] = {"ModalsPort" -> ""} 24 | 25 | Component -------------------------------------------------------------------------------- /Components/Mode.wlx: -------------------------------------------------------------------------------- 1 | (*/* uids for events */*) 2 | ButtonId = CreateUUID[]; 3 | Controller = CreateUUID[]; 4 | TextId = CreateUUID[]; 5 | 6 | (*/* callback symbol */*) 7 | Change = $Options["Change"]; 8 | 9 | (*/* state of a widget */*) 10 | State = If[!StringQ[$Options["Default"]], $Options["Default"], "System"]; 11 | 12 | (*/* handling clicks */*) 13 | EventHandler[ButtonId, Function[Null, 14 | Print[State]; 15 | Switch[State, 16 | "System", 17 | State = "Dark"; 18 | With[{client = $Client}, 19 | EventFire[Controller, State, <|"Client"->client|>]; 20 | ], 21 | 22 | "Dark", 23 | State = "Light"; 24 | With[{client = $Client}, 25 | EventFire[Controller, State, <|"Client"->client|>]; 26 | ], 27 | 28 | "Light", 29 | State = "System"; 30 | With[{client = $Client}, 31 | EventFire[Controller, State, <|"Client"->client|>]; 32 | ] 33 | ]; 34 | 35 | Change[State]; 36 | ]]; 37 | 38 |
46 | 47 | 48 | 49 | 50 | const text = document.getElementById(''); 51 | const fade = () => { 52 | text.classList.remove('hidden'); 53 | text.classList.remove('opacity-0'); 54 | setTimeout(() => { 55 | text.classList.add('opacity-0'); 56 | setTimeout(() => { 57 | text.classList.add('hidden'); 58 | }, 150); 59 | }, 100); 60 | }; 61 | 62 | this.on('System', (data) => { 63 | text.innerText = 'System'; 64 | fade(); 65 | }); 66 | 67 | this.on('Dark', (data) => { 68 | text.innerText = 'Dark'; 69 | fade(); 70 | }); 71 | 72 | this.on('Light', (data) => { 73 | text.innerText = 'Light'; 74 | fade(); 75 | }); 76 | 77 |
78 | -------------------------------------------------------------------------------- /Components/Notifications/Components/Custom.wlx: -------------------------------------------------------------------------------- 1 | CreateType[Notifications`Custom(*`*), init, {"Topic"->"Title", "Icon" -> With[{}, 2 | 6 | ], "Promise"->Null, "Body"->"Message", "DOM"->Null}] 7 | 8 | (*/* Might be an issue since this component it imported multiple times, could rewrite definitions */*) 9 | 10 | Echo["Notifications >> Created custom notifications type"]; 11 | 12 | init[n_] := With[{dom = CreateUUID[]}, 13 | Echo["Created! Spinner"]; 14 | n["DOM"] = dom; 15 | n["Promise"] = Promise[]; 16 | Then[n["Promise"], Function[Null, 17 | EventFire[#, Resolve, Null] &/@ n["Instances"] 18 | ], 19 | Function[Null, 20 | EventFire[#, Resolve, Null] &/@ n["Instances"] 21 | ]]; 22 | ]; 23 | 24 | Notifications`Custom(*`*) /: Delete[n_Notifications`Custom(*`*)] := ( 25 | EventFire[n["Promise"], Resolve, "Removed"]; 26 | ); 27 | 28 | Component[n_, client_, controller_] := With[{Uid = n["DOM"], Message = n["Body"], Icon = n["Icon"], Topic = n["Topic"], p = Promise[], LocalController = CreateUUID[]}, 29 | n["Instances"] = Append[n["Instances"], p]; 30 | Then[p, 31 | Function[Null, 32 | EventFire[Uid, "Remove", <|"Client"->client|>]; 33 | ], 34 | Function[Null, 35 | EventFire[Uid, "Remove", <|"Client"->client|>]; 36 | ] 37 | ]; 38 | 39 | With[{template = { 40 |
41 |
42 |
43 |
44 | 45 |
46 |
47 |

48 |
49 |
50 | 51 |
52 | 53 | this.on('Remove', () => { 54 | const doc = document.getElementById(''); 55 | doc.classList.remove('ease-out', 'duration-300'); 56 | doc.classList.add('ease-in', 'duration-100'); 57 | doc.classList.remove('opacity-100'); 58 | doc.classList.add('opacity-0'); 59 | setTimeout(() => { 60 | doc.remove(); 61 | }, 100); 62 | }); 63 | 64 |
65 | , 66 | "" 67 | } // StringRiffle 68 | }, 69 | 70 | <|"Data" -> template, "ID" -> Uid|> 71 | ] 72 | ]; 73 | 74 | 75 | Component -------------------------------------------------------------------------------- /Components/Notifications/Components/Dialog.wlx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WLJSTeam/wolfram-js-frontend/653c2a94c97f1c87b9fcb96a348f5c452ecba594/Components/Notifications/Components/Dialog.wlx -------------------------------------------------------------------------------- /Components/Notifications/Components/MessagesList.wlx: -------------------------------------------------------------------------------- 1 | {GenericTemplate, GenericScript} = ImportComponent["Generic.wlx"]; 2 | 3 | Component[OptionsPattern[]] := With[{Controller = OptionValue["Controller"]}, WebUILazyLoad[ 4 | With[{ 5 | MessageList = Table[ 6 | With[{Msg = GenericTemplate[Item["Type"], Item["Message"], "Class"->""]["Data"]}, 7 |
  • 8 | ] 9 | , {Item, Reverse @ ReleaseHold @ OptionValue["Data"]}], 10 | 11 | UId = CreateUUID[] 12 | }, 13 | 14 | EventHandler[UId, Function[Null, 15 | EventFire[Controller, "Remove", <|"Client"->Global`$Client (*`*)|>]; 16 | EventRemove[UId]; 17 | ]]; 18 | 19 | 58 | ] 59 | , "Event" -> Controller] ] 60 | 61 | Options[Component] = {"Event" -> "BlackHole"} 62 | 63 | Component -------------------------------------------------------------------------------- /Components/Notifications/Components/Types.wl: -------------------------------------------------------------------------------- 1 | BeginPackage["Notebook`Notifications`Types`", {"JerryI`Misc`Events`", "JerryI`Misc`Events`Promise`"}] 2 | 3 | Begin["`Private`"] 4 | 5 | 6 | 7 | End[] 8 | EndPackage[] -------------------------------------------------------------------------------- /Components/PromptTools.wlx: -------------------------------------------------------------------------------- 1 | 2 | Component[OptionsPattern[]] := With[{event = OptionValue["PromptToolbar"], notebook = OptionValue["Notebook"]}, 3 | 4 | If[notebook["AskedToExtend"] === True || n["ShowToolbox"] === True || True, 5 |
    6 | 15 | 24 | 25 | 26 |
    27 | , 28 | "" 29 | ] 30 | ] 31 | 32 | Options[Component] = {"Notebook"-> Null, "PromptToolbar" -> "", "Template" -> ""} 33 | 34 | Component -------------------------------------------------------------------------------- /Components/Settings.wlx: -------------------------------------------------------------------------------- 1 | 2 | 10 | -------------------------------------------------------------------------------- /Components/Sidebar/Body.wlx: -------------------------------------------------------------------------------- 1 | ItemList := ImportComponent["Components/ItemList.wlx"]; 2 | 3 | 4 | 5 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Components/Sidebar/Components/ItemDirectory.wlx: -------------------------------------------------------------------------------- 1 | ItemList := ImportComponent["ItemList.wlx"]; 2 | File = $Options["File"]; 3 | Level = $Options["Level"] + 1; 4 | 5 | Icons = $Options["Icons"]; 6 | 7 | Parameters = $Options["Parameters"]; 8 | 9 | Dropdown := ImportComponent["Dropdown.wlx"]; 10 | 11 | (*/* uids for events */*) 12 | ButtonId = CreateUUID[]; 13 | Controller = CreateUUID[]; 14 | Port = $Options["Port"]; 15 | 16 | (*/* state of a widget */*) 17 | State = "Empty"; 18 | 19 | (*/* handling clicks */*) 20 | EventHandler[ButtonId, Function[Null, 21 | Print[State]; 22 | Switch[State, 23 | "Empty", 24 | State = "Open"; 25 | With[{client = $Client}, 26 | EventFire[Controller, "Load", <|"Client"->client|>]; 27 | ], 28 | 29 | "Open", 30 | State = "Hidden"; 31 | With[{client = $Client}, 32 | EventFire[Controller, "Hide", <|"Client"->client|>]; 33 | ], 34 | 35 | "Hidden", 36 | State = "Open"; 37 | With[{client = $Client}, 38 | EventFire[Controller, "Show", <|"Client"->client|>]; 39 | ] 40 | ]; 41 | ]]; 42 | 43 | Selected = If[TrueQ[$Options["Selected"]], "bg-yellow-300", ""]; 44 | 45 |
    46 |
    47 | 58 | 59 | 60 |
    61 | 62 | 63 | 64 | 65 | const button = document.getElementById('svg-'); 66 | this.on('Load', (data) => { 67 | button.classList.add('rotate-90', 'text-gray-500'); 68 | }); 69 | 70 | this.on('Show', (data) => { 71 | button.classList.add('rotate-90', 'text-gray-500'); 72 | }); 73 | 74 | this.on('Hide', (data) => { 75 | button.classList.remove('rotate-90', 'text-gray-500'); 76 | }); 77 | 78 | 79 | 80 | 81 | 82 |
    -------------------------------------------------------------------------------- /Components/Sidebar/Components/ItemFile.wlx: -------------------------------------------------------------------------------- 1 | Dropdown := ImportComponent["Dropdown.wlx"]; 2 | 3 | File = $Options["File"]; 4 | 5 | Selected = If[TrueQ[$Options["Selected"]], "bg-gray-454-half dark:bg-gray-700", ""]; 6 | 7 | Port = $Options["Port"]; 8 | 9 | Icon = FileExtension[File] /. Join[$Options["Icons"], { 10 | "wln" -> 11 | , 12 | _ -> "" 13 | }]; 14 | 15 | Href = If[TrueQ[$Options["Selected"]], 16 |
    17 | 18 | 19 | 20 |
    21 | , 22 | If[MemberQ[Join[Keys[$Options["Icons"]], {"wln"}], FileExtension[File]], 23 | 24 | 25 | 26 | 27 | 28 | , 29 | 30 | 31 | 32 | 33 | 34 | ] 35 | ]; 36 | 37 | 38 |
    39 |
    40 | 41 | 42 |
    43 | -------------------------------------------------------------------------------- /Components/Sidebar/Components/ItemList.wlx: -------------------------------------------------------------------------------- 1 | Level = $Options["Level"]; 2 | Class = StringJoin[$Options["Class"], " pl-", ToString[Level]]; 3 | Path = $Options["Path"]; 4 | RawPath = $Options["RawPath"]; 5 | Current = $Options["Current"]; 6 | Parameters = $Options["Parameters"]; 7 | 8 | Icons = $Options["Icons"]; 9 | 10 | Port = $Options["Port"]; 11 | 12 | Dir := ImportComponent["ItemDirectory.wlx"]; 13 | Fl := ImportComponent["ItemFile.wlx"]; 14 | Pl := ImportComponent["ItemParent.wlx"]; 15 | 16 | If[!DirectoryQ[Path], Path = DirectoryName[Path]]; 17 | 18 | With[{ 19 | Ul = Table[ 20 | If[DirectoryQ[i], 21 | 22 |
  • , 23 |
  • 24 | ] 25 | , {i, Select[FileNames["*", Path], !StringMatchQ[#, ___~~".DS_Store"]&]}], 26 | 27 | Extra = 28 | With[{ 29 | parent = ParentDirectory[Path] 30 | }, 31 | If[Level == 0 && StringQ[parent] && $Env["parent_folder"] =!= parent, 32 |
  • 33 | , 34 | "" 35 | ] 36 | ] 37 | }, 38 |