diff --git a/.github/workflows/plutus-playground-e2e-tests.yml b/.github/workflows/plutus-playground-e2e-tests.yml deleted file mode 100644 index 3f698318d9..0000000000 --- a/.github/workflows/plutus-playground-e2e-tests.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Plutus Playground E2E Tests - -on: - schedule: - - cron: '0 2 * * *' - workflow_dispatch: - -jobs: - plutus-playground-e2e-tests: - runs-on: ubuntu-20.04 - steps: - - name: Checkout Plutus - uses: actions/checkout@v3 - - - name: Setup Haskell - uses: haskell/actions/setup@v2 - with: - ghc-version: '8.10.4' - cabal-version: '3.2.0.0' - - - name: Setup Nix - uses: cachix/install-nix-action@v18 - with: - nix_path: nixpkgs=channel:nixos-unstable - extra_nix_config: | - substituters = https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/ - trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= - - - name: Build Plutus Playground - run: nix-build -A plutus-playground.client -A plutus-playground.server - - - name: Run Plutus Playground - env: - CLIENT_PORT: 8009 - run: | - nix-shell --run 'plutus-playground-server' shell.nix & - while ! [ -d plutus-playground-client/generated ]; do echo "Waiting for server to generate purescript sources" && sleep 10; done - nix-shell --run '(cd plutus-playground-client && npm start)' shell.nix & - while ! echo exit | nc localhost 8009; do echo "Waiting for playground client on 8009" && sleep 10; done - - - name: Setup NodeJs - uses: actions/setup-node@v3 - with: - node-version: '12.12.0' - - - name: Setup Playwright - working-directory: ./plutus-playground-client/e2e-tests/ - run: | - npm install -D @playwright/test - npx playwright install - - - name: Run Tests - working-directory: ./plutus-playground-client/e2e-tests/ - run: | - npx playwright test - - - name: 'Upload Artifact' - uses: actions/upload-artifact@v3 - with: - name: html-report - path: plutus-playground-client/e2e-tests/html-report/index.html - retention-days: 5 \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0aa20caea6..5d2902aa6d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,7 +30,6 @@ jobs: - uses: nixbuild/nix-quick-install-action@v19 - run: | nix --extra-experimental-features 'nix-command flakes' --extra-experimental-features flakes flake lock --option trusted-public-keys "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option substituters "https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/" - nix-shell --extra-experimental-features 'nix-command flakes' --command "cd plutus-playground-client && (update-client-deps || update-client-deps)" --option trusted-public-keys "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option substituters "https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/" # Double-call to work around bug in spago2nix on first fetch # Disabled until we can find a way to run it only for Linux # nix-shell --command "updateMaterialized" --option trusted-public-keys "hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" --option substituters "https://hydra.iohk.io https://iohk.cachix.org https://cache.nixos.org/" git diff --exit-code diff --git a/.gitignore b/.gitignore index dd400639f6..c10d6b68e4 100644 --- a/.gitignore +++ b/.gitignore @@ -76,12 +76,9 @@ pkgs/.stack **/.spago/ **/.spago2nix/ **/.psa-stash -plutus-playground-client/generated plutus-pab-executables/demo/pab-nami/client/generated # Backend config files -marlowe-playground-server/playground.yaml -plutus-playground-server/playground.yaml plutus-pab/plutus-pab.yaml # Misc diff --git a/ARCHITECTURE.adoc b/ARCHITECTURE.adoc index 9eed2127fc..ac00f5ada3 100644 --- a/ARCHITECTURE.adoc +++ b/ARCHITECTURE.adoc @@ -37,20 +37,6 @@ include::plutus-contract/ARCHITECTURE.adoc[] include::plutus-use-cases/ARCHITECTURE.adoc[] -== Playground - -The Plutus Playground is our web-based environment for developing and -testing basic Plutus contracts. That means it's the main way that -anyone outside the team has interacted with out product! - -include::playground-common/ARCHITECTURE.adoc[] - -include::plutus-playground-server/ARCHITECTURE.adoc[] - -include::plutus-playground-client/ARCHITECTURE.adoc[] - -include::web-common/ARCHITECTURE.adoc[] - == Smart Contract Backend The smart contract backend provides the runtime environment for compiled Plutus contracts. It manages the state of contract instances and brokers messages between them and the nodes, users, and wallets that they interact with. diff --git a/README.adoc b/README.adoc index 476df0abfe..9680ee5f5f 100644 --- a/README.adoc +++ b/README.adoc @@ -14,7 +14,6 @@ This repository contains: * Plutus Platform ** Libraries which implement the Plutus Application Framework, a framework for writing applications that work with Cardano. ** A selection of end-to-end usecases written with the Plutus Application Framework -** The Plutus Playground, a web-based playground for learning and writing basic Plutus Applications. [IMPORTANT] ==== @@ -167,15 +166,6 @@ Run `cabal build plutus-pab` from the root to build the Plutus PAB library. See the link:./cabal.project[cabal project file] to see the other packages that you can build with `cabal`. -=== Deployment - -The Plutus Playground is automatically deployed upon certain pushes to GitHub - -* https://plutus-playground-plutus-apps-staging.plutus.aws.iohkdev.io/[Staging] is deployed from every commit pushed to `main` (this URL subject to change) -* https://playground.plutus.iohkdev.io/[Production] is deployed from every release tag (matching `vYYYY-MM-DD`) - -For more details, including instructions for setting up ad hoc testing deployments, see https://github.com/input-output-hk/plutus-ops[the plutus-ops repo]. - [[nix-advice]] == Nix diff --git a/bitte/default.nix b/bitte/default.nix index ce5120e63a..a5a2128a96 100644 --- a/bitte/default.nix +++ b/bitte/default.nix @@ -1,19 +1,10 @@ -{ plutus-playground, web-ghc, docs, pkgs }: +{ docs, pkgs }: let staticSite = pkgs.callPackage ./static-site.nix { }; playgroundStatic = pkgs.callPackage ./playground-static.nix { inherit staticSite; docs = docs.site; }; in { - web-ghc-server-entrypoint = pkgs.callPackage ./web-ghc-server.nix { - web-ghc-server = web-ghc; - }; - - plutus-playground-server-entrypoint = pkgs.callPackage ./plutus-playground-server.nix { - variant = "plutus"; - pkg = plutus-playground.server; - }; plutus-playground-client-entrypoint = playgroundStatic { - client = plutus-playground.client; variant = "plutus"; }; } diff --git a/bitte/playground-static.nix b/bitte/playground-static.nix index 5408839633..f4e242ff06 100644 --- a/bitte/playground-static.nix +++ b/bitte/playground-static.nix @@ -2,10 +2,10 @@ let shiftedDocs = linkFarm docs.name [{ name = "doc"; path = docs; }]; in -{ variant, client }: staticSite { +{ variant }: staticSite { root = (symlinkJoin { name = "${variant}-playground-client-and-docs"; - paths = [ client shiftedDocs ]; + paths = [ shiftedDocs ]; }); port-name = "${variant}_playground_client"; } diff --git a/bitte/plutus-playground-server.nix b/bitte/plutus-playground-server.nix deleted file mode 100644 index 024d23ebe5..0000000000 --- a/bitte/plutus-playground-server.nix +++ /dev/null @@ -1,8 +0,0 @@ -# Needed variables: -# NOMAD_PORT_${variant}_playground_server -{ writeShellScriptBin, pkg, variant, symlinkJoin, lib, cacert, z3 }: -writeShellScriptBin "entrypoint" '' - export PATH=${lib.makeBinPath [ pkg z3 ]} - export SYSTEM_CERTIFICATE_PATH=${cacert}/etc/ssl/certs/ca-bundle.crt - exec ${variant}-playground-server webserver -p $NOMAD_PORT_${variant}_playground_server -'' diff --git a/bitte/web-ghc-server.nix b/bitte/web-ghc-server.nix deleted file mode 100644 index 768267c6a0..0000000000 --- a/bitte/web-ghc-server.nix +++ /dev/null @@ -1,7 +0,0 @@ -# Needed variables: -# NOMAD_PORT_web_ghc_server -# NOMAD_IP_web_ghc_server -{ writeShellScriptBin, web-ghc-server, symlinkJoin }: -writeShellScriptBin "entrypoint" '' - exec -a web-ghc-server ${web-ghc-server}/bin/web-ghc-server webserver --port "$NOMAD_PORT_web_ghc_server" --bind "$NOMAD_IP_web_ghc_server" -'' diff --git a/cabal.project b/cabal.project index 233e789d30..c128434456 100644 --- a/cabal.project +++ b/cabal.project @@ -35,12 +35,10 @@ packages: cardano-streaming plutus-ledger-constraints plutus-pab plutus-pab-executables - plutus-playground-server plutus-script-utils plutus-tx-constraints plutus-use-cases rewindable-index - web-ghc -- We never, ever, want this. write-ghc-environment-files: never diff --git a/ci.nix b/ci.nix index edd1de7e3b..9cc5767667 100644 --- a/ci.nix +++ b/ci.nix @@ -93,7 +93,7 @@ let inherit forceNewEval; } // pkgs.lib.optionalAttrs (!rootsOnly) (filterCross { # build relevant top level attributes from default.nix - inherit (packages) docs tests plutus-playground plutus-use-cases; + inherit (packages) docs tests plutus-use-cases; # Build the shell expression to be sure it works on all platforms # diff --git a/default.nix b/default.nix index 4896ed417c..3b0b24bed1 100644 --- a/default.nix +++ b/default.nix @@ -28,24 +28,12 @@ in rec { inherit pkgs plutus-apps; - inherit (plutus-apps) web-ghc; - inherit (haskell.packages.plutus-pab-executables.components.exes) plutus-pab-examples plutus-uniswap; webCommon = pkgs.callPackage sources.web-common { inherit (plutus-apps.lib) gitignore-nix; }; - plutus-playground = pkgs.recurseIntoAttrs rec { - haddock = plutus-apps.plutus-haddock-combined; - - inherit (pkgs.callPackage ./plutus-playground-client { - inherit (plutus-apps) purs-tidy; - inherit (plutus-apps.lib) buildPursPackage buildNodeModules filterNpm gitignore-nix; - inherit haskell webCommon; - }) client server start-backend generate-purescript; - }; - # TODO: Fails for now because of webpack can't include `nami-wallet` lib in it's bundle. # To reproduce the error, run `npm run build:webpack:prod` in `plutus-pab-executables/demo/pab-nami/client` pab-nami-demo = pkgs.recurseIntoAttrs rec { @@ -74,7 +62,6 @@ rec { inherit pkgs docs; inherit (plutus-apps.lib) gitignore-nix; inherit (plutus-apps) fixStylishHaskell fix-purs-tidy fixPngOptimization fixCabalFmt; - inherit plutus-playground web-ghc; src = ./.; }; @@ -86,5 +73,5 @@ rec { build-and-push-devcontainer-script = import ./nix/devcontainer/deploy/default.nix { inherit pkgs plutus-apps; }; # Packages needed for the bitte deployment - bitte-packages = import ./bitte { inherit plutus-playground docs pkgs web-ghc; }; + bitte-packages = import ./bitte { inherit docs pkgs; }; } diff --git a/deployment.nix b/deployment.nix index 4070e6ec5b..e99d212bb5 100644 --- a/deployment.nix +++ b/deployment.nix @@ -3,7 +3,7 @@ , packages ? import ./. { inherit system enableHaskellProfiling; } }: let - inherit (packages) pkgs plutus-apps plutus-playground pab-nami-demo plutus-chain-index pab-cli docs webCommon; + inherit (packages) pkgs plutus-apps pab-nami-demo plutus-chain-index pab-cli docs webCommon; inherit (pkgs) lib utillinux python3 nixpkgs-fmt; inherit (plutus-apps) haskell; diff --git a/doc/conf.py b/doc/conf.py index 6ab83d1cb7..541ecaabf2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -11,15 +11,6 @@ sys.path.insert(0, abspath(join(dirname(__file__)))) sys.path.append(os.path.abspath('exts')) -# -- Doc config values -marlowe_playground_url = "https://alpha.marlowe.iohkdev.io/" -plutus_playground_url = "https://alpha.plutus.iohkdev.io/" - -rst_epilog = """ -.. _Plutus Playground: {0} -.. _Marlowe Playground: {1} -""".format(plutus_playground_url, marlowe_playground_url) - # -- RTD configuration ------------------------------------------------ on_rtd = os.environ.get("READTHEDOCS", None) == "True" diff --git a/doc/plutus/tutorials/index.rst b/doc/plutus/tutorials/index.rst index 40caad581e..5acf4a9609 100644 --- a/doc/plutus/tutorials/index.rst +++ b/doc/plutus/tutorials/index.rst @@ -7,7 +7,6 @@ Tutorials :maxdepth: 2 :titlesonly: - plutus-playground basic-apps basic-apps-constraints contract-testing diff --git a/doc/plutus/tutorials/plutus-playground.rst b/doc/plutus/tutorials/plutus-playground.rst deleted file mode 100644 index d1b6f101ae..0000000000 --- a/doc/plutus/tutorials/plutus-playground.rst +++ /dev/null @@ -1,242 +0,0 @@ -.. highlight:: haskell -.. _basic_playground_tutorial: - -Compiling and testing a Plutus app in the Plutus Playground -=========================================================== - -The Plutus Playground consists of a code editor and a simulator. - -.. figure:: images/playground.png - - Plutus Playground (code editor) - -You can write Plutus apps in the code editor and test them in the simulator. - -.. note:: - - Plutus apps are distributed applications with on-chain and off-chain state. - Their main task is to build the transactions that produce and spend Plutus script outputs. - -The Plutus Playground includes a number of sample apps. -In this tutorial you are going to run through two of these sample apps. - -.. _playground-compiling-hello-world: - -You can find a video that covers this tutorial on `youtube `_. - -Running the "Hello, World" app ------------------------------- - -When you first open the Plutus Playground, the code editor is populated with the "Vesting" app. -To load the "Hello, World" app, click the "Hello, World" link in the top row. -This app is much simpler than the vesting app. -In fact, the app itself only consists of a single line, and a type annotation: - -.. literalinclude:: HelloWorldApp.hs - :start-after: BLOCK1 - :end-before: BLOCK2 - -Running the first simulation of the app -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Now that the app has been compiled, you can run it in the simulated environment. -The builtin examples are already compiled, so you can click **Simulate** right away. - -.. note:: - - If an app has not been compiled yet, the **Simulate** button is deactivated. - To compile the app, click the **Compile** button. - The feedback line at the bottom of the code editor changes to "Compiling...". - When the app has been compiled without errors, the feedback message changes to "Compilation successful", and the **Simulate** button is active. - -Click the **Simulate** button. -The code editor is replaced by the simulator. - -.. figure:: images/playground-simulator.png - - Plutus Playground (simulator) - -You can use the simulator to define complex scenarios with multiple agents trading and communicating over Cardano. -For the "Hello, World" app however you don't need to change anything in the simulator. -You can click **Evaluate** right away. -This sends the simulation to the server, alongside the source code of our app. -When the server has finished running the simulation, the transactions pane is displayed, which presents the outcome of the simulation. - -Interpreting the results of the first simulation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The "Transactions" pane has four sections: Blockchain, final balances, logs and trace. - -Blockchain -"""""""""" - -The blockchain section shows all the transactions that were produced during the simulation. - -.. figure:: images/playground-transactions.png - - Simulated blockchain with a single transaction - - -Each simulation is run on a fresh blockchain. -The "Hello, World" simulation only results in a single transaction called "Slot 0, Tx 0". -This is the initial transaction that distributes some funds to the simulated agents. -The initial transaction is preselected when you open the blockchain view. -There are two sections with detailed information about the selected transaction. -The first section shows the inputs and outputs of the selected transaction, and some other details. -The second section has a table with the balances of each address *after* the selected transaction. -You can see that wallet 1 and wallet 2 each have one hundred lovelace. - -Final Balances -"""""""""""""" - -Below this a chart shows the final balances at the end of the simulation, after all transactions. -Since you only have a single transaction, the final balances are exactly the same as the "Balances Carried Forward" from the initial transaction. - -.. figure:: images/playground-logs.png - - Log output from the "Hello, World" simulation - -Logs -"""" - -The "Logs" section displays messages that were produced by the emulator during the simulation. -The logs tell us that the initial transaction was validated, then the slot number changed, and then the app running in each wallet produced a log message saying "Hello, World". - -.. note:: - - Each of the simulated wallets has its own application instance with its own state. This is why the message "Hello, world" appears twice in the emulator logs. - -Trace -""""" - -The final "Trace" section contains some more detailed information about the emulator. -This data is useful for diagnosing problems with the app. - -Adding a payment to the first simulation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Now you can extend the simulation by adding a new wallet and a payment between two wallets. -Click the **Close** button to return to the simulator. -In the "Wallets" section of the simulator there is a box for each simulated wallet. -Click **Add Wallet** to add a new simulated wallet. -Now click **Pay to Wallet** on wallet 3. In the "Actions" section there are now two entries, a "Wait" action and a "Pay to Wallet" action. - -In the "Pay to Wallet" action, enter the number 2 into the "Recipient" field. -This means that wallet 2 is the recipient of the payment (the payer is wallet 3). -Change the amount to five lovelace. - -Now you need to make sure our simulation runs long enough for the payment to appear on the blockchain. -The simulation ends after the last action in the action sequence. -To make it run a little longer, click **Add Wait Action**. -Another "Wait" action is added to the end of the list. - -.. figure:: images/playground-payment.png - - Action sequence for a payment of five lovelace from wallet 3 to wallet 2. - -Now click **Evaluate**. -The results pane is displayed and you can see that the blockchain has two transactions. -Click the second transaction. -It has one input (a public-key output belonging to wallet 3) and two outputs: -One output with five lovelace belonging to wallet 2, and another output with the remaining five lovelace belonging to wallet 3. -This second output is called a *change output*. -It is needed because the input that was spent contained ten lovelace, and you only wanted to pay five of them to wallet 2. -Therefore the remaining five lovelace were given back to wallet 3. - -The "Balances carried forward" and "Final balances" sections also reflect the payment that was made. - -Finally, the logs indicate that there are now three instances running, because the "Hello, world" message shows up three times. -You can see that the payment transaction was validated, and that the simulation ran until slot 12. - -Running the "Vesting" app -------------------------- - -You've seen how to compile code, run simulations and make sense of their output. -In the second part of this tutorial you are going to run an app that actually does something on the blockchain, and you're going to feed input to it using the endpoints that it provides. - -Click the "Vesting" link in the row of demo files at the top. -The vesting app is loaded into the code editor. -You are not going to look at the source for now (there are comments in the code explaining how it works). - -.. note:: - - The vesting app locks some funds in a script. The recipient of the funds can retrieve them later, when some time has passed. - -Click **Compile** and then **Simulate** to get to the simulator. -The vesting app comes with a predefined simulation of a total of six actions. -Besides the "Wait" actions which you've seen before, there are some app-specific actions: "vest funds" and "retrieve funds". -The vesting app defines endpoints with those names and uses them to ask for input. - -The box for the "vest funds" action is empty. -This endpoint is there to tell the app to make a payment to the address of the vesting script. -The box for the "retrieve funds" endpoint has an input field for an Ada amount. -In each of the two invocations you retrieve four lovelace. - -Each endpoint used by an app has its own type (number, text, currency, etc.) that is defined in the source code. -The Plutus Playground uses this type to provide the correct set of form elements for creating a value of the type. -That way you don't need to manually enter JSON objects into the action boxes, and you can perform some basic validation of the values. - -Running the vesting simulation -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Click **Evaluate** to view what the simulation does. -There are four transactions. - -.. figure:: images/playground-vesting-blockchain.png - - Blockchain of the vesting simulation. - - The highlighted transaction locks eight lovelace with the vesting script. - -Select the transaction in slot 1. -One of its outputs is a script output. -This is the vesting script that locks eight lovelace. - -Now select the next transaction (Slot 21, Tx 0). -It spends the script output, paying four lovelace to wallet 1 and the remaining four lovelace to the vesting script. - -Note that the script address of the input and of the output are identical. -The script address always stays the same, but the number of outputs at the address changes over time. - -.. note:: - - At any point in time there may be zero, one or more outputs at the script address. All those outputs together constitute the *state* of the script. You change the state by spending and producing outputs at the script address. - -The final transaction (Slot 61, Tx 0) takes the remaining four lovelace from the script and places them in a public-key output belonging to wallet 1. - -At the end of the simulation, wallet 1 has eight lovelace more than it started out with. -The money came from wallet 2 via the vesting script. -Note the timing: Wallet 1 retrieved the funds in slot 21 and 61. -The vesting contract defines how long the funds have to stay locked in the script before the recipient can retrieve them. - -Error Handling -^^^^^^^^^^^^^^ - -Let's return to the simulator by clicking the "X" button on the transactions pane. -Change the first "Wait" action to wait for 10 blocks instead of 20 and click **Evaluate**. - -.. figure:: images/playground-vesting-actions-modified.png - - Vesting simulation modified to produce an error. - -Now there are only two transactions. -The simlation finished with the total of eight lovelace still locked by the script. - -Scroll down to the "Trace" section of the transactions view. -Among the messages for slot 11 there is one that says ``Contract instance stopped with error``. -It explains the reason for the failure. -Wallet 1 attempted to retrieve the funds before it was allowed to do so. -The app instance for wallet 1 then stopped with an error and did not process any more endpoint calls. - -It is important to realise the source of the error. -The error came from the *client* (wallet one), not from the blockchain. -If it had come from the blockchain you would have seen a failed transaction in the logs. - -The app running in wallet one did not attempt to submit a transaction for retrieving the funds, because such a transaction would fail to validate. -Instead, the app stopped with an error, leaving the on-chain state untouched. -This is another example the different notions of state that you are dealing with in Plutus apps. - -Exercise --------- - -As an exercise, load the "Starter" app, compile it and run the default simulation. Check the logs to see an example of an on-chain error in the Playground. diff --git a/doc/reference/index.rst b/doc/reference/index.rst index 7acd1e90e5..ae6900f837 100644 --- a/doc/reference/index.rst +++ b/doc/reference/index.rst @@ -14,4 +14,3 @@ Elsewhere --------- - `Haddock generated documentation `_ -- `The Plutus playground `_ diff --git a/flake.nix b/flake.nix index fe7602101f..6ff144b9e6 100644 --- a/flake.nix +++ b/flake.nix @@ -1,7 +1,7 @@ # NOTE: This flake is only provided as interface to `bitte` and shouldn't be used otherwise # # Occasionally building flake builds will segfault. The workaround for this is to -# disable the garbage collector `GC_DONT_GC=1 nix build .#web-ghc-server +# disable the garbage collector `GC_DONT_GC=1 nix build .#docs # # In case you are not sure if you should be using this flake, the answer is: No. { diff --git a/nix/modules/plutus-playground.nix b/nix/modules/plutus-playground.nix deleted file mode 100644 index cb24ab09ab..0000000000 --- a/nix/modules/plutus-playground.nix +++ /dev/null @@ -1,94 +0,0 @@ -{ config, lib, pkgs, ... }: -let - inherit (lib) types mkOption mkIf; - cfg = config.services.plutus-playground; -in -{ - options.services.plutus-playground = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - If enabled the plutus-playground server will be started. - ''; - }; - - webghcURL = mkOption { - type = types.str; - default = "http://localhost:4000"; - description = '' - The webghc endpoint serving /runghc for compilation requests. - ''; - }; - - frontendURL = mkOption { - type = types.str; - default = "http://localhost:4000"; - description = '' - URL where the plutus playground is served. - ''; - }; - - githubCallbackPath = mkOption { - type = types.str; - default = "/#/gh-oauth-cb"; - description = '' - The github callback path - ''; - }; - - port = mkOption { - type = types.port; - default = 4000; - description = '' - Port the plutus-playground server should bind to. - ''; - }; - playground-server-package = mkOption { - type = types.package; - description = '' - plutus playground package to execute. - ''; - }; - }; - - config = mkIf cfg.enable { - - systemd.services.plutus-playground = { - after = [ "network.target" ]; - wantedBy = [ "nginx.service" ]; - before = [ "nginx.service" ]; - - serviceConfig = { - # runtime behavior - TimeoutStartSec = 5; - TimeoutStopSec = 5; - Restart = "always"; - - # sane defaults for security - DynamicUser = true; - ProtectKernelTunables = true; - ProtectControlGroups = true; - ProtectKernelModules = true; - PrivateDevices = true; - SystemCallArchitectures = "native"; - }; - - script = '' - if [ -f /var/lib/playgrounds/plutus.env ]; then - echo "Loading environment config from '/var/lib/playgrounds/plutus.env'" - source /var/lib/playgrounds/plutus.env - else - echo "No environment config. Using defaults" - fi - - export WEBGHC_URL=${cfg.webghcURL} - export FRONTEND_URL=${cfg.frontendURL} - export GITHUB_CALLBACK_PATH=${cfg.githubCallbackPath} - - ${cfg.playground-server-package}/bin/plutus-playground-server webserver -p ${builtins.toString cfg.port}; - ''; - }; - }; - -} diff --git a/nix/modules/web-ghc.nix b/nix/modules/web-ghc.nix deleted file mode 100644 index 5662cdee7a..0000000000 --- a/nix/modules/web-ghc.nix +++ /dev/null @@ -1,73 +0,0 @@ -{ config, lib, pkgs, ... }: -let - inherit (lib) types mkOption mkIf; - cfg = config.services.web-ghc; -in -{ - options.services.web-ghc = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - If enabled the web-ghc service will be started. - ''; - }; - ipAddress = mkOption { - type = types.str; - default = "0.0.0.0"; - description = '' - IP address to bind to. - ''; - }; - port = mkOption { - type = types.port; - default = 4002; - description = '' - Port the web-ghc service should bind to. - ''; - }; - web-ghc-package = mkOption { - type = types.package; - description = '' - ghc-web package to execute. - ''; - }; - timeout = mkOption { - type = types.int; - default = 80; - description = '' - Interpretation timeout in seconds. - ''; - }; - }; - - config = mkIf cfg.enable { - - systemd.services.web-ghc = { - after = [ "network.target" ]; - wantedBy = [ "multi-user.target" ]; - serviceConfig = { - # runtime behavior - TimeoutStartSec = 5; - TimeoutStopSec = 5; - CapabilityBoundingSet = "~CAP_SYS_ADMIN"; - Restart = "always"; - ExecStart = "${cfg.web-ghc-package}/bin/web-ghc-server webserver -b ${cfg.ipAddress} -p ${builtins.toString cfg.port} -t ${builtins.toString cfg.timeout}"; - - # allow binding on port 80 - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; - - - # sane defaults for security - DynamicUser = true; - ProtectKernelTunables = true; - ProtectControlGroups = true; - ProtectKernelModules = true; - PrivateDevices = true; - SystemCallArchitectures = "native"; - - }; - }; - }; - -} diff --git a/nix/pkgs/default.nix b/nix/pkgs/default.nix index 556f249954..385f706a62 100644 --- a/nix/pkgs/default.nix +++ b/nix/pkgs/default.nix @@ -78,9 +78,6 @@ let # sphinx haddock support sphinxcontrib-haddock = pkgs.callPackage (sources.sphinxcontrib-haddock) { pythonPackages = pkgs.python3Packages; }; - # ghc web service - web-ghc = pkgs.callPackage ./web-ghc { inherit haskell; }; - # combined haddock documentation for all public plutus libraries plutus-haddock-combined = let @@ -117,7 +114,6 @@ in inherit haskell cabal-install cardano-repo-tool stylish-haskell hlint haskell-language-server haskell-language-server-wrapper hie-bios cabal-fmt; inherit purs-tidy purs-0_14_3 spago spago2nix purescript-language-server psa; inherit fix-purs-tidy fixStylishHaskell fixCabalFmt fixPngOptimization updateClientDeps; - inherit web-ghc; inherit easyPS plutus-haddock-combined; inherit lib; } diff --git a/nix/pkgs/haskell/haskell.nix b/nix/pkgs/haskell/haskell.nix index 155c2e6f43..78cdd578f3 100644 --- a/nix/pkgs/haskell/haskell.nix +++ b/nix/pkgs/haskell/haskell.nix @@ -68,13 +68,11 @@ let plutus-ledger-constraints.package.buildable = false; plutus-pab.package.buildable = false; plutus-pab-executables.package.buildable = false; - plutus-playground-server.package.buildable = false; # Would also require libpq plutus-script-utils.package.buildable = false; plutus-tx-constraints.package.buildable = false; plutus-tx-plugin.package.buildable = false; plutus-use-cases.package.buildable = false; plutus-example.package.buildable = false; - web-ghc.package.buildable = false; # These need R plutus-core.components.benchmarks.cost-model-test.buildable = lib.mkForce false; plutus-core.components.benchmarks.update-cost-model.buildable = lib.mkForce false; @@ -187,7 +185,6 @@ let plutus-example.ghcOptions = [ "-Werror" ]; plutus-ledger.ghcOptions = [ "-Werror" ]; plutus-ledger-constraints.ghcOptions = [ "-Werror" ]; - plutus-playground-server.ghcOptions = [ "-Werror" ]; plutus-pab.ghcOptions = [ "-Werror" ]; plutus-pab-executables.ghcOptions = [ "-Werror" ]; plutus-script-utils.ghcOptions = [ "-Werror" ]; diff --git a/nix/pkgs/web-ghc/default.nix b/nix/pkgs/web-ghc/default.nix deleted file mode 100644 index bfb3bc7636..0000000000 --- a/nix/pkgs/web-ghc/default.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ haskell, makeWrapper, runCommand, extraPackagesFun ? ps: [ ], writeShellScriptBin, bubblewrap, lib, util-linux }: -let - web-ghc-server = haskell.packages.web-ghc.components.exes.web-ghc-server; - - runtimeGhc = haskell.project.ghcWithPackages (ps: [ - ps.playground-common - ps.plutus-core - ps.plutus-tx - ps.plutus-contract - ps.plutus-ledger - ] ++ (extraPackagesFun ps)); - - runtimeGhcWrapped = writeShellScriptBin "runghc" '' - export PATH=$PATH:${lib.makeBinPath [ bubblewrap runtimeGhc util-linux ]} - echo $PATH - echo AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - exec setpriv --ambient-caps -all -- \ - bwrap --ro-bind /nix /nix --ro-bind /proc /proc --dev /dev --ro-bind "''${@: -1}" "''${@: -1}" --unshare-all -- \ - runghc "$@" - ''; -in -runCommand "web-ghc" { buildInputs = [ makeWrapper ]; } '' - # We need to provide the ghc interpreter with the location of the ghc lib dir and the package db - mkdir -p $out/bin - ln -s ${web-ghc-server}/bin/web-ghc-server $out/bin/web-ghc-server - wrapProgram $out/bin/web-ghc-server --set GHC_BIN_DIR ${runtimeGhc}/bin -'' diff --git a/nix/tests/default.nix b/nix/tests/default.nix index e5b018670a..661e9ed927 100644 --- a/nix/tests/default.nix +++ b/nix/tests/default.nix @@ -5,8 +5,6 @@ , fixCabalFmt , fixPngOptimization , src -, plutus-playground -, web-ghc , docs , vmCompileTests ? false }: @@ -42,8 +40,4 @@ pkgs.recurseIntoAttrs { src = cleanSrc; inherit fixPngOptimization; }; - - vmTests = pkgs.callPackage ./vm.nix { - inherit vmCompileTests plutus-playground web-ghc docs; - }; } diff --git a/nix/tests/vm-tests/all.nix b/nix/tests/vm-tests/all.nix deleted file mode 100644 index 430980aa59..0000000000 --- a/nix/tests/vm-tests/all.nix +++ /dev/null @@ -1,176 +0,0 @@ -{ makeTest -, lib -, docs -, plutus-playground -, web-ghc -, vmCompileTests # when enabled the test tries to compile plutus/marlowe code on webghc -}: -let - plutusApiRequest = builtins.toFile "plutus-request.json" (builtins.readFile ./contract-api-request.json); -in -makeTest { - skipLint = true; - name = "all"; - nodes = { - - # --------------------------------------------------------------------------------------------------------------- - # pab : 192.168.1.1 - running plutus pab - # -------------------------------------------------------------------------------------------------------------- - - # --------------------------------------------------------------------------------------------------------------- - # playgrounds : 192.168.1.2 - running plutus/marlowe playgrounds and nginx - # -------------------------------------------------------------------------------------------------------------- - - playgrounds = { pkgs, ... }: { - imports = [ - ../../modules/plutus-playground.nix - ]; - - networking = { - firewall.allowedTCPPorts = [ 7070 8080 9090 ]; - extraHosts = '' - 127.0.0.1 plutus-playground - 192.168.1.3 webghc - ''; - dhcpcd.enable = false; - interfaces.eth1.ipv6.addresses = lib.mkOverride 0 [{ address = "fd00::2"; prefixLength = 64; }]; - interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [{ address = "192.168.1.2"; prefixLength = 24; }]; - }; - - services = { - plutus-playground = { - enable = true; - port = 4000; - playground-server-package = plutus-playground.server; - webghcURL = "http://webghc"; - }; - - nginx = { - enable = true; - recommendedGzipSettings = true; - recommendedProxySettings = true; - recommendedOptimisation = true; - - upstreams = { - plutus-playground.servers."127.0.0.1:4000" = { }; - marlowe-playground.servers."127.0.0.1:4001" = { }; - marlowe-dashboard.servers."192.168.1.1:8080" = { }; - }; - virtualHosts = { - "plutus-playground" = { - listen = [{ addr = "0.0.0.0"; port = 8080; }]; - locations = { - "/api" = { - proxyPass = "http://plutus-playground"; - proxyWebsockets = true; - }; - "^~ /doc/" = { - alias = "${docs.site}/"; - extraConfig = '' - error_page 404 = @fallback; - ''; - }; - "/" = { - root = "${plutus-playground.client}"; - extraConfig = '' - error_page 404 = @fallback; - ''; - }; - "@fallback" = { - proxyPass = "http://plutus-playground"; - proxyWebsockets = true; - extraConfig = '' - error_page 404 = @fallback; - ''; - }; - }; - }; - }; - }; - }; - - environment.systemPackages = with pkgs; [ curl ]; - }; - - # --------------------------------------------------------------------------------------------------------------- - # webghc : 192.168.1.3 - running webghc with plutus/marlowe deps - # -------------------------------------------------------------------------------------------------------------- - - webghc = { pkgs, ... }: { - - virtualisation.memorySize = 1024; - - networking = { - firewall.allowedTCPPorts = [ 80 ]; - dhcpcd.enable = false; - interfaces.eth1.ipv6.addresses = lib.mkOverride 0 [{ address = "fd00::3"; prefixLength = 64; }]; - interfaces.eth1.ipv4.addresses = lib.mkOverride 0 [{ address = "192.168.1.3"; prefixLength = 24; }]; - }; - - imports = [ - ../../modules/web-ghc.nix - ]; - services = { - web-ghc = { - enable = true; - port = 80; - web-ghc-package = web-ghc; - }; - }; - }; - }; - testScript = '' - playgrounds.start() - webghc.start() - - # - # assert connectivity - # - playgrounds.wait_for_unit("network-online.target") - - # Refer to configuration above to see what - # service each individual port relates to. - webghc.wait_for_unit("network-online.target") - playgrounds.succeed("ping -c1 192.168.1.2") - playgrounds.succeed("ping -c1 192.168.1.3") - webghc.succeed("ping -c1 192.168.1.2") - webghc.succeed("ping -c1 192.168.1.3") - - - # - # playground / frontend asserts - # - playgrounds.wait_for_unit("plutus-playground.service") - playgrounds.wait_for_unit("nginx.service") - playgrounds.wait_for_open_port(8080) - - with subtest("********************************************************************************************* TEST: All content is being served on playgrounds"): - res = playgrounds.succeed("curl --silent http://plutus-playground:8080/") - assert "plutus" in res, "Expected string 'plutus' from 'http://plutus-playground:8080'. Actual: {}".format(res) - - res = playgrounds.succeed("curl --silent http://plutus-playground:8080/doc/") - assert "Plutus Tools" in res, "Expected string 'Plutus Tools' from 'http://plutus-playground:8080/doc/'. Actual: {}".format(res) - - res = playgrounds.succeed("curl --silent http://plutus-playground:8080/doc/plutus/tutorials/") - assert "Tutorials" in res, "Expected string 'Tutorials' from 'http://plutus-playground:8080/doc/plutus/tutorials/'. Actual: {}".format(res) - - # - # webghc asserts - # - webghc.wait_for_unit("web-ghc.service") - webghc.wait_for_open_port(80) - - # - # pab asserts - # - - '' + lib.optionalString (vmCompileTests) '' - # - # plutus-playground / webghc : using api/contract - # marlowe-playground / webghc : using /runghc - # - with subtest("********************************************************************************************* TEST: compilation works"): - res = playgrounds.succeed("curl --silent -H 'Content-Type: application/json' --request POST --data @${plutusApiRequest} http://plutus-playground:8080/api/contract") - assert "Right" in res, "Expected response wrapped in 'Right'. Actual: {}".format(res) - ''; -} diff --git a/nix/tests/vm-tests/contract-api-request.json b/nix/tests/vm-tests/contract-api-request.json deleted file mode 100644 index e1788a8458..0000000000 --- a/nix/tests/vm-tests/contract-api-request.json +++ /dev/null @@ -1 +0,0 @@ -"import qualified Data.Text as T\nimport Playground.Contract\nimport Plutus.Contract hiding (when)\nimport PlutusTx.Prelude\n\n-- | A 'Contract' that logs a message.\nhello :: Contract () BlockchainActions T.Text ()\nhello = logInfo @String \"Hello, world\"\n\nendpoints :: Contract () BlockchainActions T.Text ()\nendpoints = hello\n\nmkSchemaDefinitions ''BlockchainActions\n\n$(mkKnownCurrencies [])\n\n$ensureKnownCurrencies\n" diff --git a/nix/tests/vm-tests/plutus-playground.nix b/nix/tests/vm-tests/plutus-playground.nix deleted file mode 100644 index 8a62e7c62b..0000000000 --- a/nix/tests/vm-tests/plutus-playground.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ makeTest, writeText, plutus-playground }: -let - envFile = writeText "plutus.env" '' - JWT_SIGNATURE="yadayadayada" - FRONTEND_URL="http://localhost:8080" - GITHUB_CALLBACK_PATH="/#/gh-oauth-cb" - GITHUB_CLIENT_ID="314123123a312fe" - GITHUB_CLIENT_SECRET="kljfks234dskjhfeskjr" - ''; -in -makeTest { - name = "plutus-playground"; - skipLint = true; - machine = { pkgs, ... }: - { - imports = [ ../../modules/plutus-playground.nix ]; - environment.systemPackages = with pkgs; [ curl ]; - services.plutus-playground = { - enable = true; - port = 4000; - webghcURL = "http://localhost:4000"; - frontendURL = "http://localhost:4000"; - githubCallbackPath = "/#/gh-oauth-cb"; - playground-server-package = plutus-playground.server; - }; - }; - testScript = '' - # fmt: off - machine.start() - machine.succeed("systemctl start plutus-playground") - machine.wait_for_unit("plutus-playground.service") - machine.wait_for_open_port(4000) - ''; - -} diff --git a/nix/tests/vm-tests/web-ghc.nix b/nix/tests/vm-tests/web-ghc.nix deleted file mode 100644 index dcf7034cb9..0000000000 --- a/nix/tests/vm-tests/web-ghc.nix +++ /dev/null @@ -1,47 +0,0 @@ -{ writeText, makeTest, web-ghc }: -let - testCode = '' - module Main where - main :: IO () - main = return () - ''; - validCompileRequest = writeText "req.json" (builtins.toJSON { - code = testCode; - implicitPrelude = true; - }); - invalidCompileRequest = writeText "req.json" (builtins.toJSON { - code = "this-is-not-valid"; - implicitPrelude = true; - }); - -in -makeTest { - name = "web-ghc"; - skipLint = true; - machine = { pkgs, ... }: - { - imports = [ ../../modules/web-ghc.nix ]; - environment.systemPackages = with pkgs; [ curl ]; - services.web-ghc = { - enable = true; - port = 80; - web-ghc-package = web-ghc; - timeout = 360; - }; - }; - testScript = '' - # fmt: off - machine.start() - machine.wait_for_unit("web-ghc.service") - machine.wait_for_open_port(80) - - with subtest("********************************************************************************************* TEST: Can process a valid compilation request"): - response = machine.succeed("curl -sSfL -H 'Content-Type: application/json' --request POST --data @${validCompileRequest} http://localhost:80/runghc") - assert "Right" in response, "Expected response wrapped in 'Right'. Actual: {}".format(response) - - with subtest("********************************************************************************************* TEST: Can process a invalid compilation request"): - response = machine.succeed("curl -sSfL -H 'Content-Type: application/json' --request POST --data @${invalidCompileRequest} http://localhost:80/runghc") - assert "Left" in response, "Expected response wrapped in 'Left'. Actual: {}".format(response) - ''; - -} diff --git a/nix/tests/vm.nix b/nix/tests/vm.nix deleted file mode 100644 index 1f9c3b44c1..0000000000 --- a/nix/tests/vm.nix +++ /dev/null @@ -1,17 +0,0 @@ -{ pkgs -, plutus-playground -, web-ghc -, docs -, vmCompileTests -}: -let - inherit (pkgs.stdenv) isDarwin; - testing = import (pkgs.path + "/nixos/lib/testing-python.nix") { system = builtins.currentSystem; }; - makeTest = testing.makeTest; - tests = pkgs.recurseIntoAttrs { - plutus-playground-server = pkgs.callPackage ./vm-tests/plutus-playground.nix { inherit makeTest plutus-playground; }; - web-ghc = pkgs.callPackage ./vm-tests/web-ghc.nix { inherit makeTest web-ghc; }; - all = pkgs.callPackage ./vm-tests/all.nix { inherit makeTest plutus-playground web-ghc docs vmCompileTests; }; - }; -in -{ } diff --git a/notes/playground/README.md b/notes/playground/README.md deleted file mode 100644 index 71c223caed..0000000000 --- a/notes/playground/README.md +++ /dev/null @@ -1,117 +0,0 @@ -# Plutus Playgrounds - -*Plutus Playgrounds* is a lightweight, easy-to-use, web-based environment for exploratory Plutus development. It facilitates the development and execution of Plutus contracts without the overhead of installing and maintaining a full development environment and blockchain testnet. Nevertheless, it is built around the original Plutus platform components, including the use of Plutus Core for on-chain contract code, and supports the full Plutus language. Hence, contracts developed with Plutus Playgrounds can eventually be deployed to the Cardano blockchain. - -The current version of this document sets out the minimal expectations for the v1.0 launch in addition with clearly labelled optional (nice to have, but not critical) functionality for v1.0. - - -## User Interface - -The user interface has three main panes: (1) the *editor pane,* (2) the *wallet pane,* and (3) the *transactions pane.* - -### Editor pane - -The editor pane comprises an (1) editor component with syntax highlighting for Haskell, (2) a button to submit code for type checking and compilation, and (3) a feedback console textbox with error messages and similar. If the editor component is sufficiently powerful, an optional feature is to highlight error locations in the source code. In this case, clicking on or hovering over an error should bring up the detailed error message. - -Code is type checked and compiled when the corresponding button is clicked. Optionally, the edit component should submit code for type checking (only) whenever the user stops interacting with the editor pane for 0.5-1s after having made a change to the source code. - -Optionally, this component should support editing multiple source files by having a listbox (or similar control) to switch between different Haskell sources for editing. - -### Wallet pane - -The wallet pane has two major parts: (1) a list of wallets with funds and including controls to trigger contract endpoints (i.e., wallet endpoint functions) and (2) a list of the current sequence of wallet events that the user wants to submit for execution. The list of wallets contains at least one and at most 10 wallets. It is accompanied by a "+' button to add additional wallets (greyed out once 10 wallets are displayed). Moreover, the wallet pane contains a "Replay Events" button. It triggers execution of the event sequence, generating transactions in the process. - -Each wallet includes the following components: - -* **Wallet name:** a string that can be edited by the user; -* **Wallet funds:** amount in ADA that can be edited by the user (this is the amount at genesis; i.e., start of the emulation); and -* **Contract endpoints:** These are zero to ten labelled buttons. The labels in all wallets are the same and they are the function names of the contract endpoints defined in the current contract. - -The list of current wallet events is an unbound, possibly empty list of sequentially linked events. Each event includes the following components: - -* **Event name:** the name of the contract endpoint associated with this event; -* **Wallet name:** the wallet that this event originated from; -* **Close button:** clicking this button deletes the corresponding event from the list; and -* **Event arguments:** zero to ten key-value pairs. The keys are just string labels, but the values may be structured. The minimal requirement is that the values are multiline strings. Optionally, we render them either as a string or a nested list of key-value pairs (depending on the type of the corresponding argument of the contract endpoint). - -When the user clicks a contract endpoint button in a wallet, a corresponding event is appended to the sequence of wallet events. The wallet name is set to the wallet whose button was clicked. The event arguments are initialised to default empty arguments, where appropriate. - -Optionally, the individual events in the sequence of wallet events can be reordered by dragging them around. - -The wallet pane is only active after the current contract has been compiled successfully. In fact, only in this case is the correct set of wallet endpoints known. Execution of the event sequence may fail when one or more arguments to one or more events is not a legitimate value of the corresponding type of contract endpoint function. In this case, each event with malformed argument(s) ought to be tinted red, while all malformed argument(s) are highlighted. - -### Transactions pane - -The transactions pane has three major parts. - -1. A visual representation of the transactions in the form of the UTxO graph. The UTxO graph consists of (a) nodes that represent individual (valid) transactions, (b) edges between nodes that represent (valid) input-output connections, and (c) unmatched outgoing edges that represent unspent transaction outputs. -2. The final assignment of funds to wallets. This may be a subsets of the overall funds, because some funds may be locked by scripts. Optionally, the wallets should be colour coded and edges paying funds to those wallets should use the same colour. Moreover, we may display the wallet funds as coloured bars whose relative length represents their relative (final) value. -3. A possibly empty list of *invalid* transactions, each of which indicates the reason for why it is invalid. - -Optionally, provide introspection facilities for valid and invalid transactions and graph edges. In particular, to query information that helps with debugging and also includes rejected, invalid transactions and failed script execution. Moreover, show the points in the graph, where a blockchain trigger was activated for a wallet. - - -## Protocol between the frontend and backend - -We are using a stateless architecture. Hence, the entire frontend state (that affects contract execution) needs to be transmitted to the backend on each request. Central is the contract source code and the current sequence of *wallet events*. A wallet event comprises the name of a *wallet endpoint function* and a list of arguments matching the type of the wallet endpoint function. Wallet endpoint functions are those designated functions within a contract that can be invoked by the user of a wallet that has loaded the contract. - -### Frontend state required for contract execution - -1. The contents of all Plutus source modules. (Initially, this is one module; optionally, we will extend it to a list of modules.) -2. List of initial amount of ADA in each wallet. (The length of this list determines the number of wallets.) -3. List of wallet events. - -### Wallet events - -The wallet events are invocations of wallet endpoint functions (aka *contract endpoints*), where the wallet user provides arguments to the endpoint function. The user does so within the frontend UI, which requires a limit on the number and form of those arguments. We support the following types as arguments types for wallet endpoint functions: - -* `String`, -* `PubKey`, -* integral types, and -* products of the above. - -Products can be in the form of record datatypes with a single constructor. Wallet endpoint functions can, at most, have ten arguments. - -Optionally, support for arguments of any type covered by the `Generic` class. While the type class allows us to (de)serialise those values, we need a representation that can be entered by the user. One option would be to have special UI support for the types listed above and for everything else, the user needs to enter the corresponding JSON (as a power user feature). - -### Backend response to a request for type checking and compilation - -If the provided contract modules fail to compile, the backend provides the raised error messages. If the provided contract modules do compile, the backend provides a list of all contract endpoints together with a specification of the argument types required by each of them. - -### Backend response to a request to replay the event sequence - -If one or more events are invalid (because one of the provided endpoint function arguments cannot be deserialised to the expected type), the backend provides a list of errors. If all events are valid, the backend provides (a) the final UTxO graph, (b) the final funds in each wallet (as a list of ADA values in the same order as the wallets in the request), and (c) a possibly empty set of invalid transactions. - -### Representation of the UTxO graph - -TBD - -### Representation of invalid transactions - -TBD - - -## Contracts - -Every contract includes a module `Contract` that exports a main `contract` function. The `contract` function uses - -``` -registerEndpoint :: EndpointFunction fn => fn -> ContractInit () -``` - -to register all contract endpoint functions provided by this contract. Moreover, it uses - -``` -TBD event registration functions -``` - -to register the initial set of blockchain events that the contract reacts to. - - -## Open questions - -* We may want to require the use of `SafeHaskell` for all contract code: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/safe_haskell.html -* How is the UTxO graph communicated to the frontend? And what information is provided? -* What information is provided for the set of invalid transactions? -* Do we want to use annotations to register contract endpoints? -* List all event registration functions. diff --git a/playground-common/ARCHITECTURE.adoc b/playground-common/ARCHITECTURE.adoc deleted file mode 100644 index edf4426bef..0000000000 --- a/playground-common/ARCHITECTURE.adoc +++ /dev/null @@ -1,4 +0,0 @@ -=== `playground-common` - -This package contains some library code which is shared between the Plutus and -Marlowe Playgrounds. \ No newline at end of file diff --git a/playground-common/playground-common.cabal b/playground-common/playground-common.cabal index 7deb7b47d4..23e1cd0b8c 100644 --- a/playground-common/playground-common.cabal +++ b/playground-common/playground-common.cabal @@ -15,13 +15,11 @@ library exposed-modules: Auth Auth.Types - Control.Monad.Except.Extras Control.Monad.Now Control.Monad.Trace Control.Monad.Web Gist Language.Haskell.Interpreter - Playground.API Playground.Contract Playground.Interpreter.Util Playground.Schema @@ -30,8 +28,6 @@ library PSGenerator.Common Schema Servant.Extra - Servant.Prometheus - System.IO.Extras hs-source-dirs: src default-language: Haskell2010 @@ -68,7 +64,7 @@ library build-depends: aeson , aeson-casing - , base >=4.7 && <5 + , base >=4.7 && <5 , bytestring , containers , cookie @@ -78,7 +74,6 @@ library , exceptions , foldl , freer-simple - , hashable , http-client , http-client-tls , http-conduit @@ -91,15 +86,13 @@ library , openapi3 , prettyprinter , process - , prometheus >=2 , purescript-bridge - , recursion-schemes <5.2 + , recursion-schemes <5.2 , row-types - , servant >=0.16 + , servant >=0.16 , servant-client , servant-purescript , servant-server - , servant-websockets , streaming , template-haskell , text @@ -107,9 +100,7 @@ library , time-out , time-units , transformers - , unordered-containers , uuid - , wai test-suite playground-common-test type: exitcode-stdio-1.0 @@ -117,9 +108,7 @@ test-suite playground-common-test hs-source-dirs: test other-modules: Auth.TypesSpec - Language.Haskell.InterpreterSpec Paths_playground_common - Playground.THSpec Playground.TypesSpec SchemaSpec @@ -146,7 +135,6 @@ test-suite playground-common-test aeson , base >=4.7 && <5 , bytestring - , freer-simple , recursion-schemes <5.2 , tasty , tasty-hunit diff --git a/playground-common/src/Control/Monad/Except/Extras.hs b/playground-common/src/Control/Monad/Except/Extras.hs deleted file mode 100644 index 2aec67a97f..0000000000 --- a/playground-common/src/Control/Monad/Except/Extras.hs +++ /dev/null @@ -1,11 +0,0 @@ -module Control.Monad.Except.Extras where - -import Control.Monad.Error.Class (MonadError, throwError) -import Control.Monad.Except (ExceptT, runExceptT) - -mapError :: (MonadError f m) => (e -> f) -> ExceptT e m a -> m a -mapError f action = do - result <- runExceptT action - case result of - Left e -> throwError (f e) - Right v -> pure v diff --git a/playground-common/src/Playground/API.hs b/playground-common/src/Playground/API.hs deleted file mode 100644 index 1a66a63eeb..0000000000 --- a/playground-common/src/Playground/API.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE TypeOperators #-} - -module Playground.API - ( API - ) where - -import Language.Haskell.Interpreter (InterpreterResult, SourceCode) -import Language.Haskell.Interpreter qualified as HI -import Playground.Types (CompilationResult, Evaluation, EvaluationResult, PlaygroundError) -import Servant.API (Get, JSON, Post, ReqBody, (:<|>), (:>)) - -type API - = "contract" :> ReqBody '[ JSON] SourceCode :> Post '[ JSON] (Either HI.InterpreterError (InterpreterResult CompilationResult)) - :<|> "evaluate" :> ReqBody '[ JSON] Evaluation :> Post '[ JSON] (Either PlaygroundError EvaluationResult) - :<|> "health" :> Get '[ JSON] () diff --git a/playground-common/src/Servant/Prometheus.hs b/playground-common/src/Servant/Prometheus.hs deleted file mode 100644 index b728227e1e..0000000000 --- a/playground-common/src/Servant/Prometheus.hs +++ /dev/null @@ -1,276 +0,0 @@ -{-# LANGUAGE CPP #-} -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeOperators #-} -{-# OPTIONS_GHC -fno-warn-orphans #-} - -module Servant.Prometheus ( - HasEndpoint(..), - APIEndpoint(..), - monitorEndpoints -) where - -import Control.Exception (bracket, bracket_) -import Control.Monad (mplus) -import Control.Monad.IO.Class (MonadIO) -import Control.Monad.Logger (MonadLogger, MonadLoggerIO) -import Data.HashMap.Strict qualified as H -import Data.Hashable (Hashable) -import Data.Kind (Type) -import Data.Proxy (Proxy (Proxy)) -import Data.Text (Text) -import Data.Text qualified as T -import Data.Text.Encoding qualified as T -import Data.Time.Clock (diffUTCTime, getCurrentTime) -import GHC.Generics (Generic) -import GHC.TypeLits (KnownSymbol, Symbol, symbolVal) -import Network.HTTP.Types (Method, Status (Status, statusCode)) -import Network.Wai (Middleware, Request, pathInfo, requestMethod, responseStatus) -import Servant.API (BasicAuth, Capture', CaptureAll, Description, EmptyAPI, Header', HttpVersion, IsSecure, QueryFlag, - QueryParam', QueryParams, Raw, ReflectMethod, RemoteHost, ReqBody', Stream, Summary, Vault, Verb, - WithNamedContext, reflectMethod, (:<|>), (:>)) -#if MIN_VERSION_servant(0,15,0) -import Servant.API (StreamBody') -#endif -import Servant.API.BrowserHeader (BrowserHeader) -import Servant.API.WebSocket (WebSocket, WebSocketPending) -import System.Metrics.Prometheus.Concurrent.RegistryT (RegistryT, registerCounter, registerGauge, registerHistogram) -import System.Metrics.Prometheus.Metric.Counter qualified as Counter -import System.Metrics.Prometheus.Metric.Gauge qualified as Gauge -import System.Metrics.Prometheus.Metric.Histogram qualified as Histogram -import System.Metrics.Prometheus.MetricId qualified as MetricId - -instance MonadLogger m => MonadLogger (RegistryT m) -instance MonadLoggerIO m => MonadLoggerIO (RegistryT m) - -data APIEndpoint = APIEndpoint { - pathSegments :: [Text], - method :: Method -} deriving (Eq, Hashable, Show, Generic) - -data Meters = Meters - { metersInflight :: Gauge.Gauge - , metersC2XX :: Counter.Counter - , metersC4XX :: Counter.Counter - , metersC5XX :: Counter.Counter - , metersCXXX :: Counter.Counter - , metersTime :: Histogram.Histogram - } - -gaugeInflight :: Gauge.Gauge -> Middleware -gaugeInflight inflight application request respond = - bracket_ (Gauge.inc inflight) - (Gauge.dec inflight) - (application request respond) - --- | Count responses with 2XX, 4XX, 5XX, and XXX response codes. -countResponseCodes - :: (Counter.Counter, Counter.Counter, Counter.Counter, Counter.Counter) - -> Middleware -countResponseCodes (c2XX, c4XX, c5XX, cXXX) application request respond = - application request respond' - where - respond' res = count (responseStatus res) >> respond res - count Status{statusCode = sc } - | 200 <= sc && sc < 300 = Counter.inc c2XX - | 400 <= sc && sc < 500 = Counter.inc c4XX - | 500 <= sc && sc < 600 = Counter.inc c5XX - | otherwise = Counter.inc cXXX - -responseTimeHistogram :: Histogram.Histogram -> Middleware -responseTimeHistogram hist application request respond = - bracket getCurrentTime stop $ const $ application request respond - where - stop t1 = do - t2 <- getCurrentTime - let dt = diffUTCTime t2 t1 - Histogram.observe (fromRational $ (*1000) $ toRational dt) hist - -initializeMeters :: MonadIO m => APIEndpoint -> RegistryT m Meters -initializeMeters APIEndpoint{..} = do - metersInflight <- registerGauge (prefix <> "in_flight") mempty - metersC2XX <- registerCounter (prefix <> "responses_2XX") mempty - metersC4XX <- registerCounter (prefix <> "responses_4XX") mempty - metersC5XX <- registerCounter (prefix <> "responses_5XX") mempty - metersCXXX <- registerCounter (prefix <> "responses_XXX") mempty - metersTime <- registerHistogram (prefix <> "time_ms") mempty [10,20..100] - pure Meters{..} - where - prefix = MetricId.Name . T.toLower $ "servant_path_" <> path <> "_" - path = T.intercalate "_" $ pathSegments <> [T.decodeUtf8 method] - -initializeMetersTable :: MonadIO m => [APIEndpoint] -> RegistryT m (H.HashMap APIEndpoint Meters) -initializeMetersTable endpoints = do - meters <- mapM initializeMeters endpoints - pure $ H.fromList (zip endpoints meters) - -monitorEndpoints :: - (MonadIO m, HasEndpoint api) => Proxy api -> RegistryT m Middleware -monitorEndpoints proxy = do - meters <- initializeMetersTable (enumerateEndpoints proxy) - return (monitorEndpointsWith meters) - where - monitorEndpointsWith :: H.HashMap APIEndpoint Meters -> Middleware - monitorEndpointsWith meters application request respond = - case getEndpoint proxy request >>= \ep -> H.lookup ep meters of - Nothing -> application request respond - Just endpointMeter -> - updateCounters endpointMeter application request respond - where - updateCounters Meters {..} = - responseTimeHistogram metersTime . - countResponseCodes (metersC2XX, metersC4XX, metersC5XX, metersCXXX) . - gaugeInflight metersInflight - - -class HasEndpoint a where - getEndpoint :: Proxy a -> Request -> Maybe APIEndpoint - enumerateEndpoints :: Proxy a -> [APIEndpoint] - -instance HasEndpoint EmptyAPI where - getEndpoint _ _ = Nothing - enumerateEndpoints _ = [] - -instance (HasEndpoint (a :: Type), HasEndpoint (b :: Type)) => HasEndpoint (a :<|> b) where - getEndpoint _ req = - getEndpoint (Proxy :: Proxy a) req - `mplus` getEndpoint (Proxy :: Proxy b) req - - enumerateEndpoints _ = - enumerateEndpoints (Proxy :: Proxy a) - <> enumerateEndpoints (Proxy :: Proxy b) - -instance (KnownSymbol (path :: Symbol), HasEndpoint (sub :: Type)) - => HasEndpoint (path :> sub) where - getEndpoint _ req = - case pathInfo req of - p:ps | p == T.pack (symbolVal (Proxy :: Proxy path)) -> do - APIEndpoint{..} <- getEndpoint (Proxy :: Proxy sub) req{ pathInfo = ps } - return (APIEndpoint (p:pathSegments) method) - _ -> Nothing - - enumerateEndpoints _ = - let endpoints = enumerateEndpoints (Proxy :: Proxy sub) - currentSegment = T.pack $ symbolVal (Proxy :: Proxy path) - qualify APIEndpoint{..} = APIEndpoint (currentSegment : pathSegments) method - in - map qualify endpoints - -instance (KnownSymbol (capture :: Symbol), HasEndpoint (sub :: Type)) - => HasEndpoint (Capture' mods capture a :> sub) where - getEndpoint _ req = - case pathInfo req of - _:ps -> do - APIEndpoint{..} <- getEndpoint (Proxy :: Proxy sub) req{ pathInfo = ps } - let p = T.pack $ (':':) $ symbolVal (Proxy :: Proxy capture) - return (APIEndpoint (p:pathSegments) method) - _ -> Nothing - enumerateEndpoints _ = - let endpoints = enumerateEndpoints (Proxy :: Proxy sub) - currentSegment = T.pack $ (':':) $ symbolVal (Proxy :: Proxy capture) - qualify APIEndpoint{..} = APIEndpoint (currentSegment : pathSegments) method - in - map qualify endpoints - -instance HasEndpoint (sub :: Type) => HasEndpoint (Summary d :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (Description d :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (Header' mods h a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (QueryParam' mods (h :: Symbol) a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (QueryParams (h :: Symbol) a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (QueryFlag h :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (ReqBody' mods cts a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -#if MIN_VERSION_servant(0,15,0) -instance HasEndpoint (sub :: Type) => HasEndpoint (StreamBody' mods framing ct a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) -#endif - -instance HasEndpoint (sub :: Type) => HasEndpoint (RemoteHost :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (IsSecure :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (HttpVersion :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (Vault :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (WithNamedContext x y sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance ReflectMethod method => HasEndpoint (Verb method status cts a) where - getEndpoint _ req = case pathInfo req of - [] | requestMethod req == method -> Just (APIEndpoint [] method) - _ -> Nothing - where method = reflectMethod (Proxy :: Proxy method) - - enumerateEndpoints _ = [APIEndpoint mempty method] - where method = reflectMethod (Proxy :: Proxy method) - -instance ReflectMethod method => HasEndpoint (Stream method status framing ct a) where - getEndpoint _ req = case pathInfo req of - [] | requestMethod req == method -> Just (APIEndpoint [] method) - _ -> Nothing - where method = reflectMethod (Proxy :: Proxy method) - - enumerateEndpoints _ = [APIEndpoint mempty method] - where method = reflectMethod (Proxy :: Proxy method) - -instance HasEndpoint Raw where - getEndpoint _ _ = Just (APIEndpoint [] "RAW") - enumerateEndpoints _ = [APIEndpoint [] "RAW"] - -instance HasEndpoint WebSocketPending where - getEndpoint _ _ = Just (APIEndpoint [] "Websocket") - enumerateEndpoints _ = [APIEndpoint [] "Websocket"] - -instance HasEndpoint WebSocket where - getEndpoint _ _ = Just (APIEndpoint [] "Websocket") - enumerateEndpoints _ = [APIEndpoint [] "Websocket"] - -instance HasEndpoint (sub :: Type) => HasEndpoint (CaptureAll (h :: Symbol) a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (sub :: Type) => HasEndpoint (BasicAuth (realm :: Symbol) a :> sub) where - getEndpoint _ = getEndpoint (Proxy :: Proxy sub) - enumerateEndpoints _ = enumerateEndpoints (Proxy :: Proxy sub) - -instance HasEndpoint (BrowserHeader "Cookie" Text :> a) where - getEndpoint _ _ = Nothing - enumerateEndpoints _ = [] diff --git a/playground-common/src/System/IO/Extras.hs b/playground-common/src/System/IO/Extras.hs deleted file mode 100644 index 5a9366be72..0000000000 --- a/playground-common/src/System/IO/Extras.hs +++ /dev/null @@ -1,21 +0,0 @@ -module System.IO.Extras where - -import Control.Monad.Catch (MonadMask, bracket) -import Control.Monad.IO.Class (MonadIO, liftIO) -import System.IO (Handle, IOMode, hClose, openFile) - --- withFile is a clone of System.IO.withFile however it is generalized over the monad --- This might be done using unliftio I think however it looked to be more pain that --- it was worth so I simply copied and pasted the definitions and changed the types. -withFile - :: (MonadMask m, MonadIO m) - => FilePath - -> IOMode - -> (Handle -> m a) - -> m a -withFile path mode = - bracket - (liftIO $ openFile path mode) - (\handle -> - liftIO (hClose handle) - ) diff --git a/playground-common/test/Language/Haskell/InterpreterSpec.hs b/playground-common/test/Language/Haskell/InterpreterSpec.hs deleted file mode 100644 index 3780044027..0000000000 --- a/playground-common/test/Language/Haskell/InterpreterSpec.hs +++ /dev/null @@ -1,58 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} - -module Language.Haskell.InterpreterSpec - ( tests - ) where - -import Language.Haskell.Interpreter (CompilationError (CompilationError, RawError), column, filename, parseErrorText, - row, text) -import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (assertEqual, testCase) - -tests :: TestTree -tests = testGroup "Language.Haskell.InterpreterSpec" [parseErrorTextSpec] - -parseErrorTextSpec :: TestTree -parseErrorTextSpec = - testGroup - "parseErrorText" - [ testCase "shouldn't be able to parse an empty string." $ - assertEqual "" (parseErrorText "") (RawError "") - , testCase "should handle a basic error" $ - assertEqual - "" - (parseErrorText - "Contract4205-5.hs:13:6: error: parse error on input \8216..\8217") - (CompilationError - { filename = "Contract4205-5.hs" - , row = 13 - , column = 6 - , text = [" error: parse error on input \8216..\8217"] - }) - , testCase "should handle multiline errors" $ - assertEqual - "" - (parseErrorText - "Main70317-3.hs:76:14: error:\n \8226 Could not deduce (MonadError WalletAPIError m0)\n from the context: (MonadError WalletAPIError m, WalletAPI m)\n bound by the type signature for:\n vestFunds :: forall (m :: * -> *).\n (MonadError WalletAPIError m, WalletAPI m) =>\n Vesting -> Value -> IO ()\n at Main70317-3.hs:(76,14)-(81,12)\n The type variable \8216m0\8217 is ambiguous\n \8226 In the ambiguity check for \8216vestFunds\8217\n To defer the ambiguity check to use sites, enable AllowAmbiguousTypes\n In the type signature:\n vestFunds :: (MonadError WalletAPIError m, WalletAPI m) =>\n Vesting -> Value -> IO ()") - (CompilationError - { filename = "Main70317-3.hs" - , row = 76 - , column = 14 - , text = - [ " error:" - , " \8226 Could not deduce (MonadError WalletAPIError m0)" - , " from the context: (MonadError WalletAPIError m, WalletAPI m)" - , " bound by the type signature for:" - , " vestFunds :: forall (m :: * -> *)." - , " (MonadError WalletAPIError m, WalletAPI m) =>" - , " Vesting -> Value -> IO ()" - , " at Main70317-3.hs:(76,14)-(81,12)" - , " The type variable \8216m0\8217 is ambiguous" - , " \8226 In the ambiguity check for \8216vestFunds\8217" - , " To defer the ambiguity check to use sites, enable AllowAmbiguousTypes" - , " In the type signature:" - , " vestFunds :: (MonadError WalletAPIError m, WalletAPI m) =>" - , " Vesting -> Value -> IO ()" - ] - }) - ] diff --git a/playground-common/test/Playground/THSpec.hs b/playground-common/test/Playground/THSpec.hs deleted file mode 100644 index 2d256d7023..0000000000 --- a/playground-common/test/Playground/THSpec.hs +++ /dev/null @@ -1,87 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE MonoLocalBinds #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# OPTIONS_GHC -fno-warn-missing-signatures #-} -{-# OPTIONS_GHC -fno-warn-unused-top-binds #-} -{-# OPTIONS_GHC -fno-warn-redundant-constraints #-} - -module Playground.THSpec - ( tests - ) where - -import Control.Monad.Freer (Eff, Member) -import Data.Text (Text) -import Ledger.Value (Value) -import Playground.TH (mkFunctions, mkSingleFunction) -import Playground.Types (FunctionSchema (FunctionSchema)) -import Schema (FormSchema (FormSchemaArray, FormSchemaInt, FormSchemaString, FormSchemaTuple, FormSchemaValue)) -import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (assertEqual, testCase) -import Wallet.Effects (WalletEffect) -import Wallet.Types (EndpointDescription (EndpointDescription)) - --- f1..fn are functions that we should be able to generate schemas --- for, using `mkFunction`. The schemas will be called f1Schema etc. -f0 :: Member WalletEffect effs => Eff effs () -f0 = pure () - -f1 :: Member WalletEffect effs => Eff effs () -f1 = pure () - -f2 :: Member WalletEffect effs => String -> Eff effs () -f2 _ = pure () - -f3 :: Member WalletEffect effs => String -> Value -> Eff effs () -f3 _ _ = pure () - -f4 :: Member WalletEffect effs - => Text - -> Text - -> (Int, Int) - -> [Text] - -> Eff effs () -f4 _ _ _ _ = pure () - -$(mkSingleFunction 'f0) - -$(mkFunctions ['f1, 'f2, 'f3, 'f4]) - -tests :: TestTree -tests = - testGroup - "TH" - [ testCase "Schemas compile as expected" $ do - assertEqual - "f0" - f0Schema - (FunctionSchema (EndpointDescription "f0") [] :: FunctionSchema [FormSchema]) - assertEqual - "f1" - f1Schema - (FunctionSchema (EndpointDescription "f1") [] :: FunctionSchema [FormSchema]) - assertEqual - "f2" - f2Schema - (FunctionSchema (EndpointDescription "f2") [FormSchemaString] :: FunctionSchema [FormSchema]) - assertEqual - "f3" - f3Schema - (FunctionSchema - (EndpointDescription "f3") - [FormSchemaString, FormSchemaValue] :: FunctionSchema [FormSchema]) - assertEqual - "f4" - f4Schema - (FunctionSchema - (EndpointDescription "f4") - [ FormSchemaString - , FormSchemaString - , FormSchemaTuple FormSchemaInt FormSchemaInt - , FormSchemaArray FormSchemaString - ] :: FunctionSchema [FormSchema]) - ] diff --git a/playground-common/test/Spec.hs b/playground-common/test/Spec.hs index de47585c78..c6fbc6230f 100644 --- a/playground-common/test/Spec.hs +++ b/playground-common/test/Spec.hs @@ -3,7 +3,6 @@ module Main ) where import Auth.TypesSpec qualified -import Playground.THSpec qualified import Playground.TypesSpec qualified import SchemaSpec qualified import Test.Tasty (defaultMain, testGroup) @@ -15,6 +14,5 @@ main = "all tests" [ Auth.TypesSpec.tests , SchemaSpec.tests - , Playground.THSpec.tests , Playground.TypesSpec.tests ] diff --git a/plutus-contract/ARCHITECTURE.adoc b/plutus-contract/ARCHITECTURE.adoc index 00970f6aa5..ab09031d95 100644 --- a/plutus-contract/ARCHITECTURE.adoc +++ b/plutus-contract/ARCHITECTURE.adoc @@ -12,5 +12,4 @@ Noteworthy modules: * `Contract.Trace`: The `ContractTrace` type for describing sequences of emulator actions that can be used in the Playgound and in unit tests. * `Contract.App`: Exposes a wrapper to turn `Contract` values into standalone executables, to be consumed by the SCB -It also defines the chain emulator, which is used for tests, and to back -the simulations in the Plutus Playground. +It also defines the chain emulator, which is used for tests. diff --git a/plutus-pab/plutus-pab.cabal b/plutus-pab/plutus-pab.cabal index e6006b30dd..326f9f991c 100644 --- a/plutus-pab/plutus-pab.cabal +++ b/plutus-pab/plutus-pab.cabal @@ -144,8 +144,6 @@ library , cardano-addresses , cardano-api >=1.35 , cardano-ledger-alonzo - , cardano-ledger-core - , cardano-ledger-shelley , cardano-slotting , cardano-wallet , cardano-wallet-cli @@ -215,7 +213,6 @@ library , time , time-units , transformers - , unordered-containers , uuid , wai , wai-cors diff --git a/plutus-playground-client/ARCHITECTURE.adoc b/plutus-playground-client/ARCHITECTURE.adoc deleted file mode 100644 index 30603f8c2a..0000000000 --- a/plutus-playground-client/ARCHITECTURE.adoc +++ /dev/null @@ -1,3 +0,0 @@ -=== `plutus-playground-client` - -The Plutus Playground client code, written in Purescript. \ No newline at end of file diff --git a/plutus-playground-client/README.md b/plutus-playground-client/README.md deleted file mode 100644 index e2110e878e..0000000000 --- a/plutus-playground-client/README.md +++ /dev/null @@ -1,114 +0,0 @@ -The Plutus Playground is an online IDE that enables users to easily write and -simulate Plutus Applications. - -## Getting started - -The Plutus Playground is written in [PureScript](https://www.purescript.org/) and uses npm and [spago](https://github.com/purescript/spago) for managing dependencies. It talks to the [plutus-playground-server](https://github.com/input-output-hk/plutus-apps/tree/master/plutus-playground-server) which also needs to be up and running during development. The client build also depends on purescript files that are generated by the backend service using [purescript-bridge](https://github.com/eskimor/purescript-bridge). - -**Note**: _The workflow described here relies heavily on Nix. This means you should either be working inside a nix-shell environment or use tools such as [lorri](https://github.com/target/lorri) or [nix-direnv](https://github.com/nix-community/nix-direnv) or similar to provide a suitable environment._ - -### Starting the backend server - -```bash -$ plutus-playground-server -``` - -The `plutus-playground-server` script is provided by the global [shell.nix](../shell.nix) and starts the server (If the command is not available, make sure you are in a nix-shell session or that lorri is ready). For additional information on invoking the backend server, please refer to its [README.md](https://github.com/input-output-hk/plutus-apps/tree/main/plutus-playground-server). - -### Starting the frontend server - -With the backend server running you can get started using the `npm start` script: - -```bash -$ npm run start -``` - -The `start` script will: - -- Install npm dependencies -- Generate purescript bridge code -- Compile the purescript code -- Start the webkpack server - -Once the `start` script completes you can access the frontend via [https://localhost:8009](https://localhost:8009) - -> **Note**: You may need to adjust `webpack.config.js` to serve non-SSL content; set -> `module.exports.devServer.https` to `false`. - -## Development Workflow - -The following outlines some essentials for actually working on the plutus playground code. - -### NPM Scripts - -Apart from the `start` script introduced above there are a couple of scripts for the most frequent tasks during development. In order to run a webpack server in development mode with automatic reloading use **webpack:server**: - -``` -$ npm run build:webpack:dev -``` - -Please refer to [package.json](./package.json) for the full set of provided scripts. - -### Generating PureScript Code - -The PureScript build depends on the presence of a `./generated` folder with bridge code generated by the backend. The folder is generated the first time you run `plutus-playground-server`, and can be re-generated on demand by passing a `-g` flag like so: `plutus-playground-server -g`. - -### Managing Dependencies - -There are two relevant sources of dependencies that have to be handled and integrated with Nix separately: _Javascript(/npm)_ dependencies and _PureScript_ dependencies. - -#### Managing NPM Dependencies - -The Javascript dependencies are handled by npm in [package.json](./package.json) (and [package-lock.json](./package-lock.json) which -is updated by npm automatically). - -The npm dependencies are integrated with Nix via [npmlock2nix](https://github.com/tweag/npmlock2nix) almost completely transparently. Any changes to the lockfile will be picked up npmlock2nix automatically during the nix build. No -additional files have to be generated or maintained. - -##### NodeJS GitHub dependencies - -In general, npm dependencies are handled by npmlock2nix automatically and transparently. The one exception to this rule are -GitHub dependencies. In order for these to work in restricted evaluation mode (which is what hydra uses) you have to specify -the sha256 of the dependency you want to use in your `buildNodeModules`. For example: - -``` -buildNodeModules { - projectDir = ./.; - packageJson = ./package.json; - packageLockJson = ./package-lock.json; - githubSourceHashMap = { - shmish111.nearley-webpack-loader."939360f9d1bafa9019b6ff8739495c6c9101c4a1" = "1brx669dgsryakf7my00m25xdv7a02snbwzhzgc9ylmys4p8c10x"; - }; -} -``` - -You can add new dependencies with the sha256 set to `"0000000000000000000000000000000000000000000000000000"`. This will yield an error -message during the build with the actual hash value. - -#### Managing PureScript Dependencies - -The PureScript dependencies are handled by [spago](https://github.com/purescript/spago) in [packages.dhall](./packages.dhall). - -The Nix integration is done using [spago2nix](https://github.com/justinwoo/spago2nix). Any changes to the PureScript dependencies -require an update of the Nix code generated by spago2nix: - -``` -$ spago2nix generate -``` - -This will parse the spago configuration and will generate an updated `.nix` file. - -**Note**: If the `spago2nix` command is not available make sure you are inside a nix-shell environment or that your lorri session -is up and running. - - -### Nix - -#### Building The Client With Nix - -You can run the following command (from the repository root) to build the client and the -backend server with Nix: - -```sh -$ nix-build -A plutus-playground.client -A plutus-playground.server -``` diff --git a/plutus-playground-client/default.nix b/plutus-playground-client/default.nix deleted file mode 100644 index 8a48a15473..0000000000 --- a/plutus-playground-client/default.nix +++ /dev/null @@ -1,123 +0,0 @@ -{ purs-tidy, pkgs, lib, gitignore-nix, haskell, webCommon, buildPursPackage, buildNodeModules, filterNpm }: -let - playground-exe = haskell.packages.plutus-playground-server.components.exes.plutus-playground-server; - - ghc-with-plutus = haskell.project.ghcWithPackages (ps: [ ps.plutus-core ps.plutus-tx ps.plutus-contract ps.plutus-ledger ps.playground-common ]); - - # We need these because we are not allowed to reference plutus-ledger inside - # the nix shell. - build-ghc-with-plutus = "$(nix-build --no-build-output -E '(import ./default.nix {}).plutus-apps.haskell.project.ghcWithPackages(ps: [ ps.plutus-core ps.plutus-tx ps.plutus-contract ps.plutus-ledger ps.playground-common ])')"; - - build-playground-exe = "$(nix-build default.nix -A plutus-apps.haskell.packages.plutus-playground-server.components.exes.plutus-playground-server)"; - - # generate-purescript: script to create purescript bridge code - # - # Note: We need to add ghc to the path because the purescript generator - # actually invokes ghc to generate test data so we need ghc with the necessary deps - generate-purescript = pkgs.writeShellApplication { - name = "plutus-playground-generate-purs"; - runtimeInputs = [ pkgs.nix ]; - text = '' - if [ "$#" -ne 1 ]; then - echo usage: plutus-playground-generate-purs GENERATED_DIR - exit 1 - fi - - generatedDir="$1" - rm -rf "$generatedDir" - - GHC_WITH_PKGS="${build-ghc-with-plutus}" - export PATH=$GHC_WITH_PKGS/bin:$PATH - - echo Generating purescript files in "$generatedDir" - "${build-playground-exe}"/bin/plutus-playground-server psgenerator "$generatedDir" - echo Done generating purescript files - echo - echo Formatting purescript files in "$generatedDir" - ${purs-tidy}/bin/purs-tidy format-in-place "$generatedDir" - echo Done formatting purescript files - ''; - }; - - purescript-generated = pkgs.stdenv.mkDerivation { - name = "purescript-generated"; - phases = [ "installPhase" ]; - installPhase = '' - mkdir -p $out - GHC_WITH_PKGS="${ghc-with-plutus}" - export PATH=$GHC_WITH_PKGS/bin:$PATH - "${playground-exe}"/bin/plutus-playground-server psgenerator "$out" - ''; - }; - - # start-backend: script to start the plutus-playground-server - # - # Note: We need to add ghc to the path because the server provides /runghc - # which needs ghc and dependencies. - start-backend = pkgs.writeShellScriptBin "plutus-playground-server" '' - if [ ! -d plutus-playground-client ]; then - echo Please run plutus-playground-server from the root of the repository - exit 1 - fi - - generatedDir=./plutus-playground-client/generated - - if [ ! -d "$generatedDir" ] || [ "$1" == "-g" ]; then - ${generate-purescript}/bin/plutus-playground-generate-purs "$generatedDir" - fi - - dirAge=$(datediff now "$(date -r "$generatedDir" +%F)") - echo - echo "*** Using Purescript files in $generatedDir which are $dirAge days old." - echo "*** To regenerate, run plutus-playground-server -g" - echo - echo - echo plutus-playground-server: for development use only - - GHC_WITH_PKGS="${build-ghc-with-plutus}" - export PATH=$GHC_WITH_PKGS/bin:$PATH - - export FRONTEND_URL=https://localhost:8009 - export WEBGHC_URL=http://localhost:8080 - export GITHUB_CALLBACK_PATH=https://localhost:8009/api/oauth/github/callback - - echo before "$1" - test "$1" == "-g" && shift 1 # takes care of the -g flag - echo after "$1" - "${build-playground-exe}"/bin/plutus-playground-server webserver "$@" - ''; - - # Note that this ignores the generated folder too, but it's fine since it is - # added via extraSrcs - cleanSrc = gitignore-nix.gitignoreSource ./.; - - nodeModules = buildNodeModules { - projectDir = filterNpm cleanSrc; - packageJson = ./package.json; - packageLockJson = ./package-lock.json; - }; - - client = pkgs.lib.overrideDerivation - (buildPursPackage { - inherit pkgs nodeModules; - src = cleanSrc; - extraSrcs = { - generated = purescript-generated; - }; - name = "plutus-playground-client"; - # ideally we would just use `npm run test` but - # this executes `spago` which *always* attempts to download - # remote files (which obviously fails in sandboxed builds) - checkPhase = '' - node -e 'require("./output/Test.Main").main()' - ''; - spagoPackages = pkgs.callPackage ./spago-packages.nix { }; - }) - (_: { - WEB_COMMON_SRC = webCommon.cleanSrc; - }); -in -{ - inherit client start-backend generate-purescript; - server = playground-exe; -} diff --git a/plutus-playground-client/e2e-tests/.gitignore b/plutus-playground-client/e2e-tests/.gitignore deleted file mode 100644 index 0268538fee..0000000000 --- a/plutus-playground-client/e2e-tests/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -report.json -html-report/* \ No newline at end of file diff --git a/plutus-playground-client/e2e-tests/.nvmrc b/plutus-playground-client/e2e-tests/.nvmrc deleted file mode 100644 index d72f80829e..0000000000 --- a/plutus-playground-client/e2e-tests/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -v12.12.0 diff --git a/plutus-playground-client/e2e-tests/README.md b/plutus-playground-client/e2e-tests/README.md deleted file mode 100644 index cce604a706..0000000000 --- a/plutus-playground-client/e2e-tests/README.md +++ /dev/null @@ -1,6 +0,0 @@ -## Playwright E2E Tests - -1. `nvm use` (not required for `nix-shell` users) -2. `npm i` -3. `npx playwright install` -4. `npx playwright test --headed --project=firefox --project=chromium` \ No newline at end of file diff --git a/plutus-playground-client/e2e-tests/package-lock.json b/plutus-playground-client/e2e-tests/package-lock.json deleted file mode 100644 index a41f031fdf..0000000000 --- a/plutus-playground-client/e2e-tests/package-lock.json +++ /dev/null @@ -1,1857 +0,0 @@ -{ - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", - "dev": true - }, - "@babel/core": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", - "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.16.7", - "@babel/parser": "^7.16.12", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.10", - "@babel/types": "^7.16.8", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", - "dev": true, - "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.17.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz", - "integrity": "sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz", - "integrity": "sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true - }, - "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "dev": true, - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - } - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", - "dev": true - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", - "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", - "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", - "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz", - "integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" - } - }, - "@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" - } - }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@playwright/test": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.19.1.tgz", - "integrity": "sha512-NGWqJWP4N2HFyXlOSDwQSfgmige94p9KQvml62fJ5wg4sknfkyw+CnFeLUze8qvnGlS0PbVISMRV5JOE8EdxjQ==", - "dev": true, - "requires": { - "@babel/code-frame": "7.16.7", - "@babel/core": "7.16.12", - "@babel/plugin-proposal-class-properties": "7.16.7", - "@babel/plugin-proposal-dynamic-import": "7.16.7", - "@babel/plugin-proposal-export-namespace-from": "7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7", - "@babel/plugin-proposal-numeric-separator": "7.16.7", - "@babel/plugin-proposal-optional-chaining": "7.16.7", - "@babel/plugin-proposal-private-methods": "7.16.11", - "@babel/plugin-proposal-private-property-in-object": "7.16.7", - "@babel/plugin-syntax-async-generators": "7.8.4", - "@babel/plugin-syntax-json-strings": "7.8.3", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "7.8.3", - "@babel/plugin-transform-modules-commonjs": "7.16.8", - "@babel/plugin-transform-react-jsx": "7.16.7", - "@babel/preset-typescript": "7.16.7", - "babel-plugin-module-resolver": "4.1.0", - "colors": "1.4.0", - "commander": "8.3.0", - "debug": "4.3.3", - "expect": "27.2.5", - "jest-matcher-utils": "27.2.5", - "jpeg-js": "0.4.3", - "json5": "2.2.0", - "mime": "3.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "open": "8.4.0", - "pirates": "4.0.4", - "pixelmatch": "5.2.1", - "playwright-core": "1.19.1", - "pngjs": "6.0.0", - "rimraf": "3.0.2", - "source-map-support": "0.4.18", - "stack-utils": "2.0.5", - "yazl": "2.5.1" - }, - "dependencies": { - "playwright-core": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.19.1.tgz", - "integrity": "sha512-+ByjhWX39PlINVRXr4ef9Kle85mk5QzA2WLioCoMQc3bSUtZpLV1mbeUDtRp/bvFw6YDIEyptj4QvzzRTXN3vg==", - "dev": true, - "requires": { - "commander": "8.3.0", - "debug": "4.3.3", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "jpeg-js": "0.4.3", - "mime": "3.0.0", - "pngjs": "6.0.0", - "progress": "2.0.3", - "proper-lockfile": "4.1.2", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "socks-proxy-agent": "6.1.1", - "stack-utils": "2.0.5", - "ws": "8.4.2", - "yauzl": "2.10.0", - "yazl": "2.5.1" - } - } - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/node": { - "version": "17.0.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.18.tgz", - "integrity": "sha512-eKj4f/BsN/qcculZiRSujogjvp5O/k4lOW5m35NopjZM/QwLOR075a8pJW5hD+Rtdm2DaCVPENS6KtSQnUD6BA==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-module-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz", - "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==", - "dev": true, - "requires": { - "find-babel-config": "^1.2.0", - "glob": "^7.1.6", - "pkg-up": "^3.1.0", - "reselect": "^4.0.0", - "resolve": "^1.13.1" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browserslist": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz", - "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001286", - "electron-to-chromium": "^1.4.17", - "escalade": "^3.1.1", - "node-releases": "^2.0.1", - "picocolors": "^1.0.0" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caniuse-lite": { - "version": "1.0.30001312", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz", - "integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.4.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz", - "integrity": "sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "expect": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", - "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-regex-util": "^27.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-babel-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", - "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", - "dev": true, - "requires": { - "json5": "^0.5.1", - "path-exists": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-matcher-utils": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", - "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.2.5" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", - "dev": true - }, - "pixelmatch": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", - "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", - "dev": true, - "requires": { - "pngjs": "^4.0.1" - }, - "dependencies": { - "pngjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", - "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", - "dev": true - } - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "reselect": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz", - "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==", - "dev": true - }, - "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", - "dev": true, - "requires": { - "is-core-module": "^2.8.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } - } - } -} diff --git a/plutus-playground-client/e2e-tests/package.json b/plutus-playground-client/e2e-tests/package.json deleted file mode 100644 index 95479be8ce..0000000000 --- a/plutus-playground-client/e2e-tests/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "devDependencies": { - "@playwright/test": "^1.19.1" - } -} diff --git a/plutus-playground-client/e2e-tests/playwright.config.ts b/plutus-playground-client/e2e-tests/playwright.config.ts deleted file mode 100644 index 1ebe836f67..0000000000 --- a/plutus-playground-client/e2e-tests/playwright.config.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { PlaywrightTestConfig, devices } from '@playwright/test'; - -const config: PlaywrightTestConfig = { - timeout: 60000, - expect: { - timeout: 40000, - toMatchSnapshot: { - threshold: 0.3, - }, - }, - reporter: [ - ['list'], - ['html', { open: 'never', outputFolder: 'html-report' }] - ], - forbidOnly: !!process.env.CI, - retries: process.env.CI ? 2 : 0, - workers: 1, - use: { - trace: 'on-first-retry', - ignoreHTTPSErrors: true - }, - projects: [ - { - name: 'chromium', - use: { - browserName: 'chromium', - viewport: { width: 1280, height: 720 }, - }, - }, - { - name: 'firefox', - use: { - browserName: 'firefox', - viewport: { width: 1280, height: 720 }, - } - } - ], -}; -export default config; diff --git a/plutus-playground-client/e2e-tests/src/plutus-playground/envs.json b/plutus-playground-client/e2e-tests/src/plutus-playground/envs.json deleted file mode 100644 index 98a512bc76..0000000000 --- a/plutus-playground-client/e2e-tests/src/plutus-playground/envs.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - { "name" : "staging", "url" : "https://plutus-playground-plutus-apps-staging.plutus.aws.iohkdev.io/" }, - { "name" : "production", "url" : "https://playground.plutus.iohkdev.io/" }, - { "name" : "local", "url" : "https://localhost:8009/" } -] diff --git a/plutus-playground-client/e2e-tests/src/plutus-playground/hosted_envs.json b/plutus-playground-client/e2e-tests/src/plutus-playground/hosted_envs.json deleted file mode 100644 index 4022c05d97..0000000000 --- a/plutus-playground-client/e2e-tests/src/plutus-playground/hosted_envs.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - { "name" : "staging", "url" : "https://plutus-playground-plutus-apps-staging.plutus.aws.iohkdev.io/" }, - { "name" : "production", "url" : "https://playground.plutus.iohkdev.io/" } -] diff --git a/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/editor.ts b/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/editor.ts deleted file mode 100644 index 94df9eaddd..0000000000 --- a/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/editor.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { test, expect } from '@playwright/test'; - -export class EditorPage { - readonly wonderfulText :string = 'wonderful'; - readonly notCompiledText = 'Not compiled'; - readonly compilingText = 'Compiling ...'; - readonly compilationSuccessfulText = 'Compilation successful'; - - constructor(page) { - this.page = page; - this.title = this.page.locator("text=Plutus playground"); - this.h1 = this.page.locator("h1 >> text=Editor"); - this.helloWorld = this.page.locator("a >> text=Hello, world"); - this.starter = this.page.locator("a >> text=Starter"); - this.game = this.page.locator("a >> text=Game"); - this.vesting = this.page.locator("a >> text=Vesting"); - this.crowdFunding = this.page.locator("a >> text=Crowd Funding"); - this.errorHandling = this.page.locator("a >> text=Error Handling"); - this.helloWorldInEditor = this.page.locator("//div[@class='code-editor']/descendant::span[contains(text(), 'Hello') and contains(text(), 'world')]"); // text in code editor - this.compilingInEditor = this.page.locator("//div[@class='code-editor']/descendant::span[contains(text(), 'Crowdfunding')]"); // text in code editor - this.compileBtn = this.page.locator("button >> text=Compile"); - this.simulateBtn = this.page.locator("//button >> text=Simulate"); - this.feedbackHeader = this.page.locator("//div[@class='editor-feedback-header']"); - } - - async navigate(base: string) { - await this.page.goto(base); - await expect(this.title).toHaveText('Plutus playground'); - await expect(this.h1).toHaveText('Editor'); - } - - async modifyHelloWorldText(text: string) { - await expect(this.feedbackHeader).toHaveText(this.compilationSuccessfulText); // it's already compiled becuse it's an example? - await this.helloWorldInEditor.click(); - await this.page.keyboard.type(text); - } - - async compileHelloWorld(): Promise { - const textToInsert = this.wonderfulText; - await this.helloWorld.click(); - await this.modifyHelloWorldText(textToInsert); - await expect(this.helloWorldInEditor).toBeVisible(); - await this.compile(); - return textToInsert; - } - - async compileCrowdFunding() { - await this.crowdFunding.click(); - await expect(this.compilingInEditor).toBeVisible(); - await this.compile(); - } - - async compile() { - await this.compileBtn.click(); - await expect(this.feedbackHeader).toHaveText(this.compilingText); - await expect(this.feedbackHeader).toHaveText(this.compilationSuccessfulText); - } - - async simulate() { - await this.simulateBtn.click(); - } - -} diff --git a/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/simulator.ts b/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/simulator.ts deleted file mode 100644 index d498175a50..0000000000 --- a/plutus-playground-client/e2e-tests/src/plutus-playground/pageobject/simulator.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { test, expect } from '@playwright/test'; - -export class SimulatorPage { - constructor(page) { - this.page = page; - this.walletsHeader = this.page.locator('h2 >> text=Wallets'); - this.evaluateBtn = this.page.locator('button >> text=Evaluate').first(); - this.transactionHeader = this.page.locator('h2 >> text=Transactions'); - } - - async isOpen() { - await expect(this.walletsHeader).toBeVisible(); - } - - async evaluate() { - await this.evaluateBtn.click(); - await expect(this.transactionHeader).toBeVisible(); - } - - async checkLogsContainsText(text: string, occurances: number) { - const logsTextXPath = "//div[@class='logs']//descendant::div[contains(text(),'" + text + "')]" - await expect(this.page.locator(logsTextXPath)).toHaveCount(occurances) - } - - async confirmCrowdFundingBlockchainTransactions() { - await this.confirmBlockchainTransaction(0, 0); - await this.confirmBlockchainTransaction(1, 0); - await this.confirmBlockchainTransaction(1, 1); - await this.confirmBlockchainTransaction(1, 2); - await this.confirmBlockchainTransaction(40, 0); - } - - private async confirmBlockchainTransaction(slot: number, tx: number) { - const blockchainTransactionXPath = "//div[@class='row blocks']//div[@class='card-header' and " + - "descendant::span[text()='Slot' and following-sibling::span[1][text()='" + slot + - "']] and descendant::span[text()='Tx' and following-sibling::span[text()='" + tx + "']]]"; - await expect(this.page.locator(blockchainTransactionXPath)).toBeVisible() - } - -} diff --git a/plutus-playground-client/e2e-tests/src/plutus-playground/tests/sanity.spec.ts b/plutus-playground-client/e2e-tests/src/plutus-playground/tests/sanity.spec.ts deleted file mode 100644 index 89345fff00..0000000000 --- a/plutus-playground-client/e2e-tests/src/plutus-playground/tests/sanity.spec.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { test, expect } from '@playwright/test'; -//import envs from '../envs.json'; -import envs from '../envs.json'; - -const { EditorPage } = require('../pageobject/editor'); -const { SimulatorPage } = require('../pageobject/simulator'); - -/*const prod: { name: string, url: string }[] = [ - //{ "name" : "local", "url" : "https://localhost:8009/" } - { "name" : "production", "url" : "http://playground.plutus.iohkdev.io/" } -] -//prod.forEach(function (value) {*/ - -envs.forEach(function (env) { - const baseUrl = env.url - - test(`crowd funding test - ${baseUrl}`, async ({ page }) => { - // given - const editorPage = new EditorPage(page); - const simulatorPage = new SimulatorPage(page); - await editorPage.navigate(baseUrl); - // when - await editorPage.compileCrowdFunding(); - await editorPage.simulate(); - await simulatorPage.isOpen(); - await simulatorPage.evaluate(); - //then - await simulatorPage.confirmCrowdFundingBlockchainTransactions() - }); - - test(`hello world test - ${baseUrl}`, async ({ page }) => { - // given - const editorPage = new EditorPage(page); - const simulatorPage = new SimulatorPage(page); - await editorPage.navigate(baseUrl); - // when - const insertedText = await editorPage.compileHelloWorld(); - await editorPage.simulate(); - await simulatorPage.isOpen(); - await simulatorPage.evaluate(); - //then - await simulatorPage.checkLogsContainsText(insertedText, 2); // 2 wallets - }); - -}); - diff --git a/plutus-playground-client/entry.js b/plutus-playground-client/entry.js deleted file mode 100644 index 2c8a480006..0000000000 --- a/plutus-playground-client/entry.js +++ /dev/null @@ -1,20 +0,0 @@ -/*eslint-env node*/ -/*global global*/ -import '@fortawesome/fontawesome-free/css/all.css'; -import 'chartist/dist/chartist.min.css'; -import 'chartist/dist/chartist.min.js'; -import 'chartist-plugin-tooltips/dist/chartist-plugin-tooltip.css'; -import 'chartist-plugin-tooltips/dist/chartist-plugin-tooltip.min.js'; -import 'chartist-plugin-axistitle/dist/chartist-plugin-axistitle.min.js'; -import './static/main.scss'; - -import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'; -global.monaco = monaco; -import { EmacsExtension } from 'monaco-emacs'; -global.EmacsExtension = EmacsExtension; -import { initVimMode, VimMode } from 'monaco-vim'; -global.VimMode = VimMode; -global.initVimMode = initVimMode; -global.monacoExtraTypeScriptLibs = []; - -require('./output/Main').main(); diff --git a/plutus-playground-client/package-lock.json b/plutus-playground-client/package-lock.json deleted file mode 100644 index 22228576bb..0000000000 --- a/plutus-playground-client/package-lock.json +++ /dev/null @@ -1,6420 +0,0 @@ -{ - "name": "plutus-playground-client", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@discoveryjs/json-ext": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz", - "integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==", - "dev": true - }, - "@fortawesome/fontawesome-free": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz", - "integrity": "sha512-OEdH7SyC1suTdhBGW91/zBfR6qaIhThbcN8PUXtXilY4GYnSBbVqOntdHbC1vXwsDnX0Qix2m2+DSU1J51ybOQ==" - }, - "@types/eslint": { - "version": "7.2.10", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.10.tgz", - "integrity": "sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.0.tgz", - "integrity": "sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "0.0.47", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.47.tgz", - "integrity": "sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==", - "dev": true - }, - "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", - "dev": true - }, - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", - "dev": true - }, - "@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", - "dev": true - }, - "@webassemblyjs/ast": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.0.tgz", - "integrity": "sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz", - "integrity": "sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz", - "integrity": "sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz", - "integrity": "sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz", - "integrity": "sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz", - "integrity": "sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz", - "integrity": "sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz", - "integrity": "sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.0.tgz", - "integrity": "sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.0.tgz", - "integrity": "sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz", - "integrity": "sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/helper-wasm-section": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-opt": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "@webassemblyjs/wast-printer": "1.11.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz", - "integrity": "sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz", - "integrity": "sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-buffer": "1.11.0", - "@webassemblyjs/wasm-gen": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz", - "integrity": "sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/helper-api-error": "1.11.0", - "@webassemblyjs/helper-wasm-bytecode": "1.11.0", - "@webassemblyjs/ieee754": "1.11.0", - "@webassemblyjs/leb128": "1.11.0", - "@webassemblyjs/utf8": "1.11.0" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz", - "integrity": "sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.0", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.3.tgz", - "integrity": "sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==", - "dev": true - }, - "@webpack-cli/info": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.4.tgz", - "integrity": "sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.4.0.tgz", - "integrity": "sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==", - "dev": true - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.2.4.tgz", - "integrity": "sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==", - "dev": true - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "big-integer": { - "version": "1.6.50", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.50.tgz", - "integrity": "sha512-+O2uoQWFRo8ysZNo/rjtri2jIwjr3XfeAgRjAUADRqGG+ZITvyn8J1kvXLTaKVr3hhGXk+f23tKfdzmklVM9vQ==" - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" - }, - "bignumber": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bignumber/-/bignumber-1.1.0.tgz", - "integrity": "sha1-5qsKdD2l8+oBjlwXWX0SH3howVk=" - }, - "bignumber.js": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "bootstrap": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.3.tgz", - "integrity": "sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", - "escalade": "^3.1.1", - "node-releases": "^1.1.71" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } - } - }, - "caniuse-lite": { - "version": "1.0.30001223", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001223.tgz", - "integrity": "sha512-k/RYs6zc/fjbxTjaWZemeSmOjO0JJV+KguOBA3NwPup8uzxM1cMhR2BD9XmO86GuqaqTCO8CgkgH9Rz//vdDiA==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chartist": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/chartist/-/chartist-0.11.4.tgz", - "integrity": "sha512-H4AimxaUD738/u9Mq8t27J4lh6STsLi4BQHt65nOtpLk3xyrBPaLiLMrHw7/WV9CmsjGA02WihjuL5qpSagLYw==" - }, - "chartist-plugin-axistitle": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/chartist-plugin-axistitle/-/chartist-plugin-axistitle-0.0.7.tgz", - "integrity": "sha512-qFG7R/qiZZyCn/gx9WJpMcnyhE0LIpGBxDnPpYtzY5cG53fHBkvJDsAEHEFFfO1l/RHI0G8oN9fpoUD/BMeiFA==" - }, - "chartist-plugin-tooltips": { - "version": "0.0.17", - "resolved": "https://registry.npmjs.org/chartist-plugin-tooltips/-/chartist-plugin-tooltips-0.0.17.tgz", - "integrity": "sha1-/BqY6103cSNbbgjNHBjMlsIRBmA=" - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-css": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", - "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "css-loader": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-5.2.4.tgz", - "integrity": "sha512-OFYGyINCKkdQsTrSYxzGSFnGS4gNjcXkKkQgWxK138jgnPt+lepxdjSZNc8sHAl5vP3DhsJUxufWIjOwI8PMMw==", - "dev": true, - "requires": { - "camelcase": "^6.2.0", - "icss-utils": "^5.1.0", - "loader-utils": "^2.0.0", - "postcss": "^8.2.10", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.1.0", - "schema-utils": "^3.0.0", - "semver": "^7.3.5" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - } - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-node": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.5.tgz", - "integrity": "sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw==", - "dev": true - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true - } - } - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.727", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", - "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.0.tgz", - "integrity": "sha512-Sl3KRpJA8OpprrtaIswVki3cWPiPKxXuFxJXBp+zNb6s6VwNWwFRUdtmzd2ReUut8n+sCPx7QCtQ7w5wfJhSgQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-module-lexer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.4.1.tgz", - "integrity": "sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==", - "dev": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "follow-redirects": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.0.tgz", - "integrity": "sha512-0vRwd7RKQBTt+mgu87mtYeofLFZpTas2S9zY+jIeuLJMNvudIgF52nr19q40HOwH5RrhWIPuj9puybzSJiRrVg==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "dev": true, - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, - "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", - "dev": true - }, - "html-minifier-terser": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", - "integrity": "sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==", - "dev": true, - "requires": { - "camel-case": "^4.1.1", - "clean-css": "^4.2.3", - "commander": "^4.1.1", - "he": "^1.2.0", - "param-case": "^3.0.3", - "relateurl": "^0.2.7", - "terser": "^4.6.3" - } - }, - "html-webpack-plugin": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz", - "integrity": "sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ==", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^5.0.0", - "html-minifier-terser": "^5.0.1", - "lodash": "^4.17.20", - "pretty-error": "^2.1.1", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - } - } - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", - "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", - "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-core-module": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.3.0.tgz", - "integrity": "sha512-xSphU2KG9867tsYdLD4RWQ1VqdFl4HTO9Thf3I/3dLEfr0dbPTWKsuCKrgqMljg4nPE+Gq0VCnzT3gr0CyBmsw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.3.tgz", - "integrity": "sha512-tDpEUInNcy2Yw3lNSepK3Wdw1RnXLcIVienz6Ou631Acl15cJyRWK4dgA1vCmOEgIbtOV0W7MHg+AR2Gdg1NXQ==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", - "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-symbols": "^1.0.1" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" - }, - "js-base64": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", - "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", - "dev": true - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "json-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", - "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", - "requires": { - "bignumber.js": "^9.0.0" - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "klona": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", - "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", - "dev": true - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=" - }, - "lodash.throttle": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" - }, - "loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", - "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", - "dev": true - }, - "mime-types": { - "version": "2.1.30", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", - "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", - "dev": true, - "requires": { - "mime-db": "1.47.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "mini-css-extract-plugin": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz", - "integrity": "sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "monaco-editor": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.21.3.tgz", - "integrity": "sha512-9N7wATLpi+googstvtm6IKg97vPQ77FDYEpkow5tLriM/VJ0DaTRyUP4UVzcoH7KlPDX+e/rE7/imcOUeGkT6g==" - }, - "monaco-editor-webpack-plugin": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-2.1.0.tgz", - "integrity": "sha512-DG7Dpo/ItWEOl/BG2egc/UIiHoCbHjq0EOF0E6eJQT+6QNZBOfSVU4GxaXG+kQJXB8rauxli96Xp1ITnNLZtSw==", - "requires": { - "loader-utils": "^2.0.0" - }, - "dependencies": { - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - } - } - }, - "monaco-emacs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/monaco-emacs/-/monaco-emacs-0.2.2.tgz", - "integrity": "sha512-v2FefXBSRc5WZC5jbfJ1F+kj1Nh4EO5Zxfubh8v4k/npveJzh0VmVUkMlpi1IeodcM4vIuJVZglpFr6ZM70Bkg==", - "requires": { - "lodash.kebabcase": "^4.1.1", - "lodash.throttle": "^4.1.1" - } - }, - "monaco-vim": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/monaco-vim/-/monaco-vim-0.1.13.tgz", - "integrity": "sha512-nhl84Xk7dcqXiL+c1HlaGmlEscA0hm01yScY4gBd+5GejzWrX4oHhGYlwSDyKljoCyAMUYKvbkEQK7NENl1zkw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true - }, - "nanoid": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "node-gyp": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", - "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.3", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "request": "^2.88.2", - "rimraf": "^3.0.2", - "semver": "^7.3.2", - "tar": "^6.0.2", - "which": "^2.0.2" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", - "dev": true - }, - "node-sass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", - "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", - "dev": true, - "requires": { - "async-foreach": "^0.1.3", - "chalk": "^1.1.1", - "cross-spawn": "^7.0.3", - "gaze": "^1.0.0", - "get-stdin": "^4.0.1", - "glob": "^7.0.3", - "lodash": "^4.17.15", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", - "nan": "^2.13.2", - "node-gyp": "^7.1.0", - "npmlog": "^4.0.0", - "request": "^2.88.0", - "sass-graph": "2.2.5", - "stdout-stream": "^1.4.0", - "true-case-path": "^1.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.0" - }, - "dependencies": { - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } - } - }, - "popper.js": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", - "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "8.2.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.14.tgz", - "integrity": "sha512-+jD0ZijcvyCqPQo/m/CW0UcARpdFylq04of+Q7RKX6f/Tu+dvpUI/9Sp81+i6/vJThnOBX09Quw0ZLOVwpzX3w==", - "dev": true, - "requires": { - "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-selector-parser": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.5.tgz", - "integrity": "sha512-aFYPoYmXbZ1V6HZaSvat08M97A8HqO6Pjz+PiNpw/DhuRrC72XWAdp3hL6wusDCN31sSmcZyMGa2hZEuX+Xfhg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "pretty-error": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", - "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^2.0.4" - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", - "dev": true, - "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.1" - } - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - } - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", - "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", - "dev": true, - "requires": { - "css-select": "^2.0.2", - "dom-converter": "^0.2", - "htmlparser2": "^3.10.1", - "lodash": "^4.17.20", - "strip-ansi": "^3.0.0" - } - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sass-graph": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", - "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "lodash": "^4.0.0", - "scss-tokenizer": "^0.2.3", - "yargs": "^13.3.2" - } - }, - "sass-loader": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.0.1.tgz", - "integrity": "sha512-Vp1LcP4slTsTNLEiDkTcm8zGN/XYYrZz2BZybQbliWA8eXveqA/AxsEjllQTpJbg2MzCsx/qNO48sHdZtOaxTw==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", - "dev": true, - "requires": { - "js-base64": "^2.1.8", - "source-map": "^0.4.2" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", - "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-javascript": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", - "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", - "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^3.4.0", - "websocket-driver": "^0.7.4" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "sockjs-client": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", - "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", - "dev": true, - "requires": { - "debug": "^3.2.6", - "eventsource": "^1.0.7", - "faye-websocket": "^0.11.3", - "inherits": "^2.0.4", - "json3": "^3.3.3", - "url-parse": "^1.5.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", - "dev": true - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stdout-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", - "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "style-loader": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz", - "integrity": "sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "dev": true - }, - "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz", - "integrity": "sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==", - "dev": true, - "requires": { - "jest-worker": "^26.6.2", - "p-limit": "^3.1.0", - "schema-utils": "^3.0.0", - "serialize-javascript": "^5.0.1", - "source-map": "^0.6.1", - "terser": "^5.5.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "terser": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.7.0.tgz", - "integrity": "sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.7.2", - "source-map-support": "~0.5.19" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - } - } - } - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "true-case-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", - "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", - "dev": true, - "requires": { - "glob": "^7.1.2" - } - }, - "tslib": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.2.0.tgz", - "integrity": "sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "url-parse": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", - "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "watchpack": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz", - "integrity": "sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webpack": { - "version": "5.36.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.36.2.tgz", - "integrity": "sha512-XJumVnnGoH2dV+Pk1VwgY4YT6AiMKpVoudUFCNOXMIVrEKPUgEwdIfWPjIuGLESAiS8EdIHX5+TiJz/5JccmRg==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.0", - "@types/estree": "^0.0.47", - "@webassemblyjs/ast": "1.11.0", - "@webassemblyjs/wasm-edit": "1.11.0", - "@webassemblyjs/wasm-parser": "1.11.0", - "acorn": "^8.2.1", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.8.0", - "es-module-lexer": "^0.4.0", - "eslint-scope": "^5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.4", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.0.0", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.1", - "watchpack": "^2.0.0", - "webpack-sources": "^2.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "schema-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", - "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.6", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "webpack-sources": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-2.2.0.tgz", - "integrity": "sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==", - "dev": true, - "requires": { - "source-list-map": "^2.0.1", - "source-map": "^0.6.1" - } - } - } - }, - "webpack-cli": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.7.0.tgz", - "integrity": "sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.0.3", - "@webpack-cli/info": "^1.2.4", - "@webpack-cli/serve": "^1.4.0", - "colorette": "^1.2.1", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "v8-compile-cache": "^2.2.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", - "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - } - } - }, - "webpack-dev-server": { - "version": "3.11.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", - "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.8", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "sockjs-client": "^1.5.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.7.3.tgz", - "integrity": "sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xhr2": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.2.1.tgz", - "integrity": "sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==" - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } - } -} diff --git a/plutus-playground-client/package.json b/plutus-playground-client/package.json deleted file mode 100644 index 2b15c2d3ff..0000000000 --- a/plutus-playground-client/package.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "name": "plutus-playground-client", - "version": "1.0.0", - "scripts": { - "build:spago": "spago build --purs-args \"--strict --censor-lib --stash --is-lib=generated --is-lib=.spago\"", - "build:spago:watch": "spago build --purs-args \"--strict --censor-lib --stash --is-lib=generated --is-lib=.spago\" --watch --clear-screen", - "build:webpack": "webpack-cli serve --progress --inline --hot --mode=development --node-env=development", - "build:webpack:prod": "webpack --progress --bail --mode=production --node-env=production", - "build:webpack:dev": "webpack-cli serve --progress --inline --hot --mode=development --node-env=development --host 0.0.0.0", - "install:spago": "spago install", - "docs": "spago docs", - "repl": "spago repl", - "start": "npm install && npm run install:spago && npm run build:spago && npm run build:webpack:dev", - "test": "spago test --purs-args \"--strict --censor-lib --stash --is-lib=generated --is-lib=.spago\"", - "test:watch": "spago test --purs-args \"--strict --censor-lib --stash --is-lib=generated --is-lib=.spago\" --watch --clear-screen" - }, - "resolutions": {}, - "license": "Apache-2.0", - "dependencies": { - "@fortawesome/fontawesome-free": "^5.10.2", - "big-integer": "^1.6.50", - "bignumber": "^1.1.0", - "chartist": "^0.11.4", - "chartist-plugin-axistitle": "^0.0.7", - "chartist-plugin-tooltips": "^0.0.17", - "jquery": "^3.6.0", - "json-bigint": "^1.0.0", - "monaco-editor": "^0.21.0", - "monaco-editor-webpack-plugin": "^2.1.0", - "monaco-emacs": "^0.2.2", - "monaco-vim": "^0.1.13", - "popper.js": "^1.14.4", - "uuid": "^8.3.2", - "xhr2": "^0.2.1" - }, - "devDependencies": { - "bootstrap": "^4.3.1", - "css-loader": "^5.2.4", - "file-loader": "^6.2.0", - "html-webpack-plugin": "^5.3.1", - "mini-css-extract-plugin": "^1.5.1", - "node-sass": "^5.0.0", - "sass-loader": "^11.0.1", - "style-loader": "^2.0.0", - "url-loader": "^4.1.1", - "webpack": "^5.36.2", - "webpack-cli": "^4.6.0", - "webpack-dev-server": "^3.11.2" - } -} diff --git a/plutus-playground-client/spago-packages.nix b/plutus-playground-client/spago-packages.nix deleted file mode 100644 index d8b99f01c1..0000000000 --- a/plutus-playground-client/spago-packages.nix +++ /dev/null @@ -1,1522 +0,0 @@ -# This file was generated by Spago2Nix - -{ pkgs ? import {} }: - -let - inputs = { - - "aff" = pkgs.stdenv.mkDerivation { - name = "aff"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-aff.git"; - rev = "d0eb009f2f47cb1f5ba1d8592d90c95e8e7ff75d"; - sha256 = "1780sgqyvbdgh8ynxmxn5d44vvhaz7kn9sv3l44c2s9q8xfjkfgm"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "aff-promise" = pkgs.stdenv.mkDerivation { - name = "aff-promise"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/nwolverson/purescript-aff-promise.git"; - rev = "45cfba7f663fce12fe69285fe5acaa4ff025144c"; - sha256 = "12fnlwcrj5p6kc5rls7qxwg53zd83gkdpklpmp8jyav945hlgbj2"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "affjax" = pkgs.stdenv.mkDerivation { - name = "affjax"; - version = "v12.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-affjax.git"; - rev = "5be197edc213fbededb8da908f77b69908eaa6f8"; - sha256 = "1f2snaimnl9ry8f3kankfcyy50wkba54vvin4wsrglahqgs1nrgb"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "ansi" = pkgs.stdenv.mkDerivation { - name = "ansi"; - version = "v6.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/hdgarrood/purescript-ansi.git"; - rev = "e89e6fede616bd16b001841cf30ac320c95313a6"; - sha256 = "1jsll0h7nz13zgscs036cnkkc6frnlcnk6fwjdwsyp6wbmjri2zm"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "argonaut" = pkgs.stdenv.mkDerivation { - name = "argonaut"; - version = "v8.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-argonaut.git"; - rev = "e5137df76065c14e5de70c4e2820222bd7c78fc2"; - sha256 = "05sq1102rl1phm2gadx0gp966yvk9q1r492bb30q1m0nz762q4v2"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "argonaut-codecs" = pkgs.stdenv.mkDerivation { - name = "argonaut-codecs"; - version = "v8.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-argonaut-codecs.git"; - rev = "b0a041d92bfd548e2cd793cc7c02363464325a13"; - sha256 = "11vmlq98s4jmg5grvdrrlfkqj9vk3la44ky8158a440ipcpinjkq"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "argonaut-core" = pkgs.stdenv.mkDerivation { - name = "argonaut-core"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-argonaut-core.git"; - rev = "673971dee79667882a83f9fda7097e50530726f1"; - sha256 = "13ka4xybc8ql54xlkkhy4919nnapfigdlk51ja85f8xwhr64x9kq"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "argonaut-traversals" = pkgs.stdenv.mkDerivation { - name = "argonaut-traversals"; - version = "v9.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-argonaut-traversals.git"; - rev = "36f2e368ceea1ed681bd8e2884eaca451945fc44"; - sha256 = "0bj88s7rz50jfhyawq4h97lvbr3h7pksbqnz4lmh714f5fda6ncx"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "arraybuffer-types" = pkgs.stdenv.mkDerivation { - name = "arraybuffer-types"; - version = "v3.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-arraybuffer-types.git"; - rev = "48cd7f4887791db1d9c2daf5fd98b62ba00e15bd"; - sha256 = "09r6bhsiq9iqdsjf9p8m3p31qkszsipsafvy836mfdi8af6h5fv6"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "arrays" = pkgs.stdenv.mkDerivation { - name = "arrays"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-arrays.git"; - rev = "c0aa3176b077ad7a46b11ef34487485c28142e53"; - sha256 = "0lm0m5hapimchzgfywr648pkw1hpggr6qibh8d19p2impbnc94c0"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "assert" = pkgs.stdenv.mkDerivation { - name = "assert"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-assert.git"; - rev = "71a3b1f3b9917c23691fdbb1858de171be871a10"; - sha256 = "0r1l7j67an8dy1w4xdpr8nc30lsxv31xwqph9mkfh3nd49jlyyd3"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "avar" = pkgs.stdenv.mkDerivation { - name = "avar"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-avar.git"; - rev = "ac3cbbb8d4b71ff19a78a3178355c089e44d3b4d"; - sha256 = "005046wl61w6r5v3qwd16srhcx82vdz3yvp4xzad2xaasb6iq55l"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "bifunctors" = pkgs.stdenv.mkDerivation { - name = "bifunctors"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-bifunctors.git"; - rev = "a31d0fc4bbebf19d5e9b21b65493c28b8d3fba62"; - sha256 = "0xc2hf8ccdgqw3m9qcmr38kmzv05fsxvakd07wyrqshvkzg3xn0d"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "bigints" = pkgs.stdenv.mkDerivation { - name = "bigints"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/sharkdp/purescript-bigints.git"; - rev = "d5151e04db7e18641fbb2b5892f4198b1cab5907"; - sha256 = "0x8s6d6q2rpfkk56bmayg57a7hl2h7sq9ljrxfc8sjnwd7mfs193"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "catenable-lists" = pkgs.stdenv.mkDerivation { - name = "catenable-lists"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-catenable-lists.git"; - rev = "ee03395f2c5d59a7fd8529a0faac6ec1ebcbb682"; - sha256 = "1lz06fx0za5sl65wccn5fl37mw3x4jnvrriz1gg0aqsmm9lag7ss"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "concurrent-queues" = pkgs.stdenv.mkDerivation { - name = "concurrent-queues"; - version = "v2.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-concurrent-queues.git"; - rev = "300965817e2ef8a87cc3214f0f674193596cc600"; - sha256 = "1x67azwjb1vn3dpcbzwgfvyfpx2qh0b2ns3d0jr8ckgrs4msrfmj"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "console" = pkgs.stdenv.mkDerivation { - name = "console"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-console.git"; - rev = "d7cb69ef8fed8a51466afe1b623868bb29e8586e"; - sha256 = "0fzzzqjgrz33pb2jf7cdqpg09ilxb7bsrc7sbfq52wjg0sx9aq6g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "const" = pkgs.stdenv.mkDerivation { - name = "const"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-const.git"; - rev = "3a3a4bdc44f71311cf27de9bd22039b110277540"; - sha256 = "0aq9qjbrvf8mf8hmas6imv4mg6n3zi13hkf449ns1hn12lw8qv4g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "contravariant" = pkgs.stdenv.mkDerivation { - name = "contravariant"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-contravariant.git"; - rev = "ae1a765f7ddbfd96ae1f12e399e46d554d8e3b38"; - sha256 = "029hb8i3n4759x4gc06wkfgr7wim5x1w5jy2bsiy42n0g731h5qc"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "control" = pkgs.stdenv.mkDerivation { - name = "control"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-control.git"; - rev = "18d582e311f1f8523f9eb55fb93c91bd21e22837"; - sha256 = "06dc06yli4g5yr8fb9sdpqbhiaff37g977qcsbds9q2mlhnjgfx9"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "coroutines" = pkgs.stdenv.mkDerivation { - name = "coroutines"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-coroutines.git"; - rev = "c9788b76cee058f7d3df49f4a662ed1fa1cd8f8f"; - sha256 = "1s65mv8gw4f2n0f75dld16mq9m1qmj6cp4yzy80v67nrg5mfw9xa"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "datetime" = pkgs.stdenv.mkDerivation { - name = "datetime"; - version = "v5.0.2"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-datetime.git"; - rev = "e110462829ea656d2bc0924266d4edff222108d4"; - sha256 = "1mhzn2ymdkzki7wjlr9xrdbngm0886wmfbh2c46flnf9lmfyw54y"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "debug" = pkgs.stdenv.mkDerivation { - name = "debug"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/garyb/purescript-debug.git"; - rev = "144305842dba81169a93b3a3cc75429d5c8389e9"; - sha256 = "09j69bgrq8nzw1l3aj1hka3y5ycmcsn9dlgf22k5ifrd74iic60y"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "distributive" = pkgs.stdenv.mkDerivation { - name = "distributive"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-distributive.git"; - rev = "11f3f87ca5720899e1739cedb58dd6227cae6ad5"; - sha256 = "0788znmdyh6b1c9pln624ah397l88xmd3fxlxiy3z1qy8bzr4r54"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "dom-indexed" = pkgs.stdenv.mkDerivation { - name = "dom-indexed"; - version = "v8.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-halogen/purescript-dom-indexed.git"; - rev = "d1e365cfc6d1b05d175061146a4a423d61ecf500"; - sha256 = "092z5y96bw88dywd2qnjv668lnf62anb5kgjz0x9a6cbilq62rz2"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "effect" = pkgs.stdenv.mkDerivation { - name = "effect"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-effect.git"; - rev = "985d97bd5721ddcc41304c55a7ca2bb0c0bfdc2a"; - sha256 = "1n9qr85knvpm4i0qhm8xbgfk46v9y843p76j278phfs9l6aywzsn"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "either" = pkgs.stdenv.mkDerivation { - name = "either"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-either.git"; - rev = "c1a1af35684f10eecaf6ac7d38dbf6bd48af2ced"; - sha256 = "18dk159yyv7vs0xsnh9m5fajd7zy6zw5b2mpyd6nqdh3c6bb9wh6"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "enums" = pkgs.stdenv.mkDerivation { - name = "enums"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-enums.git"; - rev = "170d959644eb99e0025f4ab2e38f5f132fd85fa4"; - sha256 = "1lci5iy6s6cmh93bpkfcmp0j4n5dnij7dswb0075bk0kzd9xp7rs"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "exceptions" = pkgs.stdenv.mkDerivation { - name = "exceptions"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-exceptions.git"; - rev = "410d0b8813592bda3c25028540eeb2cda312ddc9"; - sha256 = "1yjbrx34a0rnxgpvywb63n9jzhkdgb2q2acyzbwh290mrrggc95x"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "exists" = pkgs.stdenv.mkDerivation { - name = "exists"; - version = "v5.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-exists.git"; - rev = "c34820f8b2d15be29abdd5097c3d636f5df8f28c"; - sha256 = "15qp52cpp2yvxihkzfmn6gabyvx5s6iz5lafvqhyfgp4wfnz0bds"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "filterable" = pkgs.stdenv.mkDerivation { - name = "filterable"; - version = "v4.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-filterable.git"; - rev = "e549b35d4147a3b7f0f81d554ce118e07c78e3d0"; - sha256 = "1n1j1h21fabialc5bv4zk723sjb23cc867vf11326zib9y10aq6m"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "fixed-points" = pkgs.stdenv.mkDerivation { - name = "fixed-points"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-fixed-points.git"; - rev = "3b643d948479aee7cd3e36c95258f1f84df0c35f"; - sha256 = "0w2j0sarylzsmg8b228pmn3qndif0bzw2vmxrx30ar15qy7jdb5d"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "foldable-traversable" = pkgs.stdenv.mkDerivation { - name = "foldable-traversable"; - version = "v5.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-foldable-traversable.git"; - rev = "d581caf260772b1b446c11ac3c8be807b290b220"; - sha256 = "182na4np7hk2dqyxywy4jij2csrzx4bz02m6bq8yx1j27hlgjvsd"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "foreign" = pkgs.stdenv.mkDerivation { - name = "foreign"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-foreign.git"; - rev = "7ee18c6689c56c89755172ea53326f948da10bd3"; - sha256 = "16j7712cck79p8q53xbhn4hs886bm0ls5wvmchrhqnaghj48m85g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "foreign-generic" = pkgs.stdenv.mkDerivation { - name = "foreign-generic"; - version = "v11.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/paf31/purescript-foreign-generic.git"; - rev = "3cddc5fe3e87e426e0f719465ba60b9df4c0c72d"; - sha256 = "129bgngch2zi65838v2hcywx59gd3x56fq8zaasnwj5kwm34dxcw"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "foreign-object" = pkgs.stdenv.mkDerivation { - name = "foreign-object"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-foreign-object.git"; - rev = "c9a7b7bb8bed1b87c5545c4ebe85a70f86c0e6b1"; - sha256 = "0accw6qd93qqry19rskjgl7y54xi2wd70rglbqyjx6c5ybcjnavr"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "fork" = pkgs.stdenv.mkDerivation { - name = "fork"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-fork.git"; - rev = "153cc29e6e51fb1108368efc622d41d9f80bd707"; - sha256 = "1hyvaixza8151zbylk2kv859x48yyhla536lcjghcwd62vzfwmdn"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "form-urlencoded" = pkgs.stdenv.mkDerivation { - name = "form-urlencoded"; - version = "v6.0.2"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-form-urlencoded.git"; - rev = "860b2c4bf0a848322d2077faaefbeb98762cb8d6"; - sha256 = "1pi3vxix10crisisnd94li1vmmgiawlh5lgl51z7ssd9azygg0b0"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "free" = pkgs.stdenv.mkDerivation { - name = "free"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-free.git"; - rev = "06e76495397eafe15c9c1273f2ef05e55f1a3ca3"; - sha256 = "0kpq83qjfjzf1l2f1cnnx36kjwnm5czgjyh2imwp3bna8js6sk39"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "freeap" = pkgs.stdenv.mkDerivation { - name = "freeap"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/ethul/purescript-freeap.git"; - rev = "2756c0abaa78362694ad4abca19d2a08dc06df8d"; - sha256 = "1kslihgbpmznmalxwz9i4czrwbwkdf5xq3mswaixmcfmgzc0r63g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "freet" = pkgs.stdenv.mkDerivation { - name = "freet"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-freet.git"; - rev = "507c2edd9173cda5ad44dd0638133edd69fd9acd"; - sha256 = "0f5bibw604sd9ffmp51b3jppka88r54mh7sdz91zy5b92wgsy5yr"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "functions" = pkgs.stdenv.mkDerivation { - name = "functions"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-functions.git"; - rev = "691b3345bc2feaf914e5299796c606b6a6bf9ca9"; - sha256 = "1gnk6xh5x04zcahn82gwp49qpglxd5jkfqn0i58m27jfihvblaxd"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "functors" = pkgs.stdenv.mkDerivation { - name = "functors"; - version = "v4.1.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-functors.git"; - rev = "e936f7a8d2ec53a344c478ccada5add93273848c"; - sha256 = "0i1x14r54758s5jx5d7zy4l07mg6gabljadgybldnbpmdqk6b966"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "gen" = pkgs.stdenv.mkDerivation { - name = "gen"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-gen.git"; - rev = "85c369f56545a3de834b7e7475a56bc9193bb4b4"; - sha256 = "1h396rqn1fc2c155i58vnaksqjrpajly128ah6wq1w426vwr1vrf"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "halogen" = pkgs.stdenv.mkDerivation { - name = "halogen"; - version = "v6.1.3"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-halogen/purescript-halogen.git"; - rev = "79b86b70ab0848a3551e1dac1d854036ad23d833"; - sha256 = "08m639pfh85w52w1kk3qdk9cxvxi0f2fcfvyk23k7j5y4pi43z8f"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "halogen-subscriptions" = pkgs.stdenv.mkDerivation { - name = "halogen-subscriptions"; - version = "v1.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-halogen/purescript-halogen-subscriptions.git"; - rev = "95dfd40ec490ac847b9fe458e5821acba3e30ff5"; - sha256 = "00yjxxzwvqc0mvf6z3qml3br9f611h10v07gcbnc723xd2qvbgrb"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "halogen-vdom" = pkgs.stdenv.mkDerivation { - name = "halogen-vdom"; - version = "v7.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-halogen/purescript-halogen-vdom.git"; - rev = "ebab8125a513de17dec3b9e69804fc2ac9c517aa"; - sha256 = "14jcmca3crwc9phx1hfnr5gpdb4sw4amf5ssdfvjrs9fky06gfqy"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "http-methods" = pkgs.stdenv.mkDerivation { - name = "http-methods"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-http-methods.git"; - rev = "d373066a45017e886d1580cd359372368231de47"; - sha256 = "1g0ywd5zpckmhq28mr14yr4k28hiii1px8r8xbdx8nv45ryw69l3"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "identity" = pkgs.stdenv.mkDerivation { - name = "identity"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-identity.git"; - rev = "5c150ac5ee4fa6f145932f6322a1020463dae8e9"; - sha256 = "0a58y71ihvb5b7plnn2sxsbphqzd9nzfafak4d5a576agn76q0ql"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "integers" = pkgs.stdenv.mkDerivation { - name = "integers"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-integers.git"; - rev = "8a783f2d92596c43afca53066ac18eb389d15981"; - sha256 = "1rrygw0ai61brnvgap7dfhdzacyhg5439pz6yrmmyg32cvf0znhv"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "invariant" = pkgs.stdenv.mkDerivation { - name = "invariant"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-invariant.git"; - rev = "c421b49dec7a1511073bb408a08bdd8c9d17d7b1"; - sha256 = "0vwkbh7kv00g50xjgvxc0mv5b99mrj6q0sxznxwk32hb9hkbhy5l"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "js-date" = pkgs.stdenv.mkDerivation { - name = "js-date"; - version = "v7.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-js-date.git"; - rev = "a6834eef986e3af0490cb672dc4a8b4b089dcb15"; - sha256 = "1dpiwn65qww862ilpfbd06gwfazpxvz3jwvsjsdrcxqqfcbjp8n8"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "js-uri" = pkgs.stdenv.mkDerivation { - name = "js-uri"; - version = "v2.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-js-uri.git"; - rev = "6145d5e631be3d57d8a4a9cf976ae140713dee35"; - sha256 = "1q34ir93cqbcl9g49vv1qfj8jxbbdj7f85a14y4mzd7yjq0a042g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "json-helpers" = pkgs.stdenv.mkDerivation { - name = "json-helpers"; - version = "60615c36abaee16d8dbe09cdd0e772e6d523d024"; - src = pkgs.fetchgit { - url = "https://github.com/input-output-hk/purescript-bridge-json-helpers.git"; - rev = "60615c36abaee16d8dbe09cdd0e772e6d523d024"; - sha256 = "0b5wpdgy2pgk5r97ln3sql4h2c2v45h3jl2262gzqchhgvi3n4kb"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "lazy" = pkgs.stdenv.mkDerivation { - name = "lazy"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-lazy.git"; - rev = "2f73f61e7ac1ae1cfe05564112e3313530e673ff"; - sha256 = "1wxfx019911gbkifq266hgn67zwm89pxhi83bai77mva5n9j3f6l"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "lcg" = pkgs.stdenv.mkDerivation { - name = "lcg"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-lcg.git"; - rev = "8fb2eb16bbba2cee1d115a6729659ac649da811b"; - sha256 = "04r9bmx9kc3jqx59hh9yqqkl95mf869la9as5h36jv85ynn464dx"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "lists" = pkgs.stdenv.mkDerivation { - name = "lists"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-lists.git"; - rev = "6383c4f202b3f69474f9f7da182c2d42fcc3111c"; - sha256 = "0xmg918s3mqvfvwgjfqcs1yvcz6hy2n7h3ygqz2iyvk868gz25qs"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "markdown" = pkgs.stdenv.mkDerivation { - name = "markdown"; - version = "022d8afd0d9e0ef8114da9e9ef5a67d9ffc86a29"; - src = pkgs.fetchgit { - url = "https://github.com/input-output-hk/purescript-markdown"; - rev = "022d8afd0d9e0ef8114da9e9ef5a67d9ffc86a29"; - sha256 = "008f2wvvddg436b84kgpwz8m5h912xg1wqq73p97i79zaq13w9zm"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "math" = pkgs.stdenv.mkDerivation { - name = "math"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-math.git"; - rev = "59746cc74e23fb1f04e09342884c5d1e3943a04f"; - sha256 = "0hkf0vyiga21992d9vbvdbnzdkvgljmsi497jjas1rk3vhblx8sq"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "matryoshka" = pkgs.stdenv.mkDerivation { - name = "matryoshka"; - version = "v0.5.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-matryoshka.git"; - rev = "43eb7d9c2d42e2d8bafa4303b4f6185143846b05"; - sha256 = "13n6wiwi7kbrhfvh25mk0p323l2q48cp7s0f7ad4y2jiks3lgipn"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "maybe" = pkgs.stdenv.mkDerivation { - name = "maybe"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-maybe.git"; - rev = "8e96ca0187208e78e8df6a464c281850e5c9400c"; - sha256 = "0vyk3r9gklvv7awzpph7ra53zxxbin1ngmqflb5vvr2365v5xyqy"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "media-types" = pkgs.stdenv.mkDerivation { - name = "media-types"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-media-types.git"; - rev = "b6efa4c1e6808b31f399d8030b5938acec87cb48"; - sha256 = "0l51nd1w52756pyy3zliwmhfbin0px4pxr7d2h5vchl1wq895fja"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "mmorph" = pkgs.stdenv.mkDerivation { - name = "mmorph"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/Thimoteus/purescript-mmorph.git"; - rev = "ebe16afbfa16dd600f3379ccedc7529417402393"; - sha256 = "0ds88hray8v0519n9k546qsc4qs8bj1k5h5az7nwfp0gaq0r5wpk"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "newtype" = pkgs.stdenv.mkDerivation { - name = "newtype"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-newtype.git"; - rev = "7b292fcd2ac7c4a25d7a7a8d3387d0ee7de89b13"; - sha256 = "1fgzbxslckva2psn0sia30hfakx8xchz3wx2kkh3w8rr4nn2py8v"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "node-buffer" = pkgs.stdenv.mkDerivation { - name = "node-buffer"; - version = "v7.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-node/purescript-node-buffer.git"; - rev = "0721f1e8d768df48ae429547c8c60b121ca120cb"; - sha256 = "14bf3llsa20ivkwp5hlyk8v8zfzpzhhsni9pd8rfqdyzp6zrdx3b"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "node-fs" = pkgs.stdenv.mkDerivation { - name = "node-fs"; - version = "v6.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-node/purescript-node-fs.git"; - rev = "09a2b71a3a86f0cd19c46f4b6c40310cc1648909"; - sha256 = "1w97m2afn7yn757niknkbk7w6nyg4n5dabxr7gzfz368z1nkf45s"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "node-path" = pkgs.stdenv.mkDerivation { - name = "node-path"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-node/purescript-node-path.git"; - rev = "a2d7cf05e40b607ef7d048a3684cda788cd42890"; - sha256 = "1384qyf4v84wbahafzvqdxjllqy8qkd5dpkhsl3js444vsm2aplr"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "node-streams" = pkgs.stdenv.mkDerivation { - name = "node-streams"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-node/purescript-node-streams.git"; - rev = "886bb2045685e3b9031687d69ccfed29972147bb"; - sha256 = "1jc3d4x0v77h8qcwq7hpwprsdr3gqmdfiyr1ph0kiy7r9bbrqwfx"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "nonempty" = pkgs.stdenv.mkDerivation { - name = "nonempty"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-nonempty.git"; - rev = "d3e91e3d6e06e5bdcc5b2c21c8e5d0f9b946bb9e"; - sha256 = "0azk1jrpqnjf2i97lcp63wcm31c4hddklp1mfmdan27zap3zqyjm"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "now" = pkgs.stdenv.mkDerivation { - name = "now"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-now.git"; - rev = "4c994dae8bb650787de1e4d9e709f2565fb354fb"; - sha256 = "1wa4j2h5rlw1lgfpm7rif3v6ksm8lplxl1x69zpk8hdf0cfyz4qm"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "nullable" = pkgs.stdenv.mkDerivation { - name = "nullable"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-nullable.git"; - rev = "8b19c16b16593102ae5d5d9f5b42eea0e213e2f5"; - sha256 = "0jbmks8kwhpb5fr2b9nb70fjwh6zdnwirycvzr77jafcny24yrnl"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "numbers" = pkgs.stdenv.mkDerivation { - name = "numbers"; - version = "v8.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-numbers.git"; - rev = "f5bbd96cbed58403c4445bd4c73df50fc8d86f46"; - sha256 = "00pm2x4kh4fm91r7nmik1v5jclkgh7gpxz13ambyqxbxbiqjq0vg"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "ordered-collections" = pkgs.stdenv.mkDerivation { - name = "ordered-collections"; - version = "v2.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-ordered-collections.git"; - rev = "f226bdf904a153746bda6b928fb32fb25bb2a319"; - sha256 = "1p592g0s07c56639y71782af0zz5cndpjxd5w9n41hdszsz1b86h"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "orders" = pkgs.stdenv.mkDerivation { - name = "orders"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-orders.git"; - rev = "c25b7075426cf82bcb960495f28d2541c9a75510"; - sha256 = "0wwy3ycjll0s590ra35zf5gjvs86w97rln09bj428axhg7cvfl0a"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "parallel" = pkgs.stdenv.mkDerivation { - name = "parallel"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-parallel.git"; - rev = "16b38a2e148639b04ae67e0ce63cc220da8857f7"; - sha256 = "0x8mvhgs8ygqj34xgyhk6gixqm32p2ymm00zg0zdw13g3lil9p4x"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "parsing" = pkgs.stdenv.mkDerivation { - name = "parsing"; - version = "v6.0.2"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-parsing.git"; - rev = "d085e3740560d4dcdd710775e4181129be378b89"; - sha256 = "0lhri5bfk4j6dgzi4d5gvmd628hjs9jgyky910ylj6qzalw9fj56"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "partial" = pkgs.stdenv.mkDerivation { - name = "partial"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-partial.git"; - rev = "2f0a5239efab68179a684603263bcec8f1489b08"; - sha256 = "0acxf686hvaj793hyb7kfn9lf96kv3nk0lls2p9j095ylp55sldb"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "pipes" = pkgs.stdenv.mkDerivation { - name = "pipes"; - version = "v7.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/felixschl/purescript-pipes.git"; - rev = "42e43f0961ad0fc3f1cef6986fe23ca9f48f6dda"; - sha256 = "0jzgzi34wqqdcfgznbpfv4b8al2prd36yshnndlvkqfv70smx3kh"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "precise" = pkgs.stdenv.mkDerivation { - name = "precise"; - version = "v5.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-precise.git"; - rev = "5bedbf520022ce15b03a70474d9cf1a8dc3e6b2d"; - sha256 = "1zashxhy100r0pgmnjxbqjf9q9bml9rwm0hqqcxzkd2l0llxaggc"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "prelude" = pkgs.stdenv.mkDerivation { - name = "prelude"; - version = "v5.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-prelude.git"; - rev = "68f8012bc2309d9bf5832cdf7316ad052d586905"; - sha256 = "1x0cacvv9mmw80vy6f40y0p959q1dz28fwjswhyd7ws6npbklcy0"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "profunctor" = pkgs.stdenv.mkDerivation { - name = "profunctor"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-profunctor.git"; - rev = "4551b8e437a00268cc9b687cbe691d75e812e82b"; - sha256 = "0fvd2xiv77sp4jd4spgdp4i9812p6pdzzbg4pa96mbr0h19jf39c"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "profunctor-lenses" = pkgs.stdenv.mkDerivation { - name = "profunctor-lenses"; - version = "v7.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-profunctor-lenses.git"; - rev = "9c3d87a6dab8eb785a93bff11aa183796dc93183"; - sha256 = "1wknj7g6vwk2ga1rq57l470h322308ddjn5bd3x2hhfkiy039kc3"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "psci-support" = pkgs.stdenv.mkDerivation { - name = "psci-support"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-psci-support.git"; - rev = "f26fe8266a63494080476333e22f971404ea8846"; - sha256 = "16vhf8hapd7rcgmafmjpiq7smhzdh3300f2idk1q4kk01yxn8ddj"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "quickcheck" = pkgs.stdenv.mkDerivation { - name = "quickcheck"; - version = "v7.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-quickcheck.git"; - rev = "990fa1cf14b48b827d9b2d115b1c6977c4b0a76d"; - sha256 = "1dxchng3r2mad0505a0c7cc35vs1f7y2xb5i13p59jpdz6ijqa9k"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "quickcheck-laws" = pkgs.stdenv.mkDerivation { - name = "quickcheck-laws"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-quickcheck-laws.git"; - rev = "464597522e5e001adc2619676584871f423b9ea0"; - sha256 = "1m397bh2w5a0wvms8rjgfxh71m7krmfkgk11j5krhz86b72k3izd"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "random" = pkgs.stdenv.mkDerivation { - name = "random"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-random.git"; - rev = "3e02da113c7afbac37ea4e16188c39d3057314d5"; - sha256 = "1v6ykgp8jmx488hq8mgb0l0sf1nyhjs6wq0w279iyibk9jxc6nib"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "rationals" = pkgs.stdenv.mkDerivation { - name = "rationals"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/anttih/purescript-rationals.git"; - rev = "8c52d8cc891d1223150a31416220aa9b99404442"; - sha256 = "1idvjvvx5kwmi8kj2ps95bcvlsgij1xgin4jfw3rmcqd930wqq6q"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "record" = pkgs.stdenv.mkDerivation { - name = "record"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-record.git"; - rev = "091495d61fcaa9d8d8232e7b800f403a3165a38f"; - sha256 = "0yidfvwiajiv8xflfsi2p8dqnp0qmmcz9jry58jyn9ga82z2pqn6"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "refs" = pkgs.stdenv.mkDerivation { - name = "refs"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-refs.git"; - rev = "f66d3cdf6a6bf4510e5181b3fac215054d8f1e2e"; - sha256 = "1jhc2v784jy8bvkqy4zsh2z7pnqrhwa8n5kx98xhxx73n1bf38sg"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "remotedata" = pkgs.stdenv.mkDerivation { - name = "remotedata"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/krisajenkins/purescript-remotedata.git"; - rev = "cc9932a6c19262d8e4217c534c658a127562c14c"; - sha256 = "1kr4wbsqd3kaf8c4w13m988602qvcm3262v0aij01jrms4p1x92q"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "safe-coerce" = pkgs.stdenv.mkDerivation { - name = "safe-coerce"; - version = "v1.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-safe-coerce.git"; - rev = "e719defd227d932da067a1f0d62a60b3d3ff3637"; - sha256 = "0m942lc23317izspz1sxw957mwl9yb9bgk8dh23f7b3a8w9hh8ff"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "servant-support" = pkgs.stdenv.mkDerivation { - name = "servant-support"; - version = "1fcf4e93723f7f5d36476735b76888938ced871e"; - src = pkgs.fetchgit { - url = "https://github.com/input-output-hk/purescript-servant-support"; - rev = "1fcf4e93723f7f5d36476735b76888938ced871e"; - sha256 = "1p16vp5yfc9xffbmcv7rdg9s1q1nn5mxp6pgyxkz67v527gdj625"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "spec" = pkgs.stdenv.mkDerivation { - name = "spec"; - version = "v5.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-spec/purescript-spec.git"; - rev = "2cfa11573dbb695c117efce0a8f76a3daba12e87"; - sha256 = "0hpca1sa738029ww74zpw31br5x339q35kzb10iqd55lp6611k80"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "spec-quickcheck" = pkgs.stdenv.mkDerivation { - name = "spec-quickcheck"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-spec/purescript-spec-quickcheck.git"; - rev = "c2991f475b8fa11de8b68bcb5895b36be04d1e82"; - sha256 = "01xcbfyqzax9c5najbfy12q0nvfklfm37llj2vkmi3wgkskg4prz"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "st" = pkgs.stdenv.mkDerivation { - name = "st"; - version = "v5.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-st.git"; - rev = "994eb5e650f3caedac385dcc61694f691df57983"; - sha256 = "14hz254f1y0k3v83z719np0ddrgbca0hdsd9dvv244i07vlvm2zj"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "strings" = pkgs.stdenv.mkDerivation { - name = "strings"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-strings.git"; - rev = "157e372a23e4becd594d7e7bff6f372a6f63dd82"; - sha256 = "0hyaa4d8gyyvac2nxnwqkn2rvi5vax4bi4yv10mpk7rgb8rv7mb8"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "tailrec" = pkgs.stdenv.mkDerivation { - name = "tailrec"; - version = "v5.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-tailrec.git"; - rev = "5fbf0ac05dc6ab1a228b2897630195eb7483b962"; - sha256 = "1jjl2q2hyhjcdxpamzr1cdlxhmq2bl170x5p3jajb9zgwkqx0x22"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "these" = pkgs.stdenv.mkDerivation { - name = "these"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-these.git"; - rev = "38dcf86a9bd772091e1153f2f1c13223703599b7"; - sha256 = "0d6yg3lwgralh1kcm5cd4myyz66k9qzld61hc5dg3z92d96zbvlr"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "transformers" = pkgs.stdenv.mkDerivation { - name = "transformers"; - version = "v5.2.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-transformers.git"; - rev = "1e5d4193b38c613c97ea1ebdb721c6b94cd8c50a"; - sha256 = "0lggimnq016v98ib6h68gnciraambxrfqm2s033wm34srcy8xs06"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "tuples" = pkgs.stdenv.mkDerivation { - name = "tuples"; - version = "v6.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-tuples.git"; - rev = "d4fe8ffe9e8c512111ee0bc18a6ba0fd056a6773"; - sha256 = "0s2ar2gih4r34km8r8dqngh21s8899yb93mb7mips08ndy3ajq3a"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "type-equality" = pkgs.stdenv.mkDerivation { - name = "type-equality"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-type-equality.git"; - rev = "f7644468f22ed267a15d398173d234fa6f45e2e0"; - sha256 = "126pg4zg3bsrn8dzvv75xp586nznxyswzgjlr7cag3ij3j1z0kl0"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "typelevel-prelude" = pkgs.stdenv.mkDerivation { - name = "typelevel-prelude"; - version = "v6.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-typelevel-prelude.git"; - rev = "83ddcdb23d06c8d5ea6196596a70438f42cd4afd"; - sha256 = "1vwf3yhn8mir5y41wvlyszkgd5fxvrcyfd0l8cn20c8vfq36yzgk"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "undefinable" = pkgs.stdenv.mkDerivation { - name = "undefinable"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/ethul/purescript-undefinable.git"; - rev = "9c5c863e638b93cf73e2cfde8dfbde91480ee011"; - sha256 = "03z91g1n6zmiqgqqxi65g99a9qxfb8dcnzg2wnb16i2rl8frsl3v"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "unfoldable" = pkgs.stdenv.mkDerivation { - name = "unfoldable"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-unfoldable.git"; - rev = "bbcc2b062b9b7d3d61f123cfb32cc8c7fb811aa6"; - sha256 = "1v3bz04wj6hj7s6mcf49hajylg6w58n78q54sqi2ra2zq8h99kpw"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "unicode" = pkgs.stdenv.mkDerivation { - name = "unicode"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-unicode.git"; - rev = "8e360802e31d080dec7f3ddf4d3329c56773490f"; - sha256 = "0sqvgl3il2rl3zxkbzsqb19wib108zvyw73jxiavpfdm6hdmnxvc"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "unsafe-coerce" = pkgs.stdenv.mkDerivation { - name = "unsafe-coerce"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-unsafe-coerce.git"; - rev = "ee24f0d3b94bf925d9c50fcc2b449579580178c0"; - sha256 = "0l2agnm1k910v4yp1hz19wrsrywsr5scb397762y7pigm3frzs8r"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "unsafe-reference" = pkgs.stdenv.mkDerivation { - name = "unsafe-reference"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-unsafe-reference.git"; - rev = "d4e11a0f291fe8db9855c8bec89fd50b4e48d043"; - sha256 = "103bax2g6g97k868j66rm6658qv6ix1kk3736c0lq1p47raqf3fb"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "uri" = pkgs.stdenv.mkDerivation { - name = "uri"; - version = "v8.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-contrib/purescript-uri.git"; - rev = "d56b9c24933e40b523a0d64e272f3b9f603a1f7c"; - sha256 = "095svp82ik9574klx8s7vjsw34d4psda1hniqnhb75jkycspmqzw"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "uuid" = pkgs.stdenv.mkDerivation { - name = "uuid"; - version = "v8.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/spicydonuts/purescript-uuid.git"; - rev = "b99a5e66235d773cdd45657ff3d3c320ecf3711a"; - sha256 = "0b6swi5xxgjsps70ci2v4mr3yrqrb7gb0smmia0iq2w077j92d89"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "validation" = pkgs.stdenv.mkDerivation { - name = "validation"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript/purescript-validation.git"; - rev = "2d50284b192e71c9ca6aff87747b0d980c1ca657"; - sha256 = "0yfb97nk7179hp0r2iylj74wl7rnl1y2x6dh5hlipxg1kpq9yydk"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-clipboard" = pkgs.stdenv.mkDerivation { - name = "web-clipboard"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-clipboard.git"; - rev = "24f845a888d980d9de78c18f6a67353704429d0d"; - sha256 = "11yrwg8y91aa3r5d375vc9mg5wi5646wl5qhvdcrk839d3nl3xpf"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-common" = pkgs.stdenv.mkDerivation { - name = "web-common"; - version = "v2.0.1"; - src = pkgs.fetchgit { - url = "https://github.com/input-output-hk/purescript-web-common"; - rev = "fa101cd785ef6aa2f7aa908b38c2195aa2c2ff3d"; - sha256 = "0sbngaydgrmn948hyvx1ifdanvph1wchsdmjmvc1b25z2zrdc74q"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-dom" = pkgs.stdenv.mkDerivation { - name = "web-dom"; - version = "v5.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-dom.git"; - rev = "03dfc2f512e124615ab183ade357e3d54007c79d"; - sha256 = "06g9cp9fkzyfwbz5cs0wxjxgdydm9hy7756p2w4vx94myki20hgx"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-events" = pkgs.stdenv.mkDerivation { - name = "web-events"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-events.git"; - rev = "c8a50893f04f54e2a59be7f885d25caef3589c57"; - sha256 = "1dxwrl2r39vazb3g1ka4dkpy6idyi17aq4hf9vvdsmcwf2jjwbn9"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-file" = pkgs.stdenv.mkDerivation { - name = "web-file"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-file.git"; - rev = "3e42263b4392d82c0e379b7a481bbee9b38b1308"; - sha256 = "11x1inhr5pvs2iyg818cywwdskb33q777592sd3b4g4jyczcb1li"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-html" = pkgs.stdenv.mkDerivation { - name = "web-html"; - version = "v3.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-html.git"; - rev = "9e657a0632f7f6514c3d5d2eb4b7dbbfe0d97185"; - sha256 = "007anmqqifrjnpfa4xf7qa8xnpbhvcxqdraj9lnhizwq65vx53sn"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-socket" = pkgs.stdenv.mkDerivation { - name = "web-socket"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-socket.git"; - rev = "28c09f4c8db6bbf4c25f98db7381e42e4e73e349"; - sha256 = "1c5dajc12rfrrskg3q57hxx6cqxz19nigdx4xpjzydq6n2smmmq7"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-storage" = pkgs.stdenv.mkDerivation { - name = "web-storage"; - version = "v4.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-storage.git"; - rev = "22fa56bac204c708e521e746ad4ca2b5810f62c5"; - sha256 = "1viy027k9qyr7mckqkvizwbwkfskc6frppsa1v9a0hq6gc08mpjx"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-touchevents" = pkgs.stdenv.mkDerivation { - name = "web-touchevents"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-touchevents.git"; - rev = "c4a4c41c51bca587c22ed00980ddeca3403c08cd"; - sha256 = "0s5zalrb9i06p8dma9rnci97q10spz3r9fh727sw02r1zzpkdgrk"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-uievents" = pkgs.stdenv.mkDerivation { - name = "web-uievents"; - version = "v3.0.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-uievents.git"; - rev = "cc0fe9095d58a2b5011982e25b31beb4b3626ad6"; - sha256 = "1cb353pcsf8h0sjhk5ljc47xcwgqhwyyfygk5sbr6xgs16y53la2"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - "web-xhr" = pkgs.stdenv.mkDerivation { - name = "web-xhr"; - version = "v4.1.0"; - src = pkgs.fetchgit { - url = "https://github.com/purescript-web/purescript-web-xhr.git"; - rev = "997b87caa6dcdf66b6db22f29f522d722559956b"; - sha256 = "0hzmqga8l24l20kyd98bcpd8bmz7by14vl311m9yfdg5mjkjg42g"; - }; - phases = "installPhase"; - installPhase = "ln -s $src $out"; - }; - - }; - - cpPackage = pkg: - let - target = ".spago/${pkg.name}/${pkg.version}"; - in '' - if [ ! -e ${target} ]; then - echo "Installing ${target}." - mkdir -p ${target} - cp --no-preserve=mode,ownership,timestamp -r ${toString pkg.outPath}/* ${target} - else - echo "${target} already exists. Skipping." - fi - ''; - - getGlob = pkg: ''".spago/${pkg.name}/${pkg.version}/src/**/*.purs"''; - - getStoreGlob = pkg: ''"${pkg.outPath}/src/**/*.purs"''; - -in { - inherit inputs; - - installSpagoStyle = pkgs.writeShellScriptBin "install-spago-style" '' - set -e - echo installing dependencies... - ${builtins.toString (builtins.map cpPackage (builtins.attrValues inputs))} - echo "echo done." - ''; - - buildSpagoStyle = pkgs.writeShellScriptBin "build-spago-style" '' - set -e - echo building project... - purs compile ${builtins.toString (builtins.map getGlob (builtins.attrValues inputs))} "$@" - echo done. - ''; - - buildFromNixStore = pkgs.writeShellScriptBin "build-from-store" '' - set -e - echo building project using sources from nix store... - purs compile ${builtins.toString ( - builtins.map getStoreGlob (builtins.attrValues inputs))} "$@" - echo done. - ''; - - mkBuildProjectOutput = - { src, purs }: - - pkgs.stdenv.mkDerivation { - name = "build-project-output"; - src = src; - - buildInputs = [ purs ]; - - installPhase = '' - mkdir -p $out - purs compile "$src/**/*.purs" ${builtins.toString - (builtins.map - (x: ''"${x.outPath}/src/**/*.purs"'') - (builtins.attrValues inputs))} - mv output $out - ''; - }; -} diff --git a/plutus-playground-client/spago.dhall b/plutus-playground-client/spago.dhall deleted file mode 100644 index e7f29afed5..0000000000 --- a/plutus-playground-client/spago.dhall +++ /dev/null @@ -1,62 +0,0 @@ -{- -Welcome to a Spago project! -You can edit this file as you like. --} -{ name = "plutus-playground-client" -, dependencies = - [ "aff" - , "affjax" - , "argonaut" - , "argonaut-codecs" - , "argonaut-core" - , "arrays" - , "bifunctors" - , "console" - , "control" - , "coroutines" - , "dom-indexed" - , "effect" - , "either" - , "enums" - , "exceptions" - , "foldable-traversable" - , "foreign-object" - , "gen" - , "halogen" - , "http-methods" - , "integers" - , "json-helpers" - , "lists" - , "matryoshka" - , "maybe" - , "media-types" - , "newtype" - , "node-buffer" - , "node-fs" - , "nonempty" - , "ordered-collections" - , "prelude" - , "profunctor-lenses" - , "psci-support" - , "quickcheck" - , "remotedata" - , "servant-support" - , "spec" - , "spec-quickcheck" - , "strings" - , "tailrec" - , "transformers" - , "tuples" - , "uri" - , "web-common" - , "web-events" - , "web-html" - , "web-uievents" - ] -, packages = ../packages.dhall -, sources = - [ "src/**/*.purs" - , "test/**/*.purs" - , "generated/**/*.purs" - ] -} diff --git a/plutus-playground-client/src/Action/Lenses.purs b/plutus-playground-client/src/Action/Lenses.purs deleted file mode 100644 index ce888dea82..0000000000 --- a/plutus-playground-client/src/Action/Lenses.purs +++ /dev/null @@ -1,26 +0,0 @@ -module Action.Lenses - ( _caller - , _blocks - , _InSlot - , _slot - ) where - -import Data.BigInt.Argonaut (BigInt) -import Data.Lens (Iso', Lens', iso) -import Data.Lens.Record (prop) -import Data.Newtype (unwrap, wrap) -import Type.Proxy (Proxy(..)) -import Ledger.Slot (Slot) -import Prelude ((<<<)) - -_caller :: forall r a. Lens' { caller :: a | r } a -_caller = prop (Proxy :: _ "caller") - -_blocks :: forall r a. Lens' { blocks :: a | r } a -_blocks = prop (Proxy :: _ "blocks") - -_InSlot :: Iso' Slot BigInt -_InSlot = iso (_.getSlot <<< unwrap) (wrap <<< { getSlot: _ }) - -_slot :: forall r a. Lens' { slot :: a | r } a -_slot = prop (Proxy :: _ "slot") diff --git a/plutus-playground-client/src/Action/Validation.purs b/plutus-playground-client/src/Action/Validation.purs deleted file mode 100644 index 529f0c9700..0000000000 --- a/plutus-playground-client/src/Action/Validation.purs +++ /dev/null @@ -1,28 +0,0 @@ -module Action.Validation (actionIsValid) where - -import Data.Array as Array -import Data.Lens (view) -import Playground.Types (ContractCall(..), SimulatorWallet) -import Prelude ((==), (&&), (<<<)) -import Schema.Types (FormArgument) -import Validation (isValid) -import Ledger.CardanoWallet (WalletNumber) -import Wallet.Lenses (_simulatorWalletWallet, _walletId) - -actionIsValid :: Array SimulatorWallet -> ContractCall FormArgument -> Boolean -actionIsValid simulatorWallets simulatorAction = actionWalletsExist simulatorAction && isValid simulatorAction - where - walletExists :: WalletNumber -> Boolean - walletExists wallet = - Array.any - (\simulatorWallet -> view _walletId wallet == view (_simulatorWalletWallet <<< _walletId) simulatorWallet) - simulatorWallets - - actionWalletsExist :: ContractCall FormArgument -> Boolean - actionWalletsExist (AddBlocks _) = true -- because there is no wallet to check for in the first place - - actionWalletsExist (AddBlocksUntil _) = true -- ditto - - actionWalletsExist (CallEndpoint { caller }) = walletExists caller - - actionWalletsExist (PayToWallet { sender, recipient }) = walletExists sender && walletExists recipient diff --git a/plutus-playground-client/src/Action/View.purs b/plutus-playground-client/src/Action/View.purs deleted file mode 100644 index e9cc402070..0000000000 --- a/plutus-playground-client/src/Action/View.purs +++ /dev/null @@ -1,268 +0,0 @@ -module Action.View (actionsPane) where - -import Action.Validation (actionIsValid) -import Action.Lenses (_InSlot) -import Bootstrap (btn, card, cardBody_, col, colFormLabel, col_, formCheck, formCheckInline, formCheckInput, formCheckLabel, formControl, formGroup_, formRow_, floatRight) -import Data.Array (mapWithIndex) -import Data.Array as Array -import Data.BigInt.Argonaut (BigInt) -import Data.BigInt.Argonaut as BigInt -import Data.Either (Either(..)) -import Data.Lens (review, view) -import Data.Maybe (Maybe(..), fromMaybe) -import Data.Tuple (Tuple(..)) -import Halogen.HTML (ClassName(ClassName), HTML, IProp, button, div, div_, h2_, h3_, input, label, p_, text) -import Halogen.HTML.Elements.Keyed as Keyed -import Halogen.HTML.Events (onChange, onClick, onDragEnd, onDragEnter, onDragLeave, onDragOver, onDragStart, onDrop, onValueInput) -import Halogen.HTML.Properties (InputType(..), checked, class_, classes, draggable, for, id, min, name, placeholder, required, type_, value) -import Icons (Icon(..), icon) -import MainFrame.Types (DragAndDropEventType(..), HAction(..), SimulatorAction) -import Playground.Lenses (_endpointDescription, _getEndpointDescription) -import Playground.Types (ContractCall(..), SimulatorWallet, _FunctionSchema) -import Ledger.Slot (Slot) -import Prelude (const, one, show, ($), (+), (<$>), (<<<), (<>), (==)) -import Schema.Types (ActionEvent(..), FormArgument, SimulationAction(..)) -import Schema.View (actionArgumentForm) -import Validation (_argument) -import ValueEditor (valueForm) -import Wallet.Lenses (_walletId) -import Wallet.View (walletIdPane) -import Web.Event.Event (Event) -import Web.HTML.Event.DragEvent (DragEvent) - -actionsPane :: forall p. Maybe Int -> Array SimulatorWallet -> Array SimulatorAction -> HTML p HAction -actionsPane actionDrag wallets actions = - div - [ class_ $ ClassName "actions" ] - [ h2_ [ text "Actions" ] - , p_ [ text "This is your action sequence. Click 'Evaluate' to run these actions against a simulated blockchain." ] - , Keyed.div - [ classes $ [ ClassName "action-list" ] - <> - if actionDrag == Nothing then - [] - else - [ ClassName "actions-being-dragged" ] - ] - ( Array.snoc - (mapWithIndex (actionPane actionDrag wallets) actions) - (addWaitActionPane (Array.length actions)) - ) - ] - -actionPane :: forall p. Maybe Int -> Array SimulatorWallet -> Int -> ContractCall FormArgument -> Tuple String (HTML p HAction) -actionPane actionDrag wallets index action = - Tuple (show index) - $ div - ( [ classes - ( [ card - , actionClass - , ClassName ("action-" <> show index) - , ClassName - ( "action-" - <> (if actionIsValid wallets action then "valid-wallet" else "invalid-wallet") - ) - ] - <> - if actionDrag == Just index then - [ ClassName "drag-source" ] - else - [] - ) - ] - <> dragSourceProperties index - <> dragTargetProperties index - ) - [ ChangeSimulation - <$> cardBody_ - [ div - [ class_ $ ClassName "action-label" ] - [ text $ show (index + 1) ] - , button - [ classes [ btn, floatRight, ClassName "close-button" ] - , onClick $ const $ ModifyActions $ RemoveAction index - ] - [ icon Close ] - , actionPaneBody index action - ] - ] - -actionPaneBody :: forall p. Int -> SimulatorAction -> HTML p SimulationAction -actionPaneBody index (CallEndpoint { caller, argumentValues }) = - div_ - [ h3_ - [ walletIdPane caller - , text ": " - , text $ view (_FunctionSchema <<< _endpointDescription <<< _getEndpointDescription) argumentValues - ] - , actionArgumentForm index (PopulateAction index) $ view (_FunctionSchema <<< _argument) argumentValues - ] - -actionPaneBody index (PayToWallet { sender, recipient, amount }) = - div_ - [ h3_ [ walletIdPane sender, text ": Pay To Wallet" ] - , formGroup_ - [ label [ for "recipient" ] [ text "Recipient" ] - , input - [ type_ InputNumber - , classes [ formControl ] - , value $ BigInt.toString $ view _walletId recipient - , required true - , min 1.0 - , placeholder "Wallet ID" - , onBigIntInput $ ModifyActions <<< SetPayToWalletRecipient index <<< review _walletId - ] - ] - , formGroup_ - [ label [ for "amount" ] [ text "Amount" ] - , valueForm (ModifyActions <<< SetPayToWalletValue index) amount - ] - ] - -actionPaneBody index (AddBlocks { blocks }) = - div_ - [ h3_ [ text "Wait" ] - , waitTypeRadioInputs index (Right blocks) - , formGroup_ - [ formRow_ - [ label [ classes [ col, colFormLabel ] ] - [ text "Slots" ] - , col_ - [ input - [ type_ InputNumber - , classes [ formControl, ClassName $ "action-argument-0-blocks" ] - , value $ BigInt.toString blocks - , required true - , min 1.0 - , placeholder "Block Number" - , onBigIntInput $ ModifyActions <<< SetWaitTime index - ] - ] - ] - ] - ] - -actionPaneBody index (AddBlocksUntil { slot }) = - div_ - [ h3_ [ text "Wait" ] - , waitTypeRadioInputs index (Left slot) - , formGroup_ - [ formRow_ - [ label [ classes [ col, colFormLabel ] ] - [ text "Slot" ] - , col_ - [ input - [ type_ InputNumber - , classes [ formControl, ClassName $ "action-argument-0-until-slot" ] - , value $ BigInt.toString $ view _InSlot slot - , required true - , min 1.0 - , placeholder "Slot Number" - , onBigIntInput $ ModifyActions <<< SetWaitUntilTime index <<< review _InSlot - ] - ] - ] - ] - ] - -waitTypeRadioInputs :: forall p. Int -> Either Slot BigInt -> HTML p SimulationAction -waitTypeRadioInputs index wait = - div - [ class_ $ ClassName "wait-type-options" ] - [ div - [ classes [ formCheck, formCheckInline ] ] - [ input - ( case wait of - Left slot -> baseInputProps <> [ id waitForId, onChange $ const $ ModifyActions $ SetWaitTime index $ view _InSlot slot ] - Right _ -> baseInputProps <> [ id waitForId, checked true ] - ) - , label - [ class_ formCheckLabel - , for waitForId - ] - [ text "Wait For…" ] - ] - , div - [ classes [ formCheck, formCheckInline ] ] - [ input - ( case wait of - Right blocks -> baseInputProps <> [ id waitUntilId, onChange $ const $ ModifyActions $ SetWaitUntilTime index $ review _InSlot blocks ] - Left _ -> baseInputProps <> [ id waitForId, checked true ] - ) - , label - [ class_ formCheckLabel - , for waitUntilId - ] - [ text "Wait Until…" ] - ] - ] - where - baseInputProps = [ type_ InputRadio, class_ formCheckInput, name $ "wait-" <> show index ] - - waitForId = "wait-for-" <> show index - - waitUntilId = "wait-until-" <> show index - -addWaitActionPane :: forall p. Int -> Tuple String (HTML p HAction) -addWaitActionPane index = - Tuple "add-wait" - $ div - [ classes [ actionClass, ClassName "add-wait-action" ] ] - [ div - ( [ class_ card - , onClick $ const $ ChangeSimulation $ ModifyActions $ AddWaitAction $ BigInt.fromInt 10 - ] - <> dragTargetProperties index - ) - [ cardBody_ - [ icon Plus - , div_ [ text "Add Wait Action" ] - ] - ] - ] - ------------------------------------------------------------- -dragSourceProperties - :: forall i - . Int - -> Array - ( IProp - ( draggable :: Boolean - , onDragStart :: DragEvent - , onDragEnd :: DragEvent - | i - ) - HAction - ) -dragSourceProperties index = - [ draggable true - , onDragStart $ ActionDragAndDrop index DragStart - , onDragEnd $ ActionDragAndDrop index DragEnd - ] - -dragTargetProperties - :: forall i - . Int - -> Array - ( IProp - ( onDragEnter :: DragEvent - , onDragOver :: DragEvent - , onDragLeave :: DragEvent - , onDrop :: DragEvent - | i - ) - HAction - ) -dragTargetProperties index = - [ onDragEnter $ ActionDragAndDrop index DragEnter - , onDragOver $ ActionDragAndDrop index DragOver - , onDragLeave $ ActionDragAndDrop index DragLeave - , onDrop $ ActionDragAndDrop index Drop - ] - --- defaults to 1 because all the BigInt fields here have a minimum value of 1 -onBigIntInput :: forall i r. (BigInt -> i) -> IProp (onInput :: Event, value :: String | r) i -onBigIntInput f = onValueInput $ f <<< fromMaybe one <<< BigInt.fromString - -actionClass :: ClassName -actionClass = ClassName "action" diff --git a/plutus-playground-client/src/Chain/State.purs b/plutus-playground-client/src/Chain/State.purs deleted file mode 100644 index 8675f27c36..0000000000 --- a/plutus-playground-client/src/Chain/State.purs +++ /dev/null @@ -1,34 +0,0 @@ -module Chain.State (handleAction) where - -import Chain.Types (Action(..), AnnotatedBlockchain, State, _chainFocus, _chainFocusAge, _findTx, _sequenceId) -import Clipboard (class MonadClipboard) -import Clipboard as Clipboard -import Control.Monad.State.Trans (class MonadState) -import Data.Lens (assign, preview, use) -import Data.Maybe (Maybe, fromMaybe) -import Plutus.V1.Ledger.Tx (TxId) -import Prelude (Ordering(..), Unit, bind, compare, discard, pure, ($), (<<<), (<>)) -import Wallet.Rollup.Types (SequenceId(..)) - -handleAction :: forall m. MonadClipboard m => MonadState State m => Action -> Maybe AnnotatedBlockchain -> m Unit -handleAction (FocusTx newFocus) mAnnotatedBlockchain = do - oldFocus <- use _chainFocus - let - relativeAge = - fromMaybe EQ - $ do - annotatedBlockchain <- mAnnotatedBlockchain - oldFocusTxId :: TxId <- oldFocus - newFocusTxId :: TxId <- newFocus - oldFocusSequenceId :: SequenceId <- preview (_findTx oldFocusTxId <<< _sequenceId) annotatedBlockchain - newFocusSequenceId :: SequenceId <- preview (_findTx newFocusTxId <<< _sequenceId) annotatedBlockchain - pure $ compareSequenceIds oldFocusSequenceId newFocusSequenceId - -- Update. - assign _chainFocus newFocus - assign _chainFocusAge relativeAge - where - compareSequenceIds (SequenceId old) (SequenceId new) = - compare old.slotIndex new.slotIndex - <> compare old.txIndex new.txIndex - -handleAction (ClipboardAction subaction) _ = Clipboard.handleAction subaction diff --git a/plutus-playground-client/src/Chain/Types.purs b/plutus-playground-client/src/Chain/Types.purs deleted file mode 100644 index 53d3d8c3c2..0000000000 --- a/plutus-playground-client/src/Chain/Types.purs +++ /dev/null @@ -1,137 +0,0 @@ -module Chain.Types where - -import Prologue -import Clipboard (Action) as Clipboard -import Data.BigInt.Argonaut (BigInt) -import Data.Generic.Rep (class Generic) -import Data.Show.Generic (genericShow) -import Data.Lens (Fold', Iso', Lens', Prism', Traversal', filtered, prism', traversed) -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Data.Map (Map) -import Data.Newtype (class Newtype) -import Type.Proxy (Proxy(..)) -import Ledger.Address (PaymentPubKeyHash(..)) -import Plutus.V1.Ledger.Address (Address(..)) -import Plutus.V1.Ledger.Credential (Credential(..)) -import Ledger.Crypto (PubKey, Signature) -import Plutus.V1.Ledger.Interval (Interval) -import Ledger.Slot (Slot) -import Ledger.Tx.Internal (Tx, TxInput, TxIn, TxOut(..)) -import Plutus.V1.Ledger.Tx (TxId, TxOutRef) -import Cardano.Api.TxBody as C -import Plutus.V1.Ledger.Value (Value) -import Wallet.Rollup.Types (AnnotatedTx(..), BeneficialOwner(..), DereferencedInput, SequenceId, TxKey, _TxKey) - -data Action - = FocusTx (Maybe TxId) - | ClipboardAction Clipboard.Action - -derive instance genericChainFocus :: Generic Action _ - -instance showChainFocus :: Show Action where - show = genericShow - -_FocusTx :: Prism' Action TxId -_FocusTx = prism' set get - where - get (FocusTx txId) = txId - - get _ = Nothing - - set = FocusTx <<< Just - -newtype AnnotatedBlockchain = AnnotatedBlockchain (Array (Array AnnotatedTx)) - -derive instance newtypeAnnotatedBlockchain :: Newtype AnnotatedBlockchain _ - -_AnnotatedBlockchain :: Iso' AnnotatedBlockchain (Array (Array AnnotatedTx)) -_AnnotatedBlockchain = _Newtype - -_AnnotatedBlocks :: Traversal' AnnotatedBlockchain AnnotatedTx -_AnnotatedBlocks = _AnnotatedBlockchain <<< traversed <<< traversed - -type State = - { chainFocus :: Maybe TxId - , chainFocusAppearing :: Boolean - , chainFocusAge :: Ordering - } - -initialState :: State -initialState = - { chainFocus: Nothing - , chainFocusAppearing: false - , chainFocusAge: EQ - } - -_chainFocus :: forall r a. Lens' { chainFocus :: a | r } a -_chainFocus = prop (Proxy :: _ "chainFocus") - -_chainFocusAppearing :: forall r a. Lens' { chainFocusAppearing :: a | r } a -_chainFocusAppearing = prop (Proxy :: _ "chainFocusAppearing") - -_chainFocusAge :: forall r a. Lens' { chainFocusAge :: a | r } a -_chainFocusAge = prop (Proxy :: _ "chainFocusAge") - -_sequenceId :: Lens' AnnotatedTx SequenceId -_sequenceId = _Newtype <<< prop (Proxy :: _ "sequenceId") - -_dereferencedInputs :: Lens' AnnotatedTx (Array DereferencedInput) -_dereferencedInputs = _Newtype <<< prop (Proxy :: _ "dereferencedInputs") - -_value :: forall s a r. Newtype s { getValue :: a | r } => Lens' s a -_value = _Newtype <<< prop (Proxy :: _ "getValue") - -_txIdOf :: Lens' AnnotatedTx TxId -_txIdOf = _Newtype <<< prop (Proxy :: _ "txId") - -_balances :: Lens' AnnotatedTx (Map BeneficialOwner Value) -_balances = _Newtype <<< prop (Proxy :: _ "balances") - -_txFee :: Lens' Tx Value -_txFee = _Newtype <<< prop (Proxy :: _ "txFee") - -_txMint :: Lens' Tx Value -_txMint = _Newtype <<< prop (Proxy :: _ "txMint") - -_txValidRange :: Lens' Tx (Interval Slot) -_txValidRange = _Newtype <<< prop (Proxy :: _ "txValidRange") - -_txSignatures :: Lens' Tx (Map PubKey Signature) -_txSignatures = _Newtype <<< prop (Proxy :: _ "txSignatures") - -_txInputs :: Lens' Tx (Array TxInput) -_txInputs = _Newtype <<< prop (Proxy :: _ "txInputs") - -_txOutputs :: Lens' Tx (Array TxOut) -_txOutputs = _Newtype <<< prop (Proxy :: _ "txOutputs") - -_txInRef :: Lens' TxIn TxOutRef -_txInRef = _Newtype <<< prop (Proxy :: _ "txInRef") - -_txInputRef :: Lens' TxInput TxOutRef -_txInputRef = _Newtype <<< prop (Proxy :: _ "txInputRef") - -_txOutRefId :: Lens' TxOutRef TxId -_txOutRefId = _Newtype <<< prop (Proxy :: _ "txOutRefId") - -_txKeyTxId :: Lens' TxKey TxId -_txKeyTxId = _TxKey <<< prop (Proxy :: _ "_txKeyTxId") - -_txKeyTxOutRefIdx :: Lens' TxKey BigInt -_txKeyTxOutRefIdx = _TxKey <<< prop (Proxy :: _ "_txKeyTxOutRefIdx") - -toBeneficialOwner :: TxOut -> BeneficialOwner -toBeneficialOwner (TxOut { getTxOut: C.TxOut { txOutAddress } }) = - let - Address { addressCredential } = txOutAddress - in - case addressCredential of - PubKeyCredential pkh -> OwnedByPaymentPubKey $ PaymentPubKeyHash { unPaymentPubKeyHash: pkh } - ScriptCredential vh -> OwnedByScript vh - -_findTx :: forall m. Monoid m => TxId -> Fold' m AnnotatedBlockchain AnnotatedTx -_findTx focussedTxId = (_AnnotatedBlocks <<< filtered isAnnotationOf) - where - isAnnotationOf :: AnnotatedTx -> Boolean - isAnnotationOf (AnnotatedTx { txId }) = txId == focussedTxId diff --git a/plutus-playground-client/src/Chain/View.purs b/plutus-playground-client/src/Chain/View.purs deleted file mode 100644 index abf03e0f51..0000000000 --- a/plutus-playground-client/src/Chain/View.purs +++ /dev/null @@ -1,382 +0,0 @@ -module Chain.View - ( chainView - , txOutOfView - ) where - -import Chain.Types -import Animation (animationClass) -import Bootstrap (active, card, cardBody_, cardFooter_, cardHeader, cardHeader_, col, col3_, col6_, colLg2, colMd3, colSm6, colXs12, col_, empty, nbsp, row, row_, tableBordered, tableSmall, textTruncate) -import Bootstrap as Bootstrap -import Bootstrap.Extra (clickable) -import Cardano.Api.TxBody as C -import Clipboard (showShortCopyLong) -import Data.Array ((:)) -import Data.Array as Array -import Data.BigInt.Argonaut (BigInt) -import Data.BigInt.Argonaut as BigInt -import Data.Foldable (foldMap, foldr) -import Data.Foldable.Extra (interleave) -import Data.FoldableWithIndex (foldMapWithIndex, foldrWithIndex) -import Data.Lens (Traversal', _Just, filtered, has, preview, view) -import Data.Lens.Index (ix) -import Data.Map (Map) -import Data.Map as Map -import Data.Maybe (Maybe(..), fromMaybe) -import Data.Newtype (unwrap) -import Data.Set (Set) -import Data.Set as Set -import Data.String.Extra (abbreviate) -import Data.Tuple.Nested ((/\)) -import Halogen.HTML (ClassName(..), HTML, IProp, br_, div, div_, h2_, hr_, p_, small_, span_, strong_, table, tbody_, td, text, th, th_, thead_, tr, tr_) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (class_, classes, colSpan, rowSpan) -import PlutusTx.AssocMap as AssocMap -import Plutus.V1.Ledger.Crypto (PubKeyHash(..)) -import Ledger.Address (PaymentPubKeyHash(..)) -import Ledger.Tx.Internal (TxOut(..)) -import Plutus.V1.Ledger.Tx (TxId(..)) -import Plutus.V1.Ledger.Value (CurrencySymbol(..), TokenName(..), Value(..)) -import Prologue (Ordering(..), Tuple, const, eq, show, zero, ($), (<$>), (<<<), (<>)) -import Wallet.Rollup.Types (AnnotatedTx(..), BeneficialOwner(..), DereferencedInput(..), SequenceId(..)) -import Web.UIEvent.MouseEvent (MouseEvent) - -type NamingFn = PubKeyHash -> Maybe String - -chainView :: forall p. NamingFn -> State -> AnnotatedBlockchain -> HTML p Action -chainView namingFn state annotatedBlockchain = - div - [ classes - ( [ ClassName "chain" ] - <> animationClass _chainFocusAppearing state - <> case state.chainFocusAge of - LT -> [ ClassName "chain-focus-newer" ] - EQ -> [] - GT -> [ ClassName "chain-focus-older" ] - ) - ] - [ h2_ - [ text "Blockchain" ] - , p_ - [ text "Click a transaction for details" ] - , div - [ classes [ row, ClassName "blocks" ] ] - (chainSlotView state <$> Array.reverse (unwrap annotatedBlockchain)) - , detailView namingFn state annotatedBlockchain - ] - -slotClass :: ClassName -slotClass = ClassName "slot" - -notFoundClass :: ClassName -notFoundClass = ClassName "not-found" - -amountClass :: ClassName -amountClass = ClassName "amount" - -chainSlotView :: forall p. State -> Array AnnotatedTx -> HTML p Action -chainSlotView _ [] = empty - -chainSlotView state chainSlot = - div [ classes [ colXs12, colSm6, colMd3, colLg2, slotClass ] ] - (blockView state <$> chainSlot) - -blockView :: forall p. State -> AnnotatedTx -> HTML p Action -blockView state (AnnotatedTx { txId, sequenceId }) = - div - [ classes ([ card, clickable, ClassName "transaction" ] <> if isActive then [ active ] else []) - , onClickFocusTx txId - ] - [ entryCardHeader sequenceId false ] - where - isActive = has (_chainFocus <<< _Just <<< filtered (eq txId)) state - -detailView :: forall p. NamingFn -> State -> AnnotatedBlockchain -> HTML p Action -detailView namingFn { chainFocus: Just focussedTxId } annotatedBlockchain = case preview (_findTx focussedTxId) annotatedBlockchain of - Just annotatedTx -> transactionDetailView namingFn annotatedBlockchain annotatedTx - Nothing -> empty - -detailView _ { chainFocus: Nothing } _ = empty - -transactionDetailView :: forall p. NamingFn -> AnnotatedBlockchain -> AnnotatedTx -> HTML p Action -transactionDetailView namingFn annotatedBlockchain annotatedTx = - div - [ class_ $ ClassName "detail" ] - [ div - [ classes [ row, ClassName "transaction" ] ] - [ col3_ - [ h2_ [ text "Inputs" ] - , div_ (dereferencedInputView namingFn annotatedBlockchain <$> (view _dereferencedInputs annotatedTx)) - ] - , col6_ - [ h2_ [ text "Transaction" ] - , div [ classes [ card, active ] ] - [ entryCardHeader (view _sequenceId annotatedTx) true - , cardBody_ - [ div - [ class_ textTruncate ] - [ txIdView (view _txIdOf annotatedTx) ] - , div [ class_ textTruncate ] [] - , div [ class_ textTruncate ] [] - ] - ] - ] - ] - , balancesTable - namingFn - (view _sequenceId annotatedTx) - (view _balances annotatedTx) - ] - -entryCardHeader :: forall i p. SequenceId -> Boolean -> HTML p i -entryCardHeader sequenceId withTriangle = - cardHeader_ - if withTriangle then - [ triangleRight, sequenceIdView sequenceId ] - else - [ sequenceIdView sequenceId ] - -entryClass :: ClassName -entryClass = ClassName "entry" - -triangleRight :: forall p i. HTML p i -triangleRight = div [ class_ $ ClassName "triangle-right" ] [] - -balancesTable :: forall p. NamingFn -> SequenceId -> Map BeneficialOwner Value -> HTML p Action -balancesTable namingFn sequenceId balances = - div - [ class_ $ ClassName "balances" ] - [ h2_ - [ text "Balances Carried Forward" - , nbsp - , small_ - [ text "(as at " - , sequenceIdView sequenceId - , text ")" - ] - ] - , table - [ classes - [ Bootstrap.table - , tableBordered - , tableSmall - , ClassName "balances-table" - ] - ] - [ thead_ - [ tr_ - ( th [ rowSpan 2 ] [ text "Beneficial Owner" ] - : foldMapWithIndex - ( \currency s -> - [ th - [ colSpan (Set.size s) - , class_ textTruncate - ] - [ let - formatted = showCurrency currency - in - ClipboardAction - <$> showShortCopyLong - formatted - (Just [ text $ abbreviate 15 formatted ]) - ] - ] - ) - headings - ) - , tr_ - (foldMap (foldMap tokenHeadingView) headings) - ] - , tbody_ - ( foldMap - ( \owner -> - [ tr [ class_ $ beneficialOwnerClass owner ] - ( th_ - [ beneficialOwnerView namingFn owner ] - : foldMapWithIndex - ( \currency -> - foldMap - ( \token -> - let - _thisBalance :: Traversal' (Map BeneficialOwner Value) BigInt - _thisBalance = ix owner <<< _value <<< ix currency <<< ix token - - amount :: Maybe BigInt - amount = preview _thisBalance balances - in - [ td [ class_ amountClass ] - [ text $ formatAmount $ fromMaybe zero amount ] - ] - ) - ) - headings - ) - ] - ) - (Map.keys balances) - ) - ] - ] - where - headings :: Map CurrencySymbol (Set TokenName) - headings = collectBalanceTableHeadings balances - - tokenHeadingView :: forall i. TokenName -> Array (HTML p i) - tokenHeadingView token = [ th_ [ showToken token ] ] - -collectBalanceTableHeadings :: Map BeneficialOwner Value -> Map CurrencySymbol (Set TokenName) -collectBalanceTableHeadings balances = foldr collectCurrencies Map.empty $ Map.values balances - where - collectCurrencies :: Value -> Map CurrencySymbol (Set TokenName) -> Map CurrencySymbol (Set TokenName) - collectCurrencies (Value { getValue: entries }) ownersBalance = foldrWithIndex collectTokenNames ownersBalance entries - - collectTokenNames :: CurrencySymbol -> AssocMap.Map TokenName BigInt -> Map CurrencySymbol (Set TokenName) -> Map CurrencySymbol (Set TokenName) - collectTokenNames currency currencyBalances = Map.insertWith Set.union currency $ AssocMap.keys currencyBalances - -sequenceIdView :: forall p i. SequenceId -> HTML p i -sequenceIdView (SequenceId { slotIndex, txIndex }) = - span_ - [ span_ [ text "Slot" ] - , nbsp - , span_ [ text $ show slotIndex ] - , span_ [ text ", " ] - , span_ [ text "Tx" ] - , nbsp - , span_ [ text $ show txIndex ] - ] - -txIdView :: forall p. TxId -> HTML p Action -txIdView (TxId { getTxId: str }) = - ClipboardAction - <$> showShortCopyLong - str - ( Just - [ strong_ [ text "Tx: " ] - , nbsp - , text str - ] - ) - -dereferencedInputView :: forall p. NamingFn -> AnnotatedBlockchain -> DereferencedInput -> HTML p Action -dereferencedInputView namingFn annotatedBlockchain (DereferencedInput { originalInput, refersTo }) = - txOutOfView namingFn true refersTo - $ case originatingTx of - Just tx -> - Just - $ div - [ class_ clickable - , onClickFocusTx txId - ] - [ text "Created by:", nbsp, sequenceIdView (view _sequenceId tx) ] - Nothing -> Nothing - where - txId :: TxId - txId = view (_txInRef <<< _txOutRefId) originalInput - - originatingTx :: Maybe AnnotatedTx - originatingTx = preview (_findTx txId) annotatedBlockchain - -dereferencedInputView _ _ (InputNotFound txKey) = - div - [ classes [ card, entryClass, notFoundClass ] ] - [ div [ classes [ cardHeader, textTruncate ] ] - [ text "Input Not Found" ] - , cardBody_ - [ txIdView (view _txKeyTxId txKey) - , br_ - , text $ "Index: " <> BigInt.toString (view _txKeyTxOutRefIdx txKey) - ] - ] - -txOutOfView :: forall p. NamingFn -> Boolean -> TxOut -> Maybe (HTML p Action) -> HTML p Action -txOutOfView namingFn showArrow txOut@(TxOut { getTxOut: C.TxOut { txOutValue } }) mFooter = - div - [ classes [ card, entryClass, beneficialOwnerClass beneficialOwner ] ] - [ div [ classes [ cardHeader, textTruncate ] ] - [ if showArrow then triangleRight else empty - , beneficialOwnerView namingFn beneficialOwner - ] - , cardBody_ - [ valueView txOutValue ] - , case mFooter of - Nothing -> empty - Just footer -> cardFooter_ [ footer ] - ] - where - beneficialOwner = toBeneficialOwner txOut - -beneficialOwnerClass :: BeneficialOwner -> ClassName -beneficialOwnerClass (OwnedByPaymentPubKey _) = ClassName "wallet" - -beneficialOwnerClass (OwnedByScript _) = ClassName "script" - -beneficialOwnerView :: forall p. NamingFn -> BeneficialOwner -> HTML p Action -beneficialOwnerView namingFn (OwnedByPaymentPubKey (PaymentPubKeyHash { unPaymentPubKeyHash: pubKeyHash })) = case namingFn pubKeyHash of - Nothing -> showPubKeyHash pubKeyHash - Just name -> - span_ - [ span_ [ text name ] - , br_ - , small_ [ showPubKeyHash pubKeyHash ] - ] - -beneficialOwnerView _ (OwnedByScript a) = - ClipboardAction - <$> showShortCopyLong a - ( Just - [ text "Script" - , nbsp - , text a - ] - ) - -showPubKeyHash :: forall p. PubKeyHash -> HTML p Action -showPubKeyHash (PubKeyHash { getPubKeyHash: p }) = - ClipboardAction - <$> showShortCopyLong p - ( Just - [ text "PubKeyHash" - , nbsp - , text p - ] - ) - -valueView :: forall p i. Value -> HTML p i -valueView (Value { getValue: (AssocMap.Map []) }) = empty - -valueView (Value { getValue: (AssocMap.Map currencies) }) = div_ (interleave hr_ (currencyView <$> currencies)) - where - currencyView :: Tuple CurrencySymbol (AssocMap.Map TokenName BigInt) -> HTML p i - currencyView (currency /\ (AssocMap.Map tokens)) = - div_ - [ div [ class_ Bootstrap.textTruncate ] - [ strong_ [ text $ showCurrency currency ] ] - , div_ (tokenView <$> tokens) - ] - - tokenView :: Tuple TokenName BigInt -> HTML p i - tokenView (token /\ amount) = - row_ - [ col_ [ showToken token ] - , div [ classes [ col, amountClass ] ] - [ text $ formatAmount amount ] - ] - -formatAmount :: BigInt -> String -formatAmount = BigInt.toString - -showCurrency :: CurrencySymbol -> String -showCurrency (CurrencySymbol { unCurrencySymbol: "" }) = "Ada" - -showCurrency (CurrencySymbol { unCurrencySymbol: symbol }) = symbol - -showToken :: forall p i. TokenName -> HTML p i -showToken (TokenName { unTokenName: "" }) = text "Lovelace" - -showToken (TokenName { unTokenName: name }) = text name - -onClickFocusTx :: forall p. TxId -> IProp (onClick :: MouseEvent | p) Action -onClickFocusTx txId = - onClick - $ const - $ FocusTx - $ Just txId diff --git a/plutus-playground-client/src/Component/ErrorPane.purs b/plutus-playground-client/src/Component/ErrorPane.purs deleted file mode 100644 index 454b949c91..0000000000 --- a/plutus-playground-client/src/Component/ErrorPane.purs +++ /dev/null @@ -1,46 +0,0 @@ -module Component.ErrorPane where - -import Prelude hiding (div) - -import Bootstrap (alertDanger_, btn, floatRight) -import Halogen (RefLabel(RefLabel)) -import Halogen.HTML (ClassName(..), HTML, br_, button, div, p_, text) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (class_, classes, ref) -import Icons (Icon(..), icon) - -data ErrorPaneAction = CloseErrorPane - -errorPane :: forall p i. String -> HTML p i -errorPane error = - div - [ class_ errorClass - , ref errorRefLabel - ] - [ alertDanger_ - [ text error - , br_ - , text "Please try again or contact support for assistance." - ] - ] - -closeableErrorPane - :: forall p. String -> HTML p ErrorPaneAction -closeableErrorPane error = - div - [ class_ errorClass ] - [ alertDanger_ - [ button - [ classes [ btn, floatRight, ClassName "ajax-error-close-button" ] - , onClick $ const $ CloseErrorPane - ] - [ icon Close ] - , p_ [ text error ] - ] - ] - -errorRefLabel :: RefLabel -errorRefLabel = RefLabel "ajax-error" - -errorClass :: ClassName -errorClass = ClassName "ajax-error" diff --git a/plutus-playground-client/src/Cursor.purs b/plutus-playground-client/src/Cursor.purs deleted file mode 100644 index 10cefe834f..0000000000 --- a/plutus-playground-client/src/Cursor.purs +++ /dev/null @@ -1,146 +0,0 @@ --- | A cursor is an Array with a pointer to the 'current' item, plus --- some guarantees* that you cannot get into an invalid state. --- --- * Mostly guaranteed by using smart constructors and judicious exports. -module Cursor - ( Cursor - , current - , first - , last - , empty - , singleton - , snoc - , deleteAt - , fromArray - , toArray - , mapWithIndex - , null - , length - , _current - , setIndex - , getIndex - , left - , right - ) where - -import Prologue hiding (clamp) -import Control.Monad.Gen.Class (chooseInt) -import Data.Array as Array -import Data.Argonaut.Decode (class DecodeJson, decodeJson) -import Data.Argonaut.Encode (class EncodeJson, encodeJson) -import Data.Foldable (class Foldable, foldMap, foldl, foldr) -import Data.Lens.AffineTraversal (AffineTraversal', affineTraversal) -import Data.Lens.Index (class Index) -import Data.Maybe (fromMaybe, maybe) -import Data.Ord as Ord -import Data.Traversable (class Traversable, sequenceDefault, traverse) -import Data.Tuple (uncurry) -import Test.QuickCheck.Arbitrary (class Arbitrary, arbitrary) -import Test.QuickCheck.Gen (arrayOf) - -data Cursor a = Cursor Int (Array a) - -derive instance eqCursor :: Eq a => Eq (Cursor a) - -derive instance ordCursor :: Ord a => Ord (Cursor a) - -derive instance functorCursor :: Functor Cursor - -instance foldableCursor :: Foldable Cursor where - foldr f acc (Cursor _ xs) = foldr f acc xs - foldl f acc (Cursor _ xs) = foldl f acc xs - foldMap f (Cursor _ xs) = foldMap f xs - -instance traversableCursor :: Traversable Cursor where - traverse f (Cursor n xs) = Cursor n <$> traverse f xs - sequence = sequenceDefault - -instance showCursor :: Show a => Show (Cursor a) where - show (Cursor index xs) = "Cursor " <> show index <> " " <> show xs - -instance arbitraryCursor :: Arbitrary a => Arbitrary (Cursor a) where - arbitrary = do - xs <- arrayOf arbitrary - index <- chooseInt 0 (Array.length xs - 1) - pure $ Cursor index xs - -instance indexCursor :: Index (Cursor a) Int a where - ix n = affineTraversal set pre - where - set c@(Cursor index xs) a = fromMaybe c $ Cursor index <$> Array.updateAt n a xs - - pre c@(Cursor _ xs) = maybe (Left c) Right $ Array.index xs n - -instance encodeCursor :: EncodeJson a => EncodeJson (Cursor a) where - encodeJson (Cursor n xs) = encodeJson [ encodeJson n, encodeJson xs ] - -instance decodeCursor :: DecodeJson a => DecodeJson (Cursor a) where - decodeJson value = uncurry Cursor <$> decodeJson value - -_current :: forall a. AffineTraversal' (Cursor a) a -_current = affineTraversal set pre - where - set (Cursor index xs) a = Cursor index $ fromMaybe xs $ Array.updateAt index a xs - - pre c@(Cursor index xs) = maybe (Left c) Right $ Array.index xs index - -clamp :: forall a. Cursor a -> Cursor a -clamp (Cursor index xs) = - Cursor - (Ord.clamp 0 (Array.length xs - 1) index) - xs - -empty :: forall a. Cursor a -empty = fromArray [] - -singleton :: forall a. a -> Cursor a -singleton = fromArray <<< Array.singleton - -snoc :: forall a. Cursor a -> a -> Cursor a -snoc (Cursor index xs) x = last $ Cursor index (Array.snoc xs x) - -deleteAt :: forall a. Int -> Cursor a -> Cursor a -deleteAt n cursor@(Cursor index xs) = - fromMaybe cursor do - let - newIndex - | n >= index = index - | otherwise = index - 1 - newXs <- Array.deleteAt n xs - pure $ clamp $ Cursor newIndex newXs - -fromArray :: forall a. Array a -> Cursor a -fromArray xs = Cursor 0 xs - -toArray :: forall a. Cursor a -> Array a -toArray (Cursor _ xs) = xs - -mapWithIndex :: forall b a. (Int -> a -> b) -> Cursor a -> Cursor b -mapWithIndex f (Cursor index xs) = Cursor index (Array.mapWithIndex f xs) - -null :: forall a. Cursor a -> Boolean -null (Cursor _ xs) = Array.null xs - -length :: forall a. Cursor a -> Int -length (Cursor _ xs) = Array.length xs - -current :: forall a. Cursor a -> Maybe a -current (Cursor index xs) = Array.index xs index - -getIndex :: forall a. Cursor a -> Int -getIndex (Cursor index _) = index - -setIndex :: forall a. Int -> Cursor a -> Cursor a -setIndex newIndex (Cursor _ xs) = clamp $ Cursor newIndex xs - -left :: forall a. Cursor a -> Cursor a -left (Cursor index xs) = clamp $ Cursor (index - 1) xs - -right :: forall a. Cursor a -> Cursor a -right (Cursor index xs) = clamp $ Cursor (index + 1) xs - -first :: forall a. Cursor a -> Cursor a -first (Cursor _ xs) = Cursor 0 xs - -last :: forall a. Cursor a -> Cursor a -last (Cursor _ xs) = Cursor (Array.length xs - 1) xs diff --git a/plutus-playground-client/src/Data/Functor/Foldable.purs b/plutus-playground-client/src/Data/Functor/Foldable.purs deleted file mode 100644 index 54adb222f9..0000000000 --- a/plutus-playground-client/src/Data/Functor/Foldable.purs +++ /dev/null @@ -1,38 +0,0 @@ -module Data.Functor.Foldable where - -import Prologue -import Data.Argonaut.Decode (class DecodeJson, decodeJson) -import Data.Argonaut.Encode (class EncodeJson, encodeJson) -import Data.Eq (class Eq1) -import Data.Generic.Rep (class Generic) -import Data.Show.Generic (genericShow) -import Data.Newtype (class Newtype) -import Matryoshka (class Corecursive, class Recursive) -import Schema (FormArgumentF) - --- | This recursive type is isomorphic to `Data.Functor.Mu.Mu`, and --- only exists because we want `Encode`/`Decode` instances. -newtype Fix f = Fix (f (Fix f)) - -derive instance newtypeFix :: Newtype (Fix f) _ - -derive instance genericFix :: Generic (Fix f) _ - -derive instance eqFix :: Eq1 f => Eq (Fix f) - -instance recursiveFix :: Functor f => Recursive (Fix f) f where - project (Fix v) = v - -instance corecursiveFix :: Functor f => Corecursive (Fix f) f where - embed v = Fix v - ------------------------------------------------------------- -instance encodeJsonFixFormArgumentF :: EncodeJson (Fix FormArgumentF) where - encodeJson (Fix f) = encodeJson f - -instance decodeJsonFixFormArgumentF :: DecodeJson (Fix FormArgumentF) where - decodeJson json = Fix <$> decodeJson json - --- -instance showFix :: Show (Fix FormArgumentF) where - show value = genericShow value diff --git a/plutus-playground-client/src/Editor/Lenses.purs b/plutus-playground-client/src/Editor/Lenses.purs deleted file mode 100644 index 2981329b91..0000000000 --- a/plutus-playground-client/src/Editor/Lenses.purs +++ /dev/null @@ -1,44 +0,0 @@ -module Editor.Lenses - ( _warnings - , _keyBindings - , _feedbackPaneMinimised - , _lastCompiledCode - , _currentCodeIsCompiled - , _feedbackPaneDragStart - , _feedbackPaneExtend - , _feedbackPanePreviousExtend - ) where - -import Data.Lens (Lens') -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Data.Maybe (Maybe) -import Type.Proxy (Proxy(..)) -import Editor.Types (State) -import Halogen.Monaco (KeyBindings) -import Language.Haskell.Interpreter (SourceCode) -import Prelude ((<<<)) - -_warnings :: forall s a. Lens' { warnings :: a | s } a -_warnings = prop (Proxy :: _ "warnings") - -_keyBindings :: Lens' State KeyBindings -_keyBindings = _Newtype <<< prop (Proxy :: _ "keyBindings") - -_feedbackPaneMinimised :: Lens' State Boolean -_feedbackPaneMinimised = _Newtype <<< prop (Proxy :: _ "feedbackPaneMinimised") - -_lastCompiledCode :: Lens' State (Maybe SourceCode) -_lastCompiledCode = _Newtype <<< prop (Proxy :: _ "lastCompiledCode") - -_currentCodeIsCompiled :: Lens' State Boolean -_currentCodeIsCompiled = _Newtype <<< prop (Proxy :: _ "currentCodeIsCompiled") - -_feedbackPaneDragStart :: Lens' State (Maybe Int) -_feedbackPaneDragStart = _Newtype <<< prop (Proxy :: _ "feedbackPaneDragStart") - -_feedbackPaneExtend :: Lens' State Int -_feedbackPaneExtend = _Newtype <<< prop (Proxy :: _ "feedbackPaneExtend") - -_feedbackPanePreviousExtend :: Lens' State Int -_feedbackPanePreviousExtend = _Newtype <<< prop (Proxy :: _ "feedbackPanePreviousExtend") diff --git a/plutus-playground-client/src/Editor/State.purs b/plutus-playground-client/src/Editor/State.purs deleted file mode 100644 index 8ec3c0669b..0000000000 --- a/plutus-playground-client/src/Editor/State.purs +++ /dev/null @@ -1,134 +0,0 @@ -module Editor.State - ( initialState - , handleAction - , saveBuffer - , initEditor - ) where - -import Control.Alternative ((<|>)) -import Data.Foldable (for_) -import Data.Lens (assign, modifying, use) -import Data.Maybe (Maybe(..), fromMaybe, maybe) -import Data.Ord (clamp) -import Editor.Lenses (_currentCodeIsCompiled, _feedbackPaneDragStart, _feedbackPaneExtend, _feedbackPaneMinimised, _feedbackPanePreviousExtend, _keyBindings, _lastCompiledCode) -import Editor.Types (State(State), Action(..), readKeyBindings) -import Effect.Aff.Class (class MonadAff, liftAff) -import Effect.Class (class MonadEffect) -import Halogen (HalogenM, liftEffect, tell) -import Halogen.Monaco (KeyBindings(..)) -import Halogen.Monaco (Message(..), Query(..)) as Monaco -import Language.Haskell.Interpreter (SourceCode(SourceCode)) -import LocalStorage (Key, getItem, setItem) -import MainFrame.Lenses (_editorSlot) -import MainFrame.Types (ChildSlots) -import Monaco (Editor, getModel, layout, focus, setPosition, setValue) as Monaco -import Prelude (Unit, bind, discard, not, pure, show, unit, void, (+), (-), ($), (<$>), (==)) -import StaticData (keybindingsLocalStorageKey) -import Web.Event.Extra (preventDefault, readFileFromDragEvent) -import Web.UIEvent.MouseEvent (pageY) - -initialState :: forall m. MonadEffect m => m State -initialState = - liftEffect do - keyBindings <- loadKeyBindings - pure - $ State - { keyBindings - , feedbackPaneMinimised: true - , lastCompiledCode: Nothing - , currentCodeIsCompiled: false - , feedbackPaneDragStart: Nothing - , feedbackPaneExtend: 0 - , feedbackPanePreviousExtend: 0 - } - -handleAction - :: forall action output m - . MonadEffect m - => MonadAff m - => Key - -> Action - -> HalogenM State action ChildSlots output m Unit -handleAction _ DoNothing = pure unit - -handleAction bufferLocalStorageKey Init = do - binding <- loadKeyBindings - assign _keyBindings binding - handleAction bufferLocalStorageKey (SetKeyBindings binding) - -handleAction _ (HandleEditorMessage Monaco.EditorReady) = pure unit - -handleAction bufferLocalStorageKey (HandleEditorMessage (Monaco.TextChanged text)) = do - lastCompiledCode <- use _lastCompiledCode - case lastCompiledCode of - Just (SourceCode code) -> assign _currentCodeIsCompiled (code == text) - Nothing -> assign _currentCodeIsCompiled false - liftEffect $ saveBuffer bufferLocalStorageKey text - -handleAction _ (SetKeyBindings binding) = do - void $ tell _editorSlot unit $ Monaco.SetKeyBindings binding - void $ tell _editorSlot unit $ Monaco.Focus - void $ tell _editorSlot unit $ Monaco.Resize - assign _keyBindings binding - liftEffect $ setItem keybindingsLocalStorageKey (show binding) - -handleAction _ ToggleFeedbackPane = modifying _feedbackPaneMinimised not - -handleAction _ (HandleDragEvent event) = liftEffect $ preventDefault event - -handleAction _ (ScrollTo position) = do - void $ tell _editorSlot unit $ Monaco.SetPosition position - void $ tell _editorSlot unit $ Monaco.Focus - -handleAction bufferLocalStorageKey (HandleDropEvent event) = do - liftEffect $ preventDefault event - contents <- liftAff $ readFileFromDragEvent event - void $ tell _editorSlot unit $ Monaco.SetText contents - void $ tell _editorSlot unit $ Monaco.SetPosition { column: 1, lineNumber: 1 } - saveBuffer bufferLocalStorageKey contents - -handleAction _ (SetFeedbackPaneDragStart event) = do - liftEffect $ preventDefault event - assign _feedbackPaneDragStart $ Just $ pageY event - -handleAction _ ClearFeedbackPaneDragStart = do - feedbackPaneExtend <- use _feedbackPaneExtend - assign _feedbackPaneDragStart Nothing - assign _feedbackPanePreviousExtend feedbackPaneExtend - -handleAction _ (FixFeedbackPaneExtend mouseY) = do - feedbackPaneDragStart <- use _feedbackPaneDragStart - feedbackPanePreviousExtend <- use _feedbackPanePreviousExtend - for_ feedbackPaneDragStart - $ \startMouseY -> - assign _feedbackPaneExtend - $ clamp 0 100 - $ startMouseY - - mouseY - + feedbackPanePreviousExtend - ------------------------------------------------------------- -loadKeyBindings :: forall m. MonadEffect m => m KeyBindings -loadKeyBindings = maybe DefaultBindings readKeyBindings <$> liftEffect (getItem keybindingsLocalStorageKey) - -saveBuffer :: forall m. MonadEffect m => Key -> String -> m Unit -saveBuffer bufferLocalStorageKey text = liftEffect $ setItem bufferLocalStorageKey text - -initEditor - :: forall m - . MonadEffect m - => Maybe String - -> Key - -> State - -> Monaco.Editor - -> m Unit -initEditor initialContents bufferLocalStorageKey (State _) editor = - liftEffect do - savedContents <- getItem bufferLocalStorageKey - let - contents = fromMaybe "" (savedContents <|> initialContents) - model <- Monaco.getModel editor - Monaco.setValue model contents - Monaco.layout editor - Monaco.setPosition editor { lineNumber: 1, column: 1 } - Monaco.focus editor diff --git a/plutus-playground-client/src/Editor/Types.purs b/plutus-playground-client/src/Editor/Types.purs deleted file mode 100644 index 4685eb276d..0000000000 --- a/plutus-playground-client/src/Editor/Types.purs +++ /dev/null @@ -1,51 +0,0 @@ -module Editor.Types - ( State(..) - , Action(..) - , allKeyBindings - , readKeyBindings - ) where - -import Data.Enum (enumFromTo) -import Data.Maybe (Maybe) -import Data.Newtype (class Newtype) -import Halogen.Monaco (KeyBindings(..), Message) -import Language.Haskell.Interpreter (SourceCode) -import Monaco (IPosition) -import Prelude (bottom, top) -import Web.HTML.Event.DragEvent (DragEvent) -import Web.UIEvent.MouseEvent (MouseEvent) - -newtype State = State - { keyBindings :: KeyBindings - , feedbackPaneMinimised :: Boolean - , lastCompiledCode :: Maybe SourceCode - , currentCodeIsCompiled :: Boolean - , feedbackPaneDragStart :: Maybe Int - , feedbackPaneExtend :: Int - , feedbackPanePreviousExtend :: Int - } - -derive instance newtypeState :: Newtype State _ - -data Action - = Init - | HandleEditorMessage Message - | HandleDragEvent DragEvent - | HandleDropEvent DragEvent - | ScrollTo IPosition - | SetKeyBindings KeyBindings - | ToggleFeedbackPane - | SetFeedbackPaneDragStart MouseEvent - | ClearFeedbackPaneDragStart - | FixFeedbackPaneExtend Int - | DoNothing - -allKeyBindings :: Array KeyBindings -allKeyBindings = enumFromTo bottom top - -readKeyBindings :: String -> KeyBindings -readKeyBindings "Emacs" = Emacs - -readKeyBindings "Vim" = Vim - -readKeyBindings _ = DefaultBindings diff --git a/plutus-playground-client/src/Editor/View.purs b/plutus-playground-client/src/Editor/View.purs deleted file mode 100644 index d73af643bb..0000000000 --- a/plutus-playground-client/src/Editor/View.purs +++ /dev/null @@ -1,224 +0,0 @@ -module Editor.View - ( editorPreferencesSelect - , compileButton - , simulateButton - , editorPane - , editorFeedback - ) where - -import Prologue hiding (div) -import Component.ErrorPane (errorPane) -import Bootstrap (btn, card, cardHeader, cardHeader_, cardBody_, customSelect, empty, listGroupItem_, listGroup_, nbsp) -import Data.Array as Array -import Data.Lens (_Right, preview, to, view) -import Data.Maybe (fromMaybe, maybe) -import Data.String as String -import Editor.Lenses (_warnings) -import Editor.State (initEditor) -import Editor.Types (Action(..), State(..), allKeyBindings) -import Effect.Aff.Class (class MonadAff) -import Halogen.HTML (ClassName(ClassName), ComponentHTML, HTML, a, button, code_, div, div_, option, p_, pre, pre_, select, slot, text) -import Halogen.HTML.Events (onClick, onDragOver, onDrop, onMouseDown, onMouseMove, onMouseUp, onSelectedIndexChange) -import Halogen.HTML.Properties (class_, classes, disabled, id, selected, value) -import Halogen.Monaco (KeyBindings(..), monacoComponent) -import Icons (Icon(..), icon) -import Language.Haskell.Interpreter (CompilationError(CompilationError, RawError), InterpreterError(CompilationErrors, TimeoutError), Warning, _InterpreterResult, _Warning) -import Language.Haskell.Monaco as HM -import LocalStorage (Key) -import MainFrame.Lenses (_editorSlot) -import MainFrame.Types (ChildSlots, HAction(..), View(..), WebCompilationResult) -import Network.RemoteData (RemoteData(..), _Success, isLoading) -import Web.UIEvent.MouseEvent (MouseEvent, pageY) - -editorPreferencesSelect :: forall p. KeyBindings -> HTML p Action -editorPreferencesSelect active = - select - [ class_ customSelect - , onSelectedIndexChange $ maybe DoNothing SetKeyBindings <<< Array.index allKeyBindings - ] - (editor <$> allKeyBindings) - where - editor keyBindings = - option - [ value $ show keyBindings - , selected (active == keyBindings) - ] - [ text $ editorName keyBindings ] - - editorName DefaultBindings = "Default" - - editorName Emacs = "Emacs" - - editorName Vim = "Vim" - -compileButton :: forall p. WebCompilationResult -> HTML p HAction -compileButton compilationResult = - button - [ classes [ btn, ClassName "btn-green" ] - , onClick $ const CompileProgram - , disabled (isLoading compilationResult) - ] - [ btnText ] - where - btnText = case compilationResult of - Loading -> icon Spinner - _ -> text "Compile" - -simulateButton :: forall p. Boolean -> WebCompilationResult -> HTML p HAction -simulateButton currentCodeIsCompiled compilationResult = - button - [ classes [ btn, ClassName "btn-turquoise" ] - , onClick $ const $ ChangeView Simulations - , disabled isDisabled - ] - [ text "Simulate" ] - where - isDisabled = case compilationResult of - Success (Right _) -> not currentCodeIsCompiled - _ -> true - -editorPane :: forall m. MonadAff m => Maybe String -> Key -> State -> ComponentHTML Action ChildSlots m -editorPane initialContents bufferLocalStorageKey editorState@(State { keyBindings }) = - div - [ class_ (ClassName "code-editor") - , onDragOver HandleDragEvent - , onDrop HandleDropEvent - -- This is not the natural place to have these listeners. But see note [1] below. - , onMouseMove feedbackPaneResizeMouseMoveHandler - , onMouseUp feedbackPaneResizeMouseUpHandler - ] - [ slot - _editorSlot - unit - (monacoComponent (HM.settings (initEditor initialContents bufferLocalStorageKey editorState))) - unit - HandleEditorMessage - , case keyBindings of - Vim -> pre [ id "statusline" ] [ nbsp ] - _ -> pre [ id "statusline", class_ $ ClassName "hidden" ] [ nbsp ] - ] - -editorFeedback :: forall p. State -> WebCompilationResult -> HTML p Action -editorFeedback (State { currentCodeIsCompiled, feedbackPaneExtend, feedbackPaneMinimised }) compilationResult = - div - [ class_ $ ClassName "editor-feedback-container" - -- This is also not the natural place to have these listeners. But see note [1] below. - , onMouseMove feedbackPaneResizeMouseMoveHandler - , onMouseUp feedbackPaneResizeMouseUpHandler - ] - [ div - [ classes feedbackPaneClasses ] - [ div - [ class_ $ ClassName "editor-feedback-resize-bar" - , onMouseDown SetFeedbackPaneDragStart - -- Note [1]: This is the natural place to have these listeners. But because the mouse - -- can - and probably will - move faster than this resize bar, they also need to be on - -- the editor pane (to catch when the mouse moves up faster), and on the feedback - -- container (to catch when the mouse moves down faster). - , onMouseMove feedbackPaneResizeMouseMoveHandler - , onMouseUp feedbackPaneResizeMouseUpHandler - ] - (if feedbackPaneMinimised then [] else [ nbsp ]) - , div - [ class_ $ ClassName "editor-feedback-header" ] - [ p_ [ summaryText ] - , case compilationResult of - Success (Left _) -> minMaxButton - Failure _ -> minMaxButton - _ -> empty - ] - , div - [ class_ $ ClassName "editor-feedback-body" ] - [ errorList - , warningList - ] - ] - ] - where - feedbackPaneClasses = - [ ClassName "editor-feedback" ] - <> case feedbackPaneMinimised, feedbackPaneExtend of - false, 0 -> [] - true, 0 -> [ ClassName "minimised" ] - false, size -> [ ClassName $ "expanded-" <> show size ] - true, size -> [ ClassName "minimised", ClassName $ "expanded-" <> show size ] - - summaryText = case compilationResult of - NotAsked -> text "Not compiled" - Loading -> text "Compiling ..." - Success (Left _) -> text "Compilation failed" - Failure _ -> text "Compilation failed" - _ -> - if currentCodeIsCompiled then - text "Compilation successful" - else - text "Code changed since last compilation" - - minMaxButton = - a - [ class_ btn - , onClick $ const ToggleFeedbackPane - ] - [ icon - $ - if feedbackPaneMinimised then - ArrowUp - else - ArrowDown - ] - - errorList = case compilationResult of - Success (Left error) -> listGroup_ (interpreterErrorPane error) - Failure error -> errorPane error - _ -> empty - - warningList = - fromMaybe empty - $ preview - ( _Success - <<< _Right - <<< _InterpreterResult - <<< _warnings - <<< to compilationWarningsPane - ) - compilationResult - -feedbackPaneResizeMouseMoveHandler :: MouseEvent -> Action -feedbackPaneResizeMouseMoveHandler event = FixFeedbackPaneExtend $ pageY event - -feedbackPaneResizeMouseUpHandler :: MouseEvent -> Action -feedbackPaneResizeMouseUpHandler = const ClearFeedbackPaneDragStart - -interpreterErrorPane :: forall p. InterpreterError -> Array (HTML p Action) -interpreterErrorPane (TimeoutError error) = [ listGroupItem_ [ div_ [ text error ] ] ] - -interpreterErrorPane (CompilationErrors errors) = map compilationErrorPane errors - -compilationErrorPane :: forall p. CompilationError -> HTML p Action -compilationErrorPane (RawError error) = - div - [ classes [ card, ClassName "raw-error" ] ] - [ cardHeader_ [ text "Compilation Error" ] - , cardBody_ [ text error ] - ] - -compilationErrorPane (CompilationError error) = - div - [ classes [ card, ClassName "compilation-error" ] ] - [ div - [ class_ cardHeader ] - [ text $ "Compilation Error, Line " <> show error.row <> ", Column " <> show error.column - , nbsp - , a - [ onClick $ const $ ScrollTo { lineNumber: error.row, column: error.column } ] - [ text "(jump)" ] - ] - , cardBody_ - [ code_ [ pre_ [ text $ String.joinWith "\n" error.text ] ] ] - ] - -compilationWarningsPane :: forall p. Array Warning -> HTML p Action -compilationWarningsPane warnings = listGroup_ (listGroupItem_ <<< pure <<< compilationWarningPane <$> warnings) - -compilationWarningPane :: forall p. Warning -> HTML p Action -compilationWarningPane warning = div [ class_ $ ClassName "compilation-warning" ] [ text $ view _Warning warning ] diff --git a/plutus-playground-client/src/Gists/Types.purs b/plutus-playground-client/src/Gists/Types.purs deleted file mode 100644 index a9508fb1af..0000000000 --- a/plutus-playground-client/src/Gists/Types.purs +++ /dev/null @@ -1,30 +0,0 @@ -module Gists.Types - ( GistAction(..) - , parseGistUrl - ) where - -import Component.ErrorPane (ErrorPaneAction) -import Data.Array.NonEmpty as NonEmptyArray -import Data.Either (Either, note) -import Data.String.Regex (Regex, match, regex) -import Data.String.Regex.Flags (ignoreCase) -import Gist (GistId(..)) -import Prelude (bind, ($), (<$>)) - -data GistAction - = PublishOrUpdateGist - | SetGistUrl String - | LoadGist - | ErrorPaneAction ErrorPaneAction - -gistIdInLinkRegex :: Either String Regex -gistIdInLinkRegex = regex "^(.*/)?([0-9a-f]{32})$" ignoreCase - -parseGistUrl :: String -> Either String GistId -parseGistUrl str = do - gistIdInLink <- gistIdInLinkRegex - note "Could not parse Gist Url" - $ do - matches <- match gistIdInLink str - match <- NonEmptyArray.index matches 2 - GistId <$> match diff --git a/plutus-playground-client/src/Gists/View.purs b/plutus-playground-client/src/Gists/View.purs deleted file mode 100644 index 0b5190907b..0000000000 --- a/plutus-playground-client/src/Gists/View.purs +++ /dev/null @@ -1,167 +0,0 @@ -module Gists.View - ( gistControls - , idPublishGist - , idLoadGist - ) where - -import Prologue hiding (div) - -import Auth (AuthRole(..), AuthStatus, authStatusAuthRole) -import Bootstrap (btn, btnDanger, btnSecondary, btnSmall, empty, formControl, formGroup, isInvalid, isValid, nbsp) -import Component.ErrorPane (closeableErrorPane) -import DOM.HTML.Indexed.InputType (InputType(..)) -import Data.Lens (view) -import Data.Maybe (fromMaybe) -import Gist (Gist, GistId, gistHtmlUrl) -import Gists.Types (GistAction(..), parseGistUrl) -import Halogen.HTML (ClassName(ClassName), HTML, IProp, a, button, div, input, label, text) -import Halogen.HTML.Events (onClick, onValueInput) -import Halogen.HTML.Properties (class_, classes, disabled, for, href, id, target, type_, value) -import Icons (Icon(..), icon) -import MainFrame.Types (WebData) -import Network.RemoteData (RemoteData(NotAsked, Loading, Failure, Success)) - -idPublishGist :: forall r i. IProp (id :: String | r) i -idPublishGist = id "publish-gist" - -idLoadGist :: forall r i. IProp (id :: String | r) i -idLoadGist = id "load-gist" - -gistControls - :: forall a p - . { authStatus :: WebData AuthStatus - , createGistResult :: WebData Gist - , gistErrorPaneVisible :: Boolean - , gistUrl :: Maybe String - | a - } - -> HTML p GistAction -gistControls { authStatus, createGistResult, gistErrorPaneVisible, gistUrl } = - authButton - $ div - [ class_ $ ClassName "gist-controls" ] - [ div - [ class_ $ ClassName "form-inline" ] - [ div - [ class_ formGroup ] - [ label - [ for gistIdInputId ] - [ text "Gist ID" ] - , input - [ type_ InputText - , value $ fromMaybe "" $ gistUrl - , id gistIdInputId - , classes - ( [ formControl, ClassName "form-control-sm" ] - <> case parsedGistId of - Just (Left _) -> [ isInvalid ] - Just (Right _) -> [ isValid ] - Nothing -> [] - ) - , onValueInput SetGistUrl - ] - ] - , loadButton - , publishButton - ] - , case createGistResult, gistErrorPaneVisible of - Success gist, _ -> gistPane gist - Failure err, true -> ErrorPaneAction <$> closeableErrorPane err - Failure _, false -> empty - _, _ -> empty - ] - where - gistIdInputId = "gist-id" - - parsedGistId :: Maybe (Either String GistId) - parsedGistId = parseGistUrl <$> gistUrl - - authButton authorisedView = case view authStatusAuthRole <$> authStatus of - Failure _ -> - button - [ idPublishGist - , classes [ btn, btnSmall, btnDanger ] - ] - [ text "Failure" ] - Success Anonymous -> - a - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary ] - , href "/api/oauth/github" - ] - [ icon Github - , nbsp - , text "Log In" - ] - Success GithubUser -> authorisedView - Loading -> - button - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary ] - , disabled true - ] - [ icon Spinner ] - NotAsked -> - button - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary ] - , disabled true - ] - [ icon Spinner ] - - publishButton = case createGistResult of - Success _ -> - button - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary ] - , onClick $ const PublishOrUpdateGist - ] - [ text "Save" ] - Loading -> - -- make the button extra wide in this case, because there's no load button - button - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary, ClassName "double-width" ] - , disabled true - ] - [ icon Spinner ] - _ -> - button - [ idPublishGist - , classes [ btn, btnSmall, btnSecondary ] - , onClick $ const PublishOrUpdateGist - ] - [ text "Save" ] - - loadButton = case createGistResult of - -- no load button in this case; publish button should be twice the size - Loading -> empty - _ -> - button - [ idLoadGist - , classes - [ btn - , btnSmall - , case parsedGistId of - Just (Left _) -> btnDanger - Just (Right _) -> btnSecondary - Nothing -> btnSecondary - ] - , onClick $ const LoadGist - , disabled - $ case parsedGistId of - Just (Left _) -> true - Just (Right _) -> false - Nothing -> true - ] - [ text "Load" ] - -gistPane :: forall p i. Gist -> HTML p i -gistPane gist = - div [ class_ $ ClassName "gist-link" ] - [ a - [ href $ view gistHtmlUrl gist - , target "_blank" - ] - [ text $ "View on Github" ] - ] diff --git a/plutus-playground-client/src/Ledger/Extra.purs b/plutus-playground-client/src/Ledger/Extra.purs deleted file mode 100644 index ec625569f6..0000000000 --- a/plutus-playground-client/src/Ledger/Extra.purs +++ /dev/null @@ -1,123 +0,0 @@ -module Ledger.Extra where - -import Data.BigInt.Argonaut as BigInt -import Data.Lens (Lens', lens, view) -import Data.Lens.Record (prop) -import Type.Proxy (Proxy(..)) -import Data.Tuple (Tuple(..)) -import PlutusTx.AssocMap (unionWith) -import PlutusTx.AssocMap as AssocMap -import Ledger.Ada (Ada(..)) -import Plutus.V1.Ledger.Interval (Extended(..), Interval, LowerBound(..), UpperBound(..), _Interval) -import Ledger.Slot (Slot(..)) -import Plutus.V1.Ledger.Time (POSIXTime(..)) -import Plutus.V1.Ledger.Value (CurrencySymbol(..), TokenName(..), Value(..)) -import Prelude ((+), (<<<), (<>)) - -humaniseSlotInterval :: Interval Slot -> String -humaniseSlotInterval interval = case from, to of - LowerBound NegInf true, UpperBound PosInf true -> "All time" - _, _ -> "From " <> humaniseSlot from <> " to " <> humaniseSlot to - where - from = view (_Interval <<< _ivFrom) interval - - to = view (_Interval <<< _ivTo) interval - -humaniseSlot :: forall a. HasBound a Slot => a -> String -humaniseSlot bound = start <> " " <> end - where - start = case hasBound bound of - NegInf -> "the start of time" - Finite (Slot slot) -> "Slot " <> BigInt.toString slot.getSlot - PosInf -> "the end of time" - - end = case isInclusive bound of - true -> "(inclusive)" - false -> "(exclusive)" - -humaniseTimeInterval :: Interval POSIXTime -> String -humaniseTimeInterval interval = case from, to of - LowerBound NegInf true, UpperBound PosInf true -> "All time" - _, _ -> "From " <> humaniseTime from <> " to " <> humaniseTime to - where - from = view (_Interval <<< _ivFrom) interval - - to = view (_Interval <<< _ivTo) interval - -humaniseTime :: forall a. HasBound a POSIXTime => a -> String -humaniseTime bound = start <> " " <> end - where - start = case hasBound bound of - NegInf -> "the start of time" - Finite (POSIXTime time) -> "POSIXTime " <> BigInt.toString time.getPOSIXTime - PosInf -> "the end of time" - - end = case isInclusive bound of - true -> "(inclusive)" - false -> "(exclusive)" - --- | Any type that contains an `Extended a` value and an inclusive/exclusive flag. -class HasBound a v | a -> v where - hasBound :: a -> Extended v - isInclusive :: a -> Boolean - -instance lowerBoundHasBound :: HasBound (LowerBound v) v where - hasBound (LowerBound x _) = x - isInclusive (LowerBound _ x) = x - -instance upperBoundHasBound :: HasBound (UpperBound v) v where - hasBound (UpperBound x _) = x - isInclusive (UpperBound _ x) = x - ------------------------------------------------------------- -_ivFrom :: forall a r. Lens' { ivFrom :: a | r } a -_ivFrom = prop (Proxy :: _ "ivFrom") - -_ivTo :: forall a r. Lens' { ivTo :: a | r } a -_ivTo = prop (Proxy :: _ "ivTo") - -_LowerBoundExtended :: forall a. Lens' (LowerBound a) (Extended a) -_LowerBoundExtended = lens get set - where - get (LowerBound e _) = e - - set (LowerBound _ i) e = LowerBound e i - -_LowerBoundInclusive :: forall a. Lens' (LowerBound a) Boolean -_LowerBoundInclusive = lens get set - where - get (LowerBound _ i) = i - - set (LowerBound e _) i = LowerBound e i - -_UpperBoundExtended :: forall a. Lens' (UpperBound a) (Extended a) -_UpperBoundExtended = lens get set - where - get (UpperBound e _) = e - - set (UpperBound _ i) e = UpperBound e i - -_UpperBoundInclusive :: forall a. Lens' (UpperBound a) Boolean -_UpperBoundInclusive = lens get set - where - get (UpperBound _ i) = i - - set (UpperBound e _) i = UpperBound e i - -_a :: forall a r. Lens' { a :: a | r } a -_a = prop (Proxy :: _ "a") - ------------------------------------------------------------- -sum :: Value -> Value -> Value -sum (Value { getValue: x }) (Value { getValue: y }) = Value { getValue: unionWith (unionWith (+)) x y } - -adaToValue :: Ada -> Value -adaToValue (Lovelace ada) = - Value - { getValue: - AssocMap.Map - [ Tuple - (CurrencySymbol { unCurrencySymbol: "" }) - (AssocMap.Map [ Tuple (TokenName { unTokenName: "" }) ada.getLovelace ]) - ] - } diff --git a/plutus-playground-client/src/Main.purs b/plutus-playground-client/src/Main.purs deleted file mode 100644 index 6473664cc0..0000000000 --- a/plutus-playground-client/src/Main.purs +++ /dev/null @@ -1,32 +0,0 @@ -module Main where - -import Control.Apply (void) -import Control.Coroutine (Consumer, Process, connect, consumer, runProcess) -import Data.Maybe (Maybe(Nothing)) -import Effect (Effect) -import Effect.Aff (Aff, forkAff) -import Effect.Class.Console (log) -import Halogen.Aff (awaitBody, runHalogenAff) -import Halogen.VDom.Driver (runUI) -import LocalStorage (RawStorageEvent) -import LocalStorage as LocalStorage -import MainFrame.State (mkMainFrame) -import MainFrame.Types (HAction(..)) -import Prelude (Unit, bind, discard, pure, show, ($), (<>)) - -main :: Effect Unit -main = do - mainFrame <- mkMainFrame - runHalogenAff do - body <- awaitBody - void $ runUI mainFrame Mounted body - forkAff $ runProcess watchLocalStorageProcess - -watchLocalStorageProcess :: Process Aff Unit -watchLocalStorageProcess = connect LocalStorage.listen watchLocalStorage - -watchLocalStorage :: forall r. Consumer RawStorageEvent Aff r -watchLocalStorage = - consumer \event -> do - log $ "Got Local Storage Event: " <> show event - pure Nothing diff --git a/plutus-playground-client/src/MainFrame/Lenses.purs b/plutus-playground-client/src/MainFrame/Lenses.purs deleted file mode 100644 index 5af4b30ff2..0000000000 --- a/plutus-playground-client/src/MainFrame/Lenses.purs +++ /dev/null @@ -1,175 +0,0 @@ -module MainFrame.Lenses - ( _actionDrag - , _authStatus - , _balancesChartSlot - , _blockchainVisualisationState - , _compilationResult - , _contractDemoEditorContents - , _contractDemos - , _createGistResult - , _currentDemoName - , _currentView - , _demoFilesMenuVisible - , _editorSlot - , _editorState - , _evaluationResult - , _functionSchema - , _gistErrorPaneVisible - , _gistUrl - , _knownCurrencies - , _lastSuccessfulCompilationResult - , _result - , _resultRollup - , _simulation - , _simulationActions - , _simulationBlockchainVisualisationState - , _simulationEvaluationResult - , _simulationId - , _simulationWallets - , _simulations - , _successfulCompilationResult - , _successfulEvaluationResult - , _walletKeys - , _warnings - , getKnownCurrencies - ) where - -import Prologue -import Auth (AuthStatus) -import Chain.Types as Chain -import Control.Monad.State.Class (class MonadState) -import Cursor (Cursor, _current) -import Data.Lens (Lens', _Right, lens, preview, set) -import Data.Lens.Extra (peruse) -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Data.Lens.Types (AffineTraversal') -import Data.Maybe (fromMaybe) -import Editor.Types (State) as Editor -import Gist (Gist) -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult, SourceCode, _InterpreterResult) -import Ledger.CardanoWallet (WalletNumber) -import Ledger.Address (PaymentPubKeyHash) -import MainFrame.Types (FullSimulation, State, View, WebData, WebEvaluationResult) -import Network.RemoteData (_Success, RemoteData(NotAsked)) -import Playground.Types (CompilationResult, ContractCall, ContractDemo, EvaluationResult, FunctionSchema, KnownCurrency, Simulation, SimulatorWallet) -import Schema (FormSchema) -import Schema.Types (FormArgument) -import Type.Proxy (Proxy(..)) -import Wallet.Rollup.Types (AnnotatedTx) - -_demoFilesMenuVisible :: Lens' State Boolean -_demoFilesMenuVisible = _Newtype <<< prop (Proxy :: _ "demoFilesMenuVisible") - -_gistErrorPaneVisible :: Lens' State Boolean -_gistErrorPaneVisible = _Newtype <<< prop (Proxy :: _ "gistErrorPaneVisible") - -_currentView :: Lens' State View -_currentView = _Newtype <<< prop (Proxy :: _ "currentView") - -_contractDemos :: Lens' State (Array ContractDemo) -_contractDemos = _Newtype <<< prop (Proxy :: _ "contractDemos") - -_currentDemoName :: Lens' State (Maybe String) -_currentDemoName = _Newtype <<< prop (Proxy :: _ "currentDemoName") - -_editorState :: Lens' State Editor.State -_editorState = _Newtype <<< prop (Proxy :: _ "editorState") - -_simulations :: Lens' State (Cursor FullSimulation) -_simulations = _Newtype <<< prop (Proxy :: _ "simulations") - -_actionDrag :: Lens' State (Maybe Int) -_actionDrag = _Newtype <<< prop (Proxy :: _ "actionDrag") - -_evaluationResult :: Lens' State WebEvaluationResult -_evaluationResult = withDefault NotAsked (_simulations <<< _current <<< _simulationEvaluationResult) - -_successfulEvaluationResult :: AffineTraversal' State EvaluationResult -_successfulEvaluationResult = _evaluationResult <<< _Success <<< _Right - -_compilationResult :: Lens' State (WebData (Either InterpreterError (InterpreterResult CompilationResult))) -_compilationResult = _Newtype <<< lens g s - where - g r = r.compilationResult - - s r c = case preview (_Success <<< _Right <<< _InterpreterResult <<< _result) c of - Just cr -> r { compilationResult = c, lastSuccessfulCompilationResult = Just cr } - Nothing -> r { compilationResult = c } - -_successfulCompilationResult :: AffineTraversal' State CompilationResult -_successfulCompilationResult = _compilationResult <<< _Success <<< _Right <<< _InterpreterResult <<< _result - -_lastSuccessfulCompilationResult :: Lens' State (Maybe CompilationResult) -_lastSuccessfulCompilationResult = _Newtype <<< prop (Proxy :: _ "lastSuccessfulCompilationResult") - -_authStatus :: Lens' State (WebData AuthStatus) -_authStatus = _Newtype <<< prop (Proxy :: _ "authStatus") - -_createGistResult :: Lens' State (WebData Gist) -_createGistResult = _Newtype <<< prop (Proxy :: _ "createGistResult") - -_gistUrl :: Lens' State (Maybe String) -_gistUrl = _Newtype <<< prop (Proxy :: _ "gistUrl") - -_blockchainVisualisationState :: Lens' State Chain.State -_blockchainVisualisationState = withDefault Chain.initialState (_simulations <<< _current <<< _simulationBlockchainVisualisationState) - -_simulation :: Lens' FullSimulation Simulation -_simulation = prop (Proxy :: _ "simulation") - -_simulationEvaluationResult :: Lens' FullSimulation WebEvaluationResult -_simulationEvaluationResult = prop (Proxy :: _ "evaluationResult") - -_simulationBlockchainVisualisationState :: Lens' FullSimulation Chain.State -_simulationBlockchainVisualisationState = prop (Proxy :: _ "blockchainVisualisationState") - ------------------------------------------------------------- -withDefault :: forall s a. a -> AffineTraversal' s a -> Lens' s a -withDefault def l = lens doGet doSet - where - doGet s = fromMaybe def $ preview l s - - doSet s a = set l a s - ------------------------------------------------------------- -_editorSlot :: Proxy "editorSlot" -_editorSlot = Proxy - -_balancesChartSlot :: Proxy "balancesChartSlot" -_balancesChartSlot = Proxy - ------------------------------------------------------------- -_contractDemoEditorContents :: Lens' ContractDemo SourceCode -_contractDemoEditorContents = _Newtype <<< prop (Proxy :: _ "contractDemoEditorContents") - -_simulationId :: Lens' Simulation Int -_simulationId = _Newtype <<< prop (Proxy :: _ "simulationId") - -_simulationActions :: Lens' Simulation (Array (ContractCall FormArgument)) -_simulationActions = _Newtype <<< prop (Proxy :: _ "simulationActions") - -_simulationWallets :: Lens' Simulation (Array SimulatorWallet) -_simulationWallets = _Newtype <<< prop (Proxy :: _ "simulationWallets") - -_resultRollup :: Lens' EvaluationResult (Array (Array AnnotatedTx)) -_resultRollup = _Newtype <<< prop (Proxy :: _ "resultRollup") - -_functionSchema :: Lens' CompilationResult (Array (FunctionSchema FormSchema)) -_functionSchema = _Newtype <<< prop (Proxy :: _ "functionSchema") - -_walletKeys :: Lens' EvaluationResult (Array (Tuple PaymentPubKeyHash WalletNumber)) -_walletKeys = _Newtype <<< prop (Proxy :: _ "walletKeys") - -_knownCurrencies :: Lens' CompilationResult (Array KnownCurrency) -_knownCurrencies = _Newtype <<< prop (Proxy :: _ "knownCurrencies") - ---- Language.Haskell.Interpreter --- -_result :: forall s a. Lens' { result :: a | s } a -_result = prop (Proxy :: _ "result") - -_warnings :: forall s a. Lens' { warnings :: a | s } a -_warnings = prop (Proxy :: _ "warnings") - -getKnownCurrencies :: forall m. MonadState State m => m (Array KnownCurrency) -getKnownCurrencies = fromMaybe [] <$> peruse (_successfulCompilationResult <<< _knownCurrencies) diff --git a/plutus-playground-client/src/MainFrame/MonadApp.purs b/plutus-playground-client/src/MainFrame/MonadApp.purs deleted file mode 100644 index 67bd4ccf69..0000000000 --- a/plutus-playground-client/src/MainFrame/MonadApp.purs +++ /dev/null @@ -1,186 +0,0 @@ -module MainFrame.MonadApp - ( class MonadApp - , HalogenApp(..) - , editorGetContents - , editorHandleAction - , editorSetAnnotations - , editorSetContents - , getGistByGistId - , getOauthStatus - , postContract - , postEvaluation - , postGist - , postGistByGistId - , preventDefault - , readFileFromDragEvent - , resizeBalancesChart - , resizeEditor - , runHalogenApp - , saveBuffer - , scrollIntoView - , setDataTransferData - , setDropEffect - ) where - -import Prologue - -import Animation (class MonadAnimate, animate) -import Auth (AuthStatus) -import Clipboard (class MonadClipboard, copy) -import Control.Monad.Error.Class (class MonadThrow, throwError) -import Control.Monad.Except (mapExceptT, withExceptT) -import Control.Monad.Except.Trans (ExceptT) -import Control.Monad.Reader.Class (class MonadAsk) -import Control.Monad.State.Class (class MonadState) -import Control.Monad.State.Trans (StateT) -import Control.Monad.Trans.Class (class MonadTrans, lift) -import Data.Argonaut (Json, JsonDecodeError, printJsonDecodeError, stringify) -import Data.Array (cons) -import Data.Lens (over) -import Data.Maybe (maybe) -import Data.MediaType (MediaType) -import Data.Newtype (class Newtype, unwrap, wrap) -import Editor.State (handleAction, saveBuffer) as Editor -import Editor.Types (Action) as Editor -import Effect.Aff.Class (class MonadAff, liftAff) -import Effect.Class (class MonadEffect, liftEffect) -import Gist (Gist, GistId, NewGist) -import Halogen (HalogenM, RefLabel, query, tell) -import Halogen as H -import Halogen.Chartist as Chartist -import Halogen.Extra as HE -import Halogen.Monaco as Monaco -import Language.Haskell.Interpreter (InterpreterError, SourceCode(SourceCode), InterpreterResult) -import MainFrame.Lenses (_balancesChartSlot, _editorSlot, _editorState) -import MainFrame.Types (ChildSlots, HAction, State) -import Monaco (IMarkerData) -import Playground.Server as Server -import Playground.Types (CompilationResult, Evaluation, EvaluationResult, PlaygroundError) -import Servant.PureScript (class MonadAjax, AjaxError, printAjaxError, request) -import StaticData (bufferLocalStorageKey) -import URI.RelativePart (_relPath) -import URI.RelativeRef (_relPart) -import Web.Event.Extra (class IsEvent) -import Web.Event.Extra as WebEvent -import Web.HTML.Event.DataTransfer (DropEffect) -import Web.HTML.Event.DataTransfer as DataTransfer -import Web.HTML.Event.DragEvent (DragEvent, dataTransfer) - -class Monad m <= MonadApp m where - editorGetContents :: m (Maybe SourceCode) - editorSetContents :: SourceCode -> Maybe Int -> m Unit - editorHandleAction :: Editor.Action -> m Unit - editorSetAnnotations :: Array IMarkerData -> m Unit - -- - saveBuffer :: String -> m Unit - setDropEffect :: DropEffect -> DragEvent -> m Unit - setDataTransferData :: DragEvent -> MediaType -> String -> m Unit - readFileFromDragEvent :: DragEvent -> m String - -- - getOauthStatus :: ExceptT String m AuthStatus - getGistByGistId :: GistId -> ExceptT String m Gist - postEvaluation :: Evaluation -> ExceptT String m (Either PlaygroundError EvaluationResult) - postGist :: NewGist -> ExceptT String m Gist - postGistByGistId :: NewGist -> GistId -> ExceptT String m Gist - postContract :: SourceCode -> ExceptT String m (Either InterpreterError (InterpreterResult CompilationResult)) - resizeEditor :: m Unit - resizeBalancesChart :: m Unit - -- - preventDefault :: forall e. IsEvent e => e -> m Unit - scrollIntoView :: RefLabel -> m Unit - -newtype HalogenApp m a = HalogenApp (HalogenM State HAction ChildSlots Void m a) - -derive instance newtypeHalogenApp :: Newtype (HalogenApp m a) _ - -derive newtype instance functorHalogenApp :: Functor (HalogenApp m) - -derive newtype instance applicativeHalogenApp :: Applicative (HalogenApp m) - -derive newtype instance applyHalogenApp :: Apply (HalogenApp m) - -derive newtype instance bindHalogenApp :: Bind (HalogenApp m) - -derive newtype instance monadHalogenApp :: Monad (HalogenApp m) - -derive newtype instance monadTransHalogenApp :: MonadTrans HalogenApp - -derive newtype instance monadStateHalogenApp :: MonadState State (HalogenApp m) - -derive newtype instance monadAskHalogenApp :: MonadAsk env m => MonadAsk env (HalogenApp m) - -derive newtype instance monadEffectHalogenApp :: MonadEffect m => MonadEffect (HalogenApp m) - -derive newtype instance monadAffHalogenApp :: MonadAff m => MonadAff (HalogenApp m) - -instance monadAnimateHalogenApp :: MonadAff m => MonadAnimate (HalogenApp m) State where - animate toggle action = HalogenApp $ animate toggle (unwrap action) - -instance monadClipboardHalogenApp :: MonadEffect m => MonadClipboard (HalogenApp m) where - copy = liftEffect <<< copy - -instance monadThrowHalogenApp :: MonadThrow e m => MonadThrow e (HalogenApp m) where - throwError e = lift (throwError e) - -instance - MonadAjax JsonDecodeError Json (AjaxError JsonDecodeError Json) m => - MonadAjax JsonDecodeError Json String (HalogenApp m) where - request r = withExceptT (printAjaxError stringify printJsonDecodeError) - $ mapExceptT (HalogenApp <<< lift) - $ request - $ r - { uri = over - (_relPart <<< _relPath) - (Just <<< maybe [ "api" ] (cons "api")) - r.uri - } - ------------------------------------------------------------- -runHalogenApp :: forall m a. HalogenApp m a -> HalogenM State HAction ChildSlots Void m a -runHalogenApp = unwrap - -instance - ( MonadAjax JsonDecodeError Json (AjaxError JsonDecodeError Json) m - , MonadAff m - ) => - MonadApp (HalogenApp m) where - editorGetContents = do - mText <- wrap $ query _editorSlot unit $ Monaco.GetText identity - pure $ map SourceCode mText - editorSetContents (SourceCode contents) _ = wrap $ void $ tell _editorSlot unit $ Monaco.SetText contents - editorHandleAction action = wrap $ HE.imapState _editorState $ Editor.handleAction bufferLocalStorageKey action - editorSetAnnotations annotations = wrap $ void $ query _editorSlot unit $ Monaco.SetModelMarkers annotations identity - setDropEffect dropEffect event = wrap $ liftEffect $ DataTransfer.setDropEffect dropEffect $ dataTransfer event - setDataTransferData event mimeType value = wrap $ liftEffect $ DataTransfer.setData mimeType value $ dataTransfer event - readFileFromDragEvent event = wrap $ liftAff $ WebEvent.readFileFromDragEvent event - saveBuffer text = wrap $ Editor.saveBuffer bufferLocalStorageKey text - getOauthStatus = Server.getOauthStatus - getGistByGistId = Server.getGistsByGistId - postEvaluation = Server.postEvaluate - postGist = Server.postGists - postGistByGistId = Server.postGistsByGistId - postContract = Server.postContract - resizeEditor = wrap $ void $ H.query _editorSlot unit (Monaco.Resize unit) - resizeBalancesChart = wrap $ void $ H.query _balancesChartSlot unit (Chartist.Resize unit) - preventDefault event = wrap $ liftEffect $ WebEvent.preventDefault event - scrollIntoView ref = wrap $ HE.scrollIntoView ref - -instance MonadApp m => MonadApp (StateT s m) where - editorGetContents = lift editorGetContents - editorSetContents contents cursor = lift $ editorSetContents contents cursor - editorHandleAction action = lift $ editorHandleAction action - editorSetAnnotations annotations = lift $ editorSetAnnotations annotations - setDropEffect dropEffect event = lift $ setDropEffect dropEffect event - setDataTransferData event mimeType value = lift $ setDataTransferData event mimeType value - readFileFromDragEvent event = lift $ readFileFromDragEvent event - saveBuffer text = lift $ saveBuffer text - getOauthStatus = mapExceptT lift getOauthStatus - getGistByGistId gistId = mapExceptT lift $ getGistByGistId gistId - postEvaluation evaluation = mapExceptT lift $ postEvaluation evaluation - postGist newGist = mapExceptT lift $ postGist newGist - postGistByGistId newGist gistId = mapExceptT lift $ postGistByGistId newGist gistId - postContract source = mapExceptT lift $ postContract source - resizeEditor = lift resizeEditor - resizeBalancesChart = lift resizeBalancesChart - preventDefault event = lift $ preventDefault event - scrollIntoView = lift <<< scrollIntoView diff --git a/plutus-playground-client/src/MainFrame/State.purs b/plutus-playground-client/src/MainFrame/State.purs deleted file mode 100644 index 209f53907a..0000000000 --- a/plutus-playground-client/src/MainFrame/State.purs +++ /dev/null @@ -1,527 +0,0 @@ -module MainFrame.State - ( mkMainFrame - , handleAction - , mkInitialState - ) where - -import Prologue - -import Analytics (analyticsTracking) -import Animation (class MonadAnimate, animate) -import Chain.State (handleAction) as Chain -import Chain.Types (Action(..), AnnotatedBlockchain(..), _chainFocusAppearing, _txIdOf) -import Chain.Types (initialState) as Chain -import Clipboard (class MonadClipboard) -import Component.ErrorPane (ErrorPaneAction(..), errorRefLabel) -import Control.Monad.Error.Class (class MonadThrow, throwError) -import Control.Monad.Except.Extra (noteT) -import Control.Monad.Except.Trans (ExceptT(..), except, runExceptT) -import Control.Monad.Maybe.Extra (hoistMaybe) -import Control.Monad.Maybe.Trans (MaybeT(..), runMaybeT) -import Control.Monad.State.Class (class MonadState, gets) -import Control.Monad.State.Extra (zoomStateT) -import Control.Monad.Trans.Class (lift) -import Cursor (_current) -import Cursor as Cursor -import Data.Argonaut (Json, JsonDecodeError) -import Data.Argonaut.Decode (printJsonDecodeError) -import Data.Argonaut.Extra (parseDecodeJson, encodeStringifyJson) -import Data.Array (catMaybes, (..)) -import Data.Array (deleteAt, snoc) as Array -import Data.Array.Extra (move) as Array -import Data.Bifunctor (lmap) -import Data.BigInt.Argonaut (BigInt) -import Data.BigInt.Argonaut as BigInt -import Data.Either (either, isRight, note) -import Data.Foldable (for_) -import Data.Lens (_Right, assign, modifying, over, to, traversed, use, view) -import Data.Lens.Extra (peruse) -import Data.Lens.Fold (maximumOf, lastOf, preview) -import Data.Lens.Index (ix) -import Data.Maybe (fromMaybe) -import Data.MediaType.Common (textPlain) -import Data.Newtype (unwrap) -import Data.RawJson (RawJson(..)) -import Data.String as String -import Data.Traversable (traverse) -import Editor.Lenses (_currentCodeIsCompiled, _feedbackPaneMinimised, _lastCompiledCode) -import Editor.State (initialState) as Editor -import Editor.Types (Action(..), State) as Editor -import Effect.Aff.Class (class MonadAff) -import Effect.Class (class MonadEffect, liftEffect) -import Effect.Exception (Error, error) -import Gist (_GistId, gistId) -import Gists.Types (GistAction(..)) -import Gists.Types as Gists -import Halogen (Component) -import Halogen as H -import Halogen.Query (HalogenM) -import Language.Haskell.Interpreter (CompilationError(..), InterpreterError(..), SourceCode(..)) -import Ledger.CardanoWallet (WalletNumber(WalletNumber)) -import MainFrame.Lenses (_actionDrag, _authStatus, _blockchainVisualisationState, _compilationResult, _contractDemos, _createGistResult, _currentDemoName, _currentView, _demoFilesMenuVisible, _editorState, _evaluationResult, _functionSchema, _gistErrorPaneVisible, _gistUrl, _knownCurrencies, _lastSuccessfulCompilationResult, _resultRollup, _simulation, _simulationActions, _simulationId, _simulationWallets, _simulations, _successfulCompilationResult, _successfulEvaluationResult, getKnownCurrencies) -import MainFrame.MonadApp (class MonadApp, editorGetContents, editorHandleAction, editorSetAnnotations, editorSetContents, getGistByGistId, getOauthStatus, postContract, postEvaluation, postGist, postGistByGistId, preventDefault, resizeBalancesChart, resizeEditor, runHalogenApp, saveBuffer, scrollIntoView, setDataTransferData, setDropEffect) -import MainFrame.Types (DragAndDropEventType(..), FullSimulation, HAction(..), Query, State(..), View(..), WalletEvent(..), ChildSlots) -import MainFrame.View (render) -import Monaco (IMarkerData, markerSeverity) -import Network.RemoteData (RemoteData(..), _Success, fromEither, isSuccess) -import Playground.Gists (mkNewGist, playgroundGistFile, simulationGistFile) -import Playground.Types (ContractCall(..), ContractDemo(..), Evaluation(..), KnownCurrency, Simulation(..), SimulatorWallet(..), _CallEndpoint, _FunctionSchema) -import Plutus.V1.Ledger.Value (Value) -import Schema.Types (Expression, FormArgument, SimulationAction(..), formArgumentToJson, handleActionEvent, handleFormEvent, handleValueEvent, mkInitialValue, traverseFunctionSchema) -import Servant.PureScript (class MonadAjax, AjaxError) -import Simulator.View (simulatorTitleRefLabel, simulationsErrorRefLabel) -import StaticData (mkContractDemos, lookupContractDemo) -import Validation (_argumentValues, _argument) -import Wallet.Lenses (_simulatorWalletBalance, _simulatorWalletWallet, _walletId) -import Web.HTML.Event.DataTransfer as DataTransfer - -mkSimulatorWallet :: Array KnownCurrency -> BigInt -> SimulatorWallet -mkSimulatorWallet currencies walletId = - SimulatorWallet - { simulatorWalletWallet: WalletNumber { getWallet: walletId } - , simulatorWalletBalance: mkInitialValue currencies (BigInt.fromInt 100_000_000) - } - -mkSimulation :: Array KnownCurrency -> Int -> Simulation -mkSimulation simulationCurrencies simulationId = - Simulation - { simulationName: "Simulation " <> show simulationId - , simulationId - , simulationActions: [] - , simulationWallets: mkSimulatorWallet simulationCurrencies <<< BigInt.fromInt <$> 1 .. 2 - } - -mkFullSimulation :: Simulation -> FullSimulation -mkFullSimulation simulation = - { simulation - , evaluationResult: NotAsked - , blockchainVisualisationState: Chain.initialState - } - -mkInitialState :: forall m. MonadThrow Error m => Editor.State -> m State -mkInitialState editorState = do - contractDemos <- - either - ( throwError - <<< error - <<< append "Could not load demo scripts. Parsing errors: " - <<< printJsonDecodeError - ) - pure - mkContractDemos - pure - $ State - { demoFilesMenuVisible: false - , gistErrorPaneVisible: true - , currentView: Editor - , editorState - , contractDemos - , currentDemoName: Nothing - , compilationResult: NotAsked - , lastSuccessfulCompilationResult: Nothing - , simulations: Cursor.empty - , actionDrag: Nothing - , authStatus: NotAsked - , createGistResult: NotAsked - , gistUrl: Nothing - } - -mkMainFrame - :: forall m n - . MonadThrow Error n - => MonadEffect n - => MonadAff m - => MonadAjax JsonDecodeError Json (AjaxError JsonDecodeError Json) m - => n (Component Query HAction Void m) -mkMainFrame = do - editorState <- Editor.initialState - initialState <- mkInitialState editorState - pure $ H.mkComponent - { initialState: const initialState - , render - , eval: - H.mkEval - { handleAction: handleActionWithAnalyticsTracking - , handleQuery: const $ pure Nothing - , initialize: Just Init - , receive: const Nothing - , finalize: Nothing - } - } - --- TODO: use web-common withAnalytics function -handleActionWithAnalyticsTracking - :: forall m - . MonadAjax JsonDecodeError Json (AjaxError JsonDecodeError Json) m - => MonadEffect m - => MonadAff m - => HAction - -> HalogenM State HAction ChildSlots Void m Unit -handleActionWithAnalyticsTracking action = do - liftEffect $ analyticsTracking action - runHalogenApp $ handleAction action - -handleAction - :: forall m - . MonadAjax JsonDecodeError Json String m - => MonadState State m - => MonadClipboard m - => MonadApp m - => MonadAnimate m State - => HAction - -> m Unit -handleAction Init = do - handleAction CheckAuthStatus - editorHandleAction $ Editor.Init - -handleAction Mounted = pure unit - -handleAction (EditorAction action) = editorHandleAction action - -handleAction (ActionDragAndDrop index DragStart event) = do - setDataTransferData event textPlain (show index) - assign _actionDrag (Just index) - -handleAction (ActionDragAndDrop _ DragEnd _) = assign _actionDrag Nothing - -handleAction (ActionDragAndDrop _ DragEnter event) = do - preventDefault event - setDropEffect DataTransfer.Move event - -handleAction (ActionDragAndDrop _ DragOver event) = do - preventDefault event - setDropEffect DataTransfer.Move event - -handleAction (ActionDragAndDrop _ DragLeave _) = pure unit - -handleAction (ActionDragAndDrop destination Drop event) = do - use _actionDrag - >>= case _ of - Just source -> modifying (_simulations <<< _current <<< _simulation <<< _simulationActions) (Array.move source destination) - _ -> pure unit - preventDefault event - assign _actionDrag Nothing - --- We just ignore most Chartist events. -handleAction (HandleBalancesChartMessage _) = pure unit - -handleAction CheckAuthStatus = do - assign _authStatus Loading - authResult <- runExceptT $ getOauthStatus - assign _authStatus $ fromEither authResult - -handleAction (GistAction subEvent) = handleGistAction subEvent - -handleAction ToggleDemoFilesMenu = modifying _demoFilesMenuVisible not - -handleAction (ChangeView view) = do - assign _currentView view - when (view == Editor) resizeEditor - when (view == Transactions) resizeBalancesChart - -handleAction EvaluateActions = - void - $ runMaybeT - $ do - simulation <- peruse (_simulations <<< _current <<< _simulation) - evaluation <- - MaybeT do - contents <- editorGetContents - pure $ join $ toEvaluation <$> contents <*> simulation - assign _evaluationResult Loading - result <- lift $ runExceptT $ postEvaluation evaluation - assign _evaluationResult $ fromEither result - case result of - Right (Right _) -> do - -- on successful evaluation, update last evaluated simulation, and reset and show transactions - assign _blockchainVisualisationState Chain.initialState - -- preselect the first transaction (if any) - mAnnotatedBlockchain <- peruse (_successfulEvaluationResult <<< _resultRollup <<< to AnnotatedBlockchain) - txId <- (gets <<< lastOf) (_successfulEvaluationResult <<< _resultRollup <<< traversed <<< traversed <<< _txIdOf) - lift $ zoomStateT _blockchainVisualisationState $ Chain.handleAction (FocusTx txId) mAnnotatedBlockchain - replaceViewOnSuccess (fromEither result) Simulations Transactions - lift $ scrollIntoView simulatorTitleRefLabel - Right (Left _) -> do - -- on failed evaluation, scroll the error pane into view - lift $ scrollIntoView simulationsErrorRefLabel - Left _ -> do - -- on failed response, scroll the ajax error pane into view - lift $ scrollIntoView errorRefLabel - pure unit - -handleAction (LoadScript key) = do - contractDemos <- use _contractDemos - case lookupContractDemo key contractDemos of - Nothing -> pure unit - Just (ContractDemo { contractDemoName, contractDemoEditorContents, contractDemoSimulations, contractDemoContext }) -> do - editorSetContents contractDemoEditorContents (Just 1) - saveBuffer (unwrap contractDemoEditorContents) - assign _demoFilesMenuVisible false - assign _currentView Editor - assign _currentDemoName (Just contractDemoName) - assign _simulations $ mkFullSimulation <$> Cursor.fromArray contractDemoSimulations - assign (_editorState <<< _lastCompiledCode) (Just contractDemoEditorContents) - assign (_editorState <<< _currentCodeIsCompiled) true - assign _compilationResult (Success <<< Right $ contractDemoContext) - assign _evaluationResult NotAsked - assign _createGistResult NotAsked - --- Note: the following three cases involve some temporary fudges that should become --- unnecessary when we remodel and have one evaluationResult per simulation. In --- particular: we prevent simulation changes while the evaluationResult is Loading, --- and switch to the simulations view (from transactions) following any change -handleAction AddSimulationSlot = do - evaluationResult <- use _evaluationResult - case evaluationResult of - Loading -> pure unit - _ -> do - knownCurrencies <- getKnownCurrencies - mSignatures <- peruse (_successfulCompilationResult <<< _functionSchema) - case mSignatures of - Just _ -> - modifying _simulations - ( \simulations -> - let - maxsimulationId = fromMaybe 0 $ maximumOf (traversed <<< _simulation <<< _simulationId) simulations - - simulationId = maxsimulationId + 1 - in - Cursor.snoc simulations - (mkFullSimulation $ mkSimulation knownCurrencies simulationId) - ) - Nothing -> pure unit - assign _currentView Simulations - -handleAction (SetSimulationSlot index) = do - evaluationResult <- use _evaluationResult - case evaluationResult of - Loading -> pure unit - _ -> do - modifying _simulations (Cursor.setIndex index) - assign _currentView Simulations - -handleAction (RemoveSimulationSlot index) = do - evaluationResult <- use _evaluationResult - case evaluationResult of - Loading -> pure unit - _ -> do - simulations <- use _simulations - if (Cursor.getIndex simulations) == index then - assign _currentView Simulations - else - pure unit - modifying _simulations (Cursor.deleteAt index) - -handleAction (ModifyWallets action) = do - knownCurrencies <- getKnownCurrencies - modifying (_simulations <<< _current <<< _simulation <<< _simulationWallets) (handleActionWalletEvent (mkSimulatorWallet knownCurrencies) action) - -handleAction (ChangeSimulation subaction) = do - knownCurrencies <- getKnownCurrencies - let - initialValue = mkInitialValue knownCurrencies zero - modifying (_simulations <<< _current <<< _simulation <<< _simulationActions) (handleSimulationAction initialValue subaction) - -handleAction (ChainAction subaction) = do - mAnnotatedBlockchain <- - peruse (_successfulEvaluationResult <<< _resultRollup <<< to AnnotatedBlockchain) - let - wrapper = case subaction of - (FocusTx _) -> animate (_blockchainVisualisationState <<< _chainFocusAppearing) - _ -> identity - wrapper - $ zoomStateT _blockchainVisualisationState - $ Chain.handleAction subaction mAnnotatedBlockchain - -handleAction CompileProgram = do - mContents <- editorGetContents - case mContents of - Nothing -> pure unit - Just contents -> do - oldSuccessfulCompilationResult <- use _lastSuccessfulCompilationResult - assign _compilationResult Loading - newCompilationResult <- runExceptT $ postContract contents - assign _compilationResult $ fromEither newCompilationResult - -- If we got a successful result, update lastCompiledCode and switch tab. - for_ newCompilationResult case _ of - Right _ -> do - assign (_editorState <<< _lastCompiledCode) (Just contents) - assign (_editorState <<< _currentCodeIsCompiled) true - Left _ -> assign (_editorState <<< _feedbackPaneMinimised) false - -- Update the error display. - editorSetAnnotations - $ case newCompilationResult of - Right (Left errors) -> toAnnotations errors - _ -> [] - -- If we have a result with new signatures, we can only hold - -- onto the old actions if the signatures still match. Any - -- change means we'll have to clear out the existing simulation. - -- Same thing for currencies. - -- Potentially we could be smarter about this. But for now, - -- let's at least be correct. - newSuccessfulCompilationResult <- use _lastSuccessfulCompilationResult - let - oldSignatures = view _functionSchema <$> oldSuccessfulCompilationResult - - newSignatures = view _functionSchema <$> newSuccessfulCompilationResult - - oldCurrencies = view _knownCurrencies <$> oldSuccessfulCompilationResult - - newCurrencies = view _knownCurrencies <$> newSuccessfulCompilationResult - unless - ( oldSignatures == newSignatures - && oldCurrencies - == newCurrencies - ) - ( assign _simulations - $ case newCurrencies of - Just currencies -> Cursor.singleton $ mkFullSimulation $ mkSimulation currencies 1 - Nothing -> Cursor.empty - ) - pure unit - -handleSimulationAction - :: Value - -> SimulationAction - -> Array (ContractCall FormArgument) - -> Array (ContractCall FormArgument) -handleSimulationAction _ (ModifyActions actionEvent) = handleActionEvent actionEvent - -handleSimulationAction initialValue (PopulateAction n event) = do - over - ( ix n - <<< _CallEndpoint - <<< _argumentValues - <<< _FunctionSchema - <<< _argument - ) - $ handleFormEvent initialValue event - -handleGistAction :: forall m. MonadApp m => MonadState State m => GistAction -> m Unit -handleGistAction PublishOrUpdateGist = do - void - $ runMaybeT do - mContents <- lift $ editorGetContents - simulations <- use _simulations - newGist <- hoistMaybe $ mkNewGist { source: mContents, simulations: _.simulation <$> simulations } - mGist <- use _createGistResult - assign _createGistResult Loading - newResult <- - lift - $ runExceptT - $ case preview (_Success <<< gistId) mGist of - Nothing -> postGist newGist - Just existingGistId -> postGistByGistId newGist existingGistId - assign _createGistResult $ fromEither newResult - gistId <- hoistMaybe $ preview (_Right <<< gistId <<< _GistId) newResult - assign _gistUrl (Just gistId) - when (isRight newResult) do - assign _currentView Editor - assign _currentDemoName Nothing - -handleGistAction (SetGistUrl newGistUrl) = assign _gistUrl (Just newGistUrl) - -handleGistAction LoadGist = - void $ runExceptT - $ do - mGistId <- ExceptT (note "Gist Url not set." <$> use _gistUrl) - eGistId <- except $ Gists.parseGistUrl mGistId - -- - assign _createGistResult Loading - assign _gistErrorPaneVisible true - aGist <- lift $ runExceptT $ getGistByGistId eGistId - assign _createGistResult $ fromEither aGist - when (isRight aGist) do - assign _currentView Editor - assign _currentDemoName Nothing - gist <- except aGist - -- - -- Load the source, if available. - content <- noteT "Source not found in gist." $ view playgroundGistFile gist - lift $ editorSetContents (SourceCode content) (Just 1) - lift $ saveBuffer content - assign _simulations Cursor.empty - assign _evaluationResult NotAsked - -- - -- Load the simulation, if available. - simulationString <- noteT "Simulation not found in gist." $ view simulationGistFile gist - simulations <- except $ lmap printJsonDecodeError $ parseDecodeJson simulationString - assign _simulations $ mkFullSimulation <$> simulations - -handleGistAction (ErrorPaneAction CloseErrorPane) = assign _gistErrorPaneVisible false - -handleActionWalletEvent :: (BigInt -> SimulatorWallet) -> WalletEvent -> Array SimulatorWallet -> Array SimulatorWallet -handleActionWalletEvent mkWallet AddWallet wallets = - let - maxWalletId = fromMaybe zero $ maximumOf (traversed <<< _simulatorWalletWallet <<< _walletId) wallets - - newWallet = mkWallet (add one maxWalletId) - in - Array.snoc wallets newWallet - -handleActionWalletEvent _ (RemoveWallet index) wallets = fromMaybe wallets $ Array.deleteAt index wallets - -handleActionWalletEvent _ (ModifyBalance walletIndex action) wallets = - over - (ix walletIndex <<< _simulatorWalletBalance) - (handleValueEvent action) - wallets - -replaceViewOnSuccess :: forall m e a. MonadState State m => RemoteData e a -> View -> View -> m Unit -replaceViewOnSuccess result source target = do - currentView <- use _currentView - when (isSuccess result && currentView == source) - (assign _currentView target) - ------------------------------------------------------------- -toEvaluation :: SourceCode -> Simulation -> Maybe Evaluation -toEvaluation sourceCode (Simulation { simulationActions, simulationWallets }) = do - program <- RawJson <<< encodeStringifyJson <$> traverse toExpression simulationActions - pure - $ Evaluation - { wallets: simulationWallets - , program - , sourceCode - } - -toExpression :: ContractCall FormArgument -> Maybe Expression -toExpression = traverseContractCall encodeForm - where - encodeForm :: FormArgument -> Maybe RawJson - encodeForm argument = (RawJson <<< encodeStringifyJson) <$> formArgumentToJson argument - -traverseContractCall - :: forall m b a - . Applicative m - => (a -> m b) - -> ContractCall a - -> m (ContractCall b) -traverseContractCall _ (AddBlocks addBlocks) = pure $ AddBlocks addBlocks - -traverseContractCall _ (AddBlocksUntil addBlocksUntil) = pure $ AddBlocksUntil addBlocksUntil - -traverseContractCall _ (PayToWallet payToWallet) = pure $ PayToWallet payToWallet - -traverseContractCall f (CallEndpoint { caller, argumentValues: oldArgumentValues }) = rewrap <$> traverseFunctionSchema f oldArgumentValues - where - rewrap newArgumentValues = CallEndpoint { caller, argumentValues: newArgumentValues } - -toAnnotations :: InterpreterError -> Array IMarkerData -toAnnotations (TimeoutError _) = [] - -toAnnotations (CompilationErrors errors) = catMaybes (toAnnotation <$> errors) - -toAnnotation :: CompilationError -> Maybe IMarkerData -toAnnotation (RawError _) = Nothing - -toAnnotation (CompilationError { row, column, text }) = - Just - { severity: markerSeverity "Error" - , message: String.joinWith "\\n" text - , startLineNumber: row - , startColumn: column - , endLineNumber: row - , endColumn: column - , code: mempty - , source: mempty - } diff --git a/plutus-playground-client/src/MainFrame/Types.purs b/plutus-playground-client/src/MainFrame/Types.purs deleted file mode 100644 index 9aa9b4068b..0000000000 --- a/plutus-playground-client/src/MainFrame/Types.purs +++ /dev/null @@ -1,194 +0,0 @@ -module MainFrame.Types - ( State(..) - , View(..) - , ChainSlot - , Blockchain - , WebData - , WebCompilationResult - , WebEvaluationResult - , FullSimulation - , SimulatorAction - , Query - , HAction(..) - , WalletEvent(..) - , DragAndDropEventType(..) - , ChildSlots - ) where - -import Analytics (class IsEvent, defaultEvent) -import Auth (AuthStatus) -import Chain.Types (Action(..)) -import Chain.Types as Chain -import Clipboard as Clipboard -import Cursor (Cursor) -import Data.Array.NonEmpty (fromNonEmpty) -import Data.Either (Either) -import Data.Generic.Rep (class Generic) -import Data.Maybe (Maybe(..)) -import Data.Newtype (class Newtype) -import Data.NonEmpty ((:|)) -import Editor.Types as Editor -import Gist (Gist) -import Gists.Types (GistAction(..)) -import Halogen as H -import Halogen.Chartist as Chartist -import Halogen.Monaco as Monaco -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult) -import Network.RemoteData (RemoteData) -import Playground.Types (CompilationResult, ContractCall, ContractDemo, EvaluationResult, PlaygroundError, Simulation) -import Ledger.Tx.Internal (Tx) -import Prelude (class Eq, class Show, Unit, show, ($)) -import Schema.Types (ActionEvent(..), FormArgument, SimulationAction(..)) -import Test.QuickCheck.Arbitrary (class Arbitrary) -import Test.QuickCheck.Gen as Gen -import ValueEditor (ValueEvent(..)) -import Web.HTML.Event.DragEvent (DragEvent) - -newtype State = State - { demoFilesMenuVisible :: Boolean - , gistErrorPaneVisible :: Boolean - , currentView :: View - , contractDemos :: Array ContractDemo - , currentDemoName :: Maybe String - , editorState :: Editor.State - , compilationResult :: WebCompilationResult - , lastSuccessfulCompilationResult :: Maybe CompilationResult - , simulations :: Cursor FullSimulation - , actionDrag :: Maybe Int - , authStatus :: WebData AuthStatus - , createGistResult :: WebData Gist - , gistUrl :: Maybe String - } - -derive instance newtypeState :: Newtype State _ - -data View - = Editor - | Simulations - | Transactions - -derive instance eqView :: Eq View - -derive instance genericView :: Generic View _ - -instance arbitraryView :: Arbitrary View where - arbitrary = Gen.elements $ fromNonEmpty (Editor :| [ Simulations, Transactions ]) - -instance showView :: Show View where - show Editor = "Editor" - show Simulations = "Simulation" - show Transactions = "Transactions" - -type ChainSlot = Array Tx - -type Blockchain = Array ChainSlot - -type WebData = RemoteData String - -type WebCompilationResult = WebData (Either InterpreterError (InterpreterResult CompilationResult)) - -type WebEvaluationResult = WebData (Either PlaygroundError EvaluationResult) - -type FullSimulation = - { simulation :: Simulation - , blockchainVisualisationState :: Chain.State - , evaluationResult :: WebEvaluationResult - } - --- this synonym is defined in playground-common/src/Playground/Types.hs -type SimulatorAction = ContractCall FormArgument - -data Query :: forall k. k -> Type -data Query a - -data HAction - = Init - | Mounted - -- SubEvents. - | ActionDragAndDrop Int DragAndDropEventType DragEvent - | HandleBalancesChartMessage Chartist.Message - -- Gist support. - | CheckAuthStatus - | GistAction GistAction - -- Demo files menu. - | ToggleDemoFilesMenu - -- Tabs. - | ChangeView View - -- Editor. - | EditorAction Editor.Action - | CompileProgram - -- Simulations. - | LoadScript String - | AddSimulationSlot - | SetSimulationSlot Int - | RemoveSimulationSlot Int - -- Wallets. - | ModifyWallets WalletEvent - -- Actions. - | ChangeSimulation SimulationAction - | EvaluateActions - -- Chain. - | ChainAction (Chain.Action) - -data WalletEvent - = AddWallet - | RemoveWallet Int - | ModifyBalance Int ValueEvent - -data DragAndDropEventType - = DragStart - | DragEnd - | DragEnter - | DragOver - | DragLeave - | Drop - -instance showDragAndDropEventType :: Show DragAndDropEventType where - show DragStart = "DragStart" - show DragEnd = "DragEnd" - show DragEnter = "DragEnter" - show DragOver = "DragOver" - show DragLeave = "DragLeave" - show Drop = "Drop" - -type ChildSlots = - ( editorSlot :: H.Slot Monaco.Query Monaco.Message Unit - , balancesChartSlot :: H.Slot Chartist.Query Chartist.Message Unit - ) - --- | Here we decide which top-level queries to track as GA events, and --- how to classify them. -instance actionIsEvent :: IsEvent HAction where - toEvent Init = Nothing - toEvent Mounted = Just $ defaultEvent "Mounted" - toEvent (EditorAction (Editor.HandleDropEvent _)) = Just $ defaultEvent "DropScript" - toEvent (EditorAction _) = Just $ (defaultEvent "ConfigureEditor") - toEvent CompileProgram = Just $ defaultEvent "CompileProgram" - toEvent (HandleBalancesChartMessage _) = Nothing - toEvent CheckAuthStatus = Nothing - toEvent (GistAction PublishOrUpdateGist) = Just $ (defaultEvent "Publish") { category = Just "Gist" } - toEvent (GistAction (SetGistUrl _)) = Nothing - toEvent (GistAction LoadGist) = Just $ (defaultEvent "LoadGist") { category = Just "Gist" } - toEvent (GistAction (ErrorPaneAction _)) = Nothing - toEvent ToggleDemoFilesMenu = Nothing - toEvent (ChangeView view) = Just $ (defaultEvent "View") { label = Just $ show view } - toEvent (LoadScript script) = Just $ (defaultEvent "LoadScript") { label = Just script } - toEvent AddSimulationSlot = Just $ (defaultEvent "AddSimulationSlot") { category = Just "Simulation" } - toEvent (SetSimulationSlot _) = Just $ (defaultEvent "SetSimulationSlot") { category = Just "Simulation" } - toEvent (RemoveSimulationSlot _) = Just $ (defaultEvent "RemoveSimulationSlot") { category = Just "Simulation" } - toEvent (ModifyWallets AddWallet) = Just $ (defaultEvent "AddWallet") { category = Just "Wallet" } - toEvent (ModifyWallets (RemoveWallet _)) = Just $ (defaultEvent "RemoveWallet") { category = Just "Wallet" } - toEvent (ModifyWallets (ModifyBalance _ (SetBalance _ _ _))) = Just $ (defaultEvent "SetBalance") { category = Just "Wallet" } - toEvent (ActionDragAndDrop _ eventType _) = Just $ (defaultEvent (show eventType)) { category = Just "Action" } - toEvent EvaluateActions = Just $ (defaultEvent "EvaluateActions") { category = Just "Action" } - toEvent (ChangeSimulation (PopulateAction _ _)) = Just $ (defaultEvent "PopulateAction") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (AddAction _))) = Just $ (defaultEvent "AddAction") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (AddWaitAction _))) = Just $ (defaultEvent "AddWaitAction") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (RemoveAction _))) = Just $ (defaultEvent "RemoveAction") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (SetPayToWalletValue _ _))) = Just $ (defaultEvent "SetPayToWalletValue") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (SetPayToWalletRecipient _ _))) = Just $ (defaultEvent "SetPayToWalletRecipient") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (SetWaitTime _ _))) = Just $ (defaultEvent "SetWaitTime") { category = Just "Action" } - toEvent (ChangeSimulation (ModifyActions (SetWaitUntilTime _ _))) = Just $ (defaultEvent "SetWaitUntilTime") { category = Just "Action" } - toEvent (ChainAction (FocusTx (Just _))) = Just $ (defaultEvent "BlockchainFocus") { category = Just "Transaction" } - toEvent (ChainAction (FocusTx Nothing)) = Nothing - toEvent (ChainAction (ClipboardAction (Clipboard.CopyToClipboard _))) = Just $ (defaultEvent "ClipboardAction") { category = Just "CopyToClipboard" } diff --git a/plutus-playground-client/src/MainFrame/View.js b/plutus-playground-client/src/MainFrame/View.js deleted file mode 100644 index 53bb5a9c76..0000000000 --- a/plutus-playground-client/src/MainFrame/View.js +++ /dev/null @@ -1,11 +0,0 @@ -/*eslint-env node*/ -/*global exports global require*/ - -'use strict'; - -// Pulling in the image this way plays nicely with Webpack. The `plutusLogo` string will -// actually be the hashed, permalink URL. eg. 'e57a929e981d95dd55f1e92be8f3e0bb.png'. -// Note: `global.plutusLogo` is not defined in `src/entry.js`, but _is_ defined in -// `test/Main.js`. This ensures that the tests pass, even though the test suite -// cannot resolve the path to the image. -exports.plutusLogo = global.plutusLogo || require('static/images/plutus-logo.svg'); diff --git a/plutus-playground-client/src/MainFrame/View.purs b/plutus-playground-client/src/MainFrame/View.purs deleted file mode 100644 index 86c23ff0ff..0000000000 --- a/plutus-playground-client/src/MainFrame/View.purs +++ /dev/null @@ -1,285 +0,0 @@ -module MainFrame.View (render) where - -import Bootstrap (active, btn, containerFluid, hidden, justifyContentBetween, mlAuto, mrAuto, navItem, navLink, navbar, navbarBrand, navbarExpand, navbarNav, navbarText, nbsp) -import Control.Monad.State (evalState) -import Cursor (Cursor, current) -import Data.Either (Either(..)) -import Data.Lens (view) -import Data.Maybe (Maybe(..)) -import Data.Newtype (unwrap) -import Data.Semiring (zero) -import Data.Tuple.Nested (type (/\), (/\)) -import Editor.Lenses (_currentCodeIsCompiled, _keyBindings) -import Editor.Types as Editor -import Editor.View (compileButton, editorPreferencesSelect, simulateButton, editorPane, editorFeedback) -import Effect.Aff.Class (class MonadAff) -import Gists.View (gistControls) -import Halogen.HTML (ClassName(ClassName), ComponentHTML, HTML, a, button, div, footer, h1_, img, label_, main, nav, span, strong_, text, ul, li) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Extra (mapComponent) -import Halogen.HTML.Properties (class_, classes, height, href, src, target, width) -import Icons (Icon(..), icon) -import Language.Haskell.Interpreter (_SourceCode) -import MainFrame.Lenses (getKnownCurrencies, _contractDemoEditorContents) -import MainFrame.Types (ChildSlots, FullSimulation, HAction(..), State(..), View(..), WebCompilationResult) -import Network.RemoteData (RemoteData(..)) -import Playground.Types (ContractDemo(..)) -import Prelude (class Eq, const, ($), (<$>), (<<<), (==)) -import Schema.Types (mkInitialValue) -import Simulator.View (simulatorTitle, simulationsPane, simulationsNav) -import StaticData (bufferLocalStorageKey, lookupContractDemo) -import Transaction.View (evaluationPane) - -foreign import plutusLogo :: String - -render :: forall m. MonadAff m => State -> ComponentHTML HAction ChildSlots m -render state@(State { contractDemos, currentView, editorState, compilationResult, simulations }) = - div - [ class_ $ ClassName "frame" ] - [ mainHeader - , subHeader state - , editorMain contractDemos currentView editorState compilationResult - , simulationsMain state - , transactionsMain currentView simulations - , mainFooter - ] - -mainHeader :: forall p. HTML p HAction -mainHeader = - nav - [ classes [ navbar, navbarExpand, justifyContentBetween, ClassName "header" ] - ] - [ span [ class_ navbarBrand ] - [ img - [ height 36 - , width 36 - , src plutusLogo - ] - , text - "Plutus playground" - ] - , documentationLinksPane - ] - -documentationLinksPane :: forall p i. HTML p i -documentationLinksPane = - ul - [ class_ navbarNav ] - (makeNavItem <$> links) - where - links = - [ text "Getting Started" /\ "https://developers.cardano.org/en/programming-languages/plutus/getting-started/" - , text "Tutorials" /\ "./doc/plutus/tutorials/index.html" - , text "API" /\ "./doc/haddock/index.html" - , text "Privacy" /\ "https://static.iohk.io/docs/data-protection/iohk-data-protection-gdpr-policy.pdf" - ] - -subHeader :: forall m. MonadAff m => State -> ComponentHTML HAction ChildSlots m -subHeader state@(State { demoFilesMenuVisible, contractDemos, currentDemoName }) = - nav - [ classes [ navbar, navbarExpand, justifyContentBetween, ClassName "sub-header" ] ] - [ a - [ classes buttonClasses - , onClick $ const $ ToggleDemoFilesMenu - ] - [ buttonIcon ] - , contractDemosPane demoFilesMenuVisible contractDemos currentDemoName - , GistAction <$> gistControls (unwrap state) - ] - where - buttonClasses = - if demoFilesMenuVisible then - [ btn, buttonClass, ClassName "open" ] - else - [ btn, buttonClass ] - - buttonClass = ClassName "menu-button" - - buttonIcon = - if demoFilesMenuVisible then - icon Close - else - icon Bars - -contractDemosPane :: forall p. Boolean -> Array ContractDemo -> Maybe String -> HTML p HAction -contractDemosPane demoFilesMenuOpen contractDemos currentDemoName = - div - [ classes demoPaneClasses ] - [ span - [ class_ navbarText ] - [ text "Demo files" ] - , ul - [ class_ navbarNav ] - (demoScriptNavItem currentDemoName <$> contractDemos) - ] - where - demoPaneClasses = - if demoFilesMenuOpen then - [ navbarNav, ClassName "menu", ClassName "open" ] - else - [ navbarNav, ClassName "menu" ] - -demoScriptNavItem :: forall p. Maybe String -> ContractDemo -> HTML p HAction -demoScriptNavItem currentDemoName (ContractDemo { contractDemoName }) = - li - [ class_ navItem ] - [ a - [ classes navLinkClasses - , onClick $ const $ LoadScript contractDemoName - ] - [ text contractDemoName ] - ] - where - navLinkClasses = case currentDemoName of - Just name -> - if contractDemoName == name then - [ active, navLink ] - else - [ navLink ] - Nothing -> [ navLink ] - -editorMain :: forall m. MonadAff m => Array ContractDemo -> View -> Editor.State -> WebCompilationResult -> ComponentHTML HAction ChildSlots m -editorMain contractDemos currentView editorState compilationResult = - main - [ classes $ mainComponentClasses currentView Editor ] - [ div - [ class_ $ ClassName "main-header" ] - [ h1_ [ text "Editor" ] - , button [ classes [ btn, ClassName "hidden" ] ] [ nbsp ] - ] -- invisible button so the height matches the simulator header - , editorWrapper contractDemos editorState compilationResult - ] - -simulationsMain :: forall m. MonadAff m => State -> ComponentHTML HAction ChildSlots m -simulationsMain state@(State { currentView }) = - main - [ classes $ mainComponentClasses currentView Simulations ] - [ simulatorTitle - , simulationsWrapper state - ] - -transactionsMain :: forall m. MonadAff m => View -> Cursor FullSimulation -> ComponentHTML HAction ChildSlots m -transactionsMain currentView simulations = - main - [ classes $ mainComponentClasses currentView Transactions ] - [ simulatorTitle - , transactionsWrapper simulations - ] - -mainComponentClasses :: forall view. Eq view => view -> view -> Array (ClassName) -mainComponentClasses currentView targetView = - if currentView == targetView then - [ containerFluid, ClassName "main" ] - else - [ containerFluid, hidden, ClassName "main" ] - -editorWrapper :: forall m. MonadAff m => Array ContractDemo -> Editor.State -> WebCompilationResult -> ComponentHTML HAction ChildSlots m -editorWrapper contractDemos editorState compilationResult = - div - [ classes [ ClassName "main-body", ClassName "editor" ] ] - [ div - [ class_ $ ClassName "editor-controls" ] - [ div - [ class_ $ ClassName "key-bindings" ] - [ label_ [ text "Key Bindings" ] - , mapComponent EditorAction $ editorPreferencesSelect (view _keyBindings editorState) - ] - , div - [ class_ $ ClassName "editor-buttons" ] - [ compileButton compilationResult - , simulateButton (view _currentCodeIsCompiled editorState) compilationResult - ] - ] - , mapComponent EditorAction $ editorPane defaultContents bufferLocalStorageKey editorState - , mapComponent EditorAction $ editorFeedback editorState compilationResult - ] - where - defaultContents :: Maybe String - defaultContents = view (_contractDemoEditorContents <<< _SourceCode) <$> lookupContractDemo "Vesting" contractDemos - -simulationsWrapper :: forall p. State -> HTML p HAction -simulationsWrapper state@(State { actionDrag, compilationResult, simulations }) = - let - knownCurrencies = evalState getKnownCurrencies state - - initialValue = mkInitialValue knownCurrencies zero - in - div - [ classes [ ClassName "main-body", ClassName "simulator" ] ] - [ simulationsPane - initialValue - actionDrag - compilationResult - simulations - ] - -transactionsWrapper :: forall m. MonadAff m => Cursor FullSimulation -> ComponentHTML HAction ChildSlots m -transactionsWrapper simulations = - div - [ classes [ ClassName "main-body", ClassName "simulator" ] ] - [ div - [ class_ $ ClassName "simulations" ] - [ simulationsNav simulations - , div - [ class_ $ ClassName "simulation" ] - case current simulations of - Just { evaluationResult, blockchainVisualisationState } -> case evaluationResult of - Success (Right evaluation) -> [ evaluationPane blockchainVisualisationState evaluation ] - Success (Left _) -> - [ text "Your simulation has errors. Click the " - , strong_ [ text "Simulations" ] - , text " tab above to fix them and recompile." - ] - Failure _ -> - [ text "Your simulation has errors. Click the " - , strong_ [ text "Simulations" ] - , text " tab above to fix them and recompile." - ] - Loading -> [ icon Spinner ] - NotAsked -> - [ text "Click the " - , strong_ [ text "Simulations" ] - , text " tab above and evaluate a simulation to see some results." - ] - Nothing -> [] - ] - ] - -mainFooter :: forall p i. HTML p i -mainFooter = - footer - [ classes [ navbar, navbarExpand, ClassName "footer" ] - ] - [ div - [ classes [ navbarNav, mrAuto ] ] - [ makeNavItem $ text "cardano.org" /\ "https://cardano.org/" - , makeNavItem $ text "iohk.io" /\ "https://iohk.io/" - ] - , div - [ classes [ navbarNav ] ] - [ copyright - , nbsp - , text "2020 IOHK Ltd." - ] - , div - [ classes [ navbarNav, mlAuto ] ] - [ makeNavItem $ text "GitHub" /\ "https://github.com/input-output-hk/plutus" - , makeNavItem $ text "Twitter" /\ "https://twitter.com/hashtag/Plutus" - , makeNavItem $ text "Feedback" /\ "https://input-output.typeform.com/to/gQ0t9ep5" - ] - ] - -makeNavItem :: forall p i. HTML p i /\ String -> HTML p i -makeNavItem (label /\ link) = - span - [ classes [ navItem ] ] - [ a - [ class_ navLink - , href link - , target "_blank" - ] - [ label ] - ] - -copyright :: forall p i. HTML p i -copyright = text "\x00A9" diff --git a/plutus-playground-client/src/NavTabs.purs b/plutus-playground-client/src/NavTabs.purs deleted file mode 100644 index 8af92f0ccf..0000000000 --- a/plutus-playground-client/src/NavTabs.purs +++ /dev/null @@ -1,47 +0,0 @@ -module NavTabs where - -import Bootstrap (active, container, hidden, navItem_, navLink, navTabs_) -import Data.String as String -import Halogen.HTML (HTML, a, div, div_, text) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (classes, id) -import Prelude (class Eq, class Show, const, show, ($), (<$>), (<>), (==)) - -mainTabBar - :: forall view r p i - . Eq view - => Show view - => (view -> i) - -> Array - { link :: view - , title :: String - | r - } - -> view - -> HTML p i -mainTabBar mkAction tabs activeView = - div_ - [ navTabs_ (mkTab <$> tabs) ] - where - mkTab { link, title } = - navItem_ - [ a - [ id $ "tab-" <> String.toLower (show link) - , classes $ [ navLink ] <> activeClass - , onClick $ const $ mkAction link - ] - [ text title ] - ] - where - activeClass = - if link == activeView then - [ active ] - else - [] - -viewContainer :: forall view p i. Eq view => view -> view -> Array (HTML p i) -> HTML p i -viewContainer currentView targetView = - if currentView == targetView then - div [ classes [ container ] ] - else - div [ classes [ container, hidden ] ] diff --git a/plutus-playground-client/src/Playground/Gists.purs b/plutus-playground-client/src/Playground/Gists.purs deleted file mode 100644 index 7e68e569dc..0000000000 --- a/plutus-playground-client/src/Playground/Gists.purs +++ /dev/null @@ -1,60 +0,0 @@ -module Playground.Gists - ( mkNewGist - , gistSourceFilename - , gistSimulationFilename - , playgroundGistFile - , simulationGistFile - ) where - -import Cursor (Cursor) -import Data.Argonaut.Extra (encodeStringifyJson) -import Data.Array (catMaybes) -import Data.Array as Array -import Data.Lens (Traversal') -import Data.Lens.Index (ix) -import Data.Maybe (Maybe(..)) -import Data.Newtype (unwrap) -import Gist (Gist, NewGist(NewGist), NewGistFile(NewGistFile), gistFileContent, gistFiles) -import Language.Haskell.Interpreter (SourceCode) -import Playground.Types (Simulation) -import Prelude (($), (<$>), (<<<)) - -mkNewGist - :: { source :: Maybe SourceCode - , simulations :: Cursor Simulation - } - -> Maybe NewGist -mkNewGist { source, simulations } = - if Array.null gistFiles then - Nothing - else - Just - $ NewGist - { _newGistDescription: "Plutus Playground Smart Contract" - , _newGistPublic: true - , _newGistFiles: gistFiles - } - where - gistFiles = - catMaybes - [ mkNewGistFile gistSourceFilename <<< unwrap <$> source - , Just (mkNewGistFile gistSimulationFilename $ encodeStringifyJson simulations) - ] - - mkNewGistFile _newGistFilename _newGistFileContent = - NewGistFile - { _newGistFilename - , _newGistFileContent - } - -gistSourceFilename :: String -gistSourceFilename = "Playground.hs" - -gistSimulationFilename :: String -gistSimulationFilename = "Simulation.json" - -playgroundGistFile :: Traversal' Gist (Maybe String) -playgroundGistFile = gistFiles <<< ix gistSourceFilename <<< gistFileContent - -simulationGistFile :: Traversal' Gist (Maybe String) -simulationGistFile = gistFiles <<< ix gistSimulationFilename <<< gistFileContent diff --git a/plutus-playground-client/src/Playground/Lenses.purs b/plutus-playground-client/src/Playground/Lenses.purs deleted file mode 100644 index 380b378a38..0000000000 --- a/plutus-playground-client/src/Playground/Lenses.purs +++ /dev/null @@ -1,56 +0,0 @@ --- | Misc. useful lenses. -module Playground.Lenses where - -import Data.Function ((<<<)) -import Data.Map (Map) -import Data.Lens (Lens') -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Data.Newtype (class Newtype) -import Type.Proxy (Proxy(..)) -import Ledger.Index.Internal (UtxoIndex, _UtxoIndex) -import Ledger.Tx.Internal (TxOut) -import Plutus.V1.Ledger.Tx (TxId, TxOutRef) -import Plutus.V1.Ledger.Value (CurrencySymbol, TokenName, _CurrencySymbol, _TokenName) - -_currencySymbol :: Lens' CurrencySymbol String -_currencySymbol = _CurrencySymbol <<< prop (Proxy :: _ "unCurrencySymbol") - -_tokenName :: Lens' TokenName String -_tokenName = _TokenName <<< prop (Proxy :: _ "unTokenName") - -_amount :: forall r a. Lens' { amount :: a | r } a -_amount = prop (Proxy :: _ "amount") - -_recipient :: forall r a. Lens' { recipient :: a | r } a -_recipient = prop (Proxy :: _ "recipient") - -_endpointDescription :: forall r a. Lens' { endpointDescription :: a | r } a -_endpointDescription = prop (Proxy :: _ "endpointDescription") - -_getEndpointDescription :: forall s r a. Newtype s { getEndpointDescription :: a | r } => Lens' s a -_getEndpointDescription = _Newtype <<< prop (Proxy :: _ "getEndpointDescription") - -_endpointValue :: forall s r a. Newtype s { unEndpointValue :: a | r } => Lens' s a -_endpointValue = _Newtype <<< prop (Proxy :: _ "unEndpointValue") - -_schema :: forall r a. Lens' { schema :: a | r } a -_schema = prop (Proxy :: _ "schema") - -_txConfirmed :: forall s r a. Newtype s { unTxConfirmed :: a | r } => Lens' s a -_txConfirmed = _Newtype <<< prop (Proxy :: _ "unTxConfirmed") - -_contractInstanceTag :: forall s r a. Newtype s { unContractInstanceTag :: a | r } => Lens' s a -_contractInstanceTag = _Newtype <<< prop (Proxy :: _ "unContractInstanceTag") - -_txId :: Lens' TxId String -_txId = _Newtype <<< prop (Proxy :: _ "getTxId") - -_utxoIndexEntries :: Lens' UtxoIndex (Map TxOutRef TxOut) -_utxoIndexEntries = _UtxoIndex <<< prop (Proxy :: _ "getIndex") - -_aeDescription :: forall s r a. Newtype s { aeDescription :: a | r } => Lens' s a -_aeDescription = _Newtype <<< prop (Proxy :: _ "aeDescription") - -_aeMetadata :: forall s r a. Newtype s { aeMetadata :: a | r } => Lens' s a -_aeMetadata = _Newtype <<< prop (Proxy :: _ "aeMetadata") diff --git a/plutus-playground-client/src/Schema/Types.purs b/plutus-playground-client/src/Schema/Types.purs deleted file mode 100644 index 8f8d78738b..0000000000 --- a/plutus-playground-client/src/Schema/Types.purs +++ /dev/null @@ -1,257 +0,0 @@ -module Schema.Types where - -import Prologue -import Chain.Types (_value) -import Data.Argonaut.Core (Json) -import Data.Argonaut.Encode (encodeJson) -import Data.Array as Array -import Data.BigInt.Argonaut (BigInt) -import Data.Foldable (fold, foldMap) -import Data.Functor.Foldable (Fix(..)) -import Data.Generic.Rep (class Generic) -import Data.Show.Generic (genericShow) -import Data.Lens (_2, _Just, over, set) -import Data.Lens.Index (ix) -import Data.Maybe (fromMaybe) -import Data.Monoid.Additive (Additive(..)) -import Data.Newtype (unwrap) -import Data.RawJson (RawJson) -import Data.String.Extra as String -import Data.Traversable (sequence, traverse) -import Data.Tuple.Nested ((/\)) -import Foreign.Object as FO -import PlutusTx.AssocMap as AssocMap -import Plutus.V1.Ledger.Interval (Extended(..), Interval(..), LowerBound(..), UpperBound(..)) -import Ledger.Slot (Slot) -import Plutus.V1.Ledger.Time (POSIXTime) -import Plutus.V1.Ledger.Value (CurrencySymbol(..), Value(..)) -import Matryoshka (Algebra, ana, cata) -import Playground.Lenses (_recipient, _amount) -import Playground.Types (ContractCall(..), FunctionSchema(..), KnownCurrency(..), _PayToWallet) -import Schema (FormArgumentF(..), FormSchema(..)) -import ValueEditor (ValueEvent(..)) -import Ledger.CardanoWallet (WalletNumber) - -data SimulationAction - = ModifyActions ActionEvent - | PopulateAction Int FormEvent - -derive instance genericSimulationAction :: Generic SimulationAction _ - -instance showSimulationAction :: Show SimulationAction where - show = genericShow - -data FormEvent - = SetField FieldEvent - | SetSubField Int FormEvent - | AddSubField - | RemoveSubField Int - -derive instance genericFormEvent :: Generic FormEvent _ - -instance showFormEvent :: Show FormEvent where - show value = genericShow value - -data FieldEvent - = SetIntField (Maybe Int) - | SetBigIntField (Maybe BigInt) - | SetBoolField Boolean - | SetStringField String - | SetHexField String - | SetRadioField String - | SetValueField ValueEvent - | SetPOSIXTimeRangeField (Interval POSIXTime) - -derive instance genericFieldEvent :: Generic FieldEvent _ - -instance showFieldEvent :: Show FieldEvent where - show = genericShow - -data ActionEvent - = AddAction (ContractCall FormArgument) - | AddWaitAction BigInt - | RemoveAction Int - | SetWaitTime Int BigInt - | SetWaitUntilTime Int Slot - | SetPayToWalletValue Int ValueEvent - | SetPayToWalletRecipient Int WalletNumber - -derive instance genericActionEvent :: Generic ActionEvent _ - -instance showActionEvent :: Show ActionEvent where - show = genericShow - -type Expression = ContractCall RawJson - -type FormArgument = Fix FormArgumentF - -type Signatures = Array (FunctionSchema FormSchema) - -toArgument :: Value -> FormSchema -> FormArgument -toArgument initialValue = ana algebra - where - algebra :: FormSchema -> FormArgumentF FormSchema - algebra FormSchemaUnit = FormUnitF - - algebra FormSchemaBool = FormBoolF false - - algebra FormSchemaInt = FormIntF Nothing - - algebra FormSchemaInteger = FormIntegerF Nothing - - -- text inputs cannot distinguish between `Nothing` and `Just ""` - - -- use the latter as the default value, or validation behaves weirdly - algebra FormSchemaString = FormStringF (Just "") - - algebra FormSchemaHex = FormHexF Nothing - - algebra (FormSchemaRadio xs) = FormRadioF xs Nothing - - algebra (FormSchemaArray xs) = FormArrayF xs [] - - algebra (FormSchemaMaybe x) = FormMaybeF x Nothing - - algebra FormSchemaValue = FormValueF initialValue - - algebra FormSchemaPOSIXTimeRange = FormPOSIXTimeRangeF defaultTimeRange - - algebra (FormSchemaTuple a b) = FormTupleF a b - - algebra (FormSchemaObject xs) = FormObjectF xs - - algebra (FormSchemaUnsupported x) = FormUnsupportedF x - -defaultTimeRange :: Interval POSIXTime -defaultTimeRange = - Interval - { ivFrom: LowerBound NegInf true - , ivTo: UpperBound PosInf true - } - -formArgumentToJson :: FormArgument -> Maybe Json -formArgumentToJson = cata algebra - where - algebra :: Algebra FormArgumentF (Maybe Json) - algebra FormUnitF = Just $ encodeJson (mempty :: Array Unit) - - algebra (FormBoolF b) = Just $ encodeJson b - - algebra (FormIntF n) = encodeJson <$> n - - algebra (FormIntegerF n) = encodeJson <$> n - - algebra (FormStringF str) = encodeJson <$> str - - algebra (FormRadioF _ option) = encodeJson <$> option - - algebra (FormHexF str) = encodeJson <<< String.toHex <$> str - - algebra (FormTupleF (Just fieldA) (Just fieldB)) = Just $ encodeJson [ fieldA, fieldB ] - - algebra (FormTupleF _ _) = Nothing - - algebra (FormMaybeF _ field) = encodeJson <$> field - - algebra (FormArrayF _ fields) = Just $ encodeJson fields - - algebra (FormObjectF fields) = encodeJson <<< FO.fromFoldable <$> traverse sequence fields - - algebra (FormValueF x) = Just $ encodeJson x - - algebra (FormPOSIXTimeRangeF x) = Just $ encodeJson x - - algebra (FormUnsupportedF _) = Nothing - -mkInitialValue :: Array KnownCurrency -> BigInt -> Value -mkInitialValue currencies initialBalance = Value { getValue: value } - where - value = - map (map unwrap) - $ fold - $ foldMap - ( \(KnownCurrency { hash, knownTokens }) -> - map - ( \tokenName -> - AssocMap.Map - [ CurrencySymbol { unCurrencySymbol: hash } - /\ AssocMap.Map [ tokenName /\ Additive initialBalance ] - ] - ) - $ Array.fromFoldable knownTokens - ) - currencies - -handleFormEvent - :: Value - -> FormEvent - -> FormArgument - -> FormArgument -handleFormEvent initialValue event = cata (Fix <<< algebra event) - where - algebra (SetField (SetIntField n)) (FormIntF _) = FormIntF n - - algebra (SetField (SetBigIntField n)) (FormIntegerF _) = FormIntegerF n - - algebra (SetField (SetBoolField n)) (FormBoolF _) = FormBoolF n - - algebra (SetField (SetStringField s)) (FormStringF _) = FormStringF (Just s) - - algebra (SetField (SetHexField s)) (FormHexF _) = FormHexF (Just s) - - algebra (SetField (SetRadioField s)) (FormRadioF options _) = FormRadioF options (Just s) - - algebra (SetField (SetValueField valueEvent)) (FormValueF value) = FormValueF $ handleValueEvent valueEvent value - - algebra (SetField (SetPOSIXTimeRangeField newInterval)) (FormPOSIXTimeRangeF _) = FormPOSIXTimeRangeF newInterval - - algebra (SetSubField 1 subEvent) (FormTupleF field1 field2) = FormTupleF (handleFormEvent initialValue subEvent field1) field2 - - algebra (SetSubField 2 subEvent) (FormTupleF field1 field2) = FormTupleF field1 (handleFormEvent initialValue subEvent field2) - - algebra (SetSubField 0 subEvent) (FormMaybeF schema field) = FormMaybeF schema $ over _Just (handleFormEvent initialValue subEvent) field - - algebra (SetSubField n subEvent) (FormArrayF schema fields) = FormArrayF schema $ over (ix n) (handleFormEvent initialValue subEvent) fields - - algebra (SetSubField n subEvent) (FormObjectF fields) = FormObjectF $ over (ix n <<< _2) (handleFormEvent initialValue subEvent) fields - - -- As the code stands, this is the only guarantee we get that every - -- value in the array will conform to the schema: the fact that we - -- create the 'empty' version from the same schema template. - -- Is more type safety than that possible? Probably. - -- Is it worth the research effort? Perhaps. :thinking_face: - algebra AddSubField (FormArrayF schema fields) = FormArrayF schema $ Array.snoc fields (toArgument initialValue schema) - - algebra AddSubField arg = arg - - algebra (RemoveSubField n) (FormArrayF schema fields) = (FormArrayF schema (fromMaybe fields (Array.deleteAt n fields))) - - algebra _ arg = arg - -handleActionEvent :: ActionEvent -> Array (ContractCall FormArgument) -> Array (ContractCall FormArgument) -handleActionEvent (AddAction action) = flip Array.snoc action - -handleActionEvent (AddWaitAction blocks) = flip Array.snoc (AddBlocks { blocks }) - -handleActionEvent (RemoveAction index) = fromMaybe <*> Array.deleteAt index - -handleActionEvent (SetWaitTime index blocks) = set (ix index) (AddBlocks { blocks }) - -handleActionEvent (SetPayToWalletValue index valueEvent) = over (ix index <<< _PayToWallet <<< _amount) (handleValueEvent valueEvent) - -handleActionEvent (SetPayToWalletRecipient index recipient) = set (ix index <<< _PayToWallet <<< _recipient) recipient - -handleActionEvent (SetWaitUntilTime index slot) = set (ix index) (AddBlocksUntil { slot }) - -handleValueEvent :: ValueEvent -> Value -> Value -handleValueEvent (SetBalance currencySymbol tokenName amount) = set (_value <<< ix currencySymbol <<< ix tokenName) amount - --- | This only exists because of the orphan instance restriction. -traverseFunctionSchema - :: forall m a b - . Applicative m - => (a -> m b) - -> FunctionSchema a - -> m (FunctionSchema b) -traverseFunctionSchema f (FunctionSchema { endpointDescription, argument: oldArgument }) = rewrap <$> f oldArgument - where - rewrap newArgument = FunctionSchema { endpointDescription, argument: newArgument } diff --git a/plutus-playground-client/src/Schema/View.purs b/plutus-playground-client/src/Schema/View.purs deleted file mode 100644 index a57e464654..0000000000 --- a/plutus-playground-client/src/Schema/View.purs +++ /dev/null @@ -1,328 +0,0 @@ -module Schema.View (actionArgumentForm) where - -import Prologue hiding (div) -import Bootstrap (btn, btnInfo, btnLink, btnPrimary, btnSmall, col, col10_, col2_, colFormLabel, formCheckInput, formCheckLabel, formCheck_, formControl, formGroup, formGroup_, formRow_, formText, inputGroupAppend_, inputGroupPrepend_, inputGroup_, invalidFeedback_, row_, textMuted, validFeedback_, wasValidated) -import Bootstrap as Bootstrap -import Data.Array as Array -import Data.BigInt.Argonaut as BigInt -import Data.Functor.Foldable (Fix(..)) -import Data.FunctorWithIndex (mapWithIndex) -import Data.Int as Int -import Data.Lens (Lens', over, set, view) -import Data.Maybe (fromMaybe, maybe) -import Data.String as String -import Data.Tuple.Nested ((/\)) -import Halogen (ClassName(..)) -import Halogen.HTML (HTML, button, code_, div, div_, input, label, small, text) -import Halogen.HTML.Elements.Keyed as Keyed -import Halogen.HTML.Events (onChecked, onClick, onValueInput) -import Halogen.HTML.Properties (IProp, InputType(..), checked, class_, classes, for, id, name, placeholder, required, type_, value) -import Halogen.HTML.Properties as HP -import Icons (Icon(..), icon) -import Ledger.Extra (_LowerBoundExtended, _LowerBoundInclusive, _UpperBoundExtended, _UpperBoundInclusive, _ivFrom, _ivTo, humaniseTimeInterval) -import Plutus.V1.Ledger.Interval (Extended(..), Interval, _Interval) -import Plutus.V1.Ledger.Time (POSIXTime(..)) -import Schema (FormArgumentF(..)) -import Schema.Types (FieldEvent(..), FormArgument, FormEvent(..)) -import Validation (ValidationError, WithPath, joinPath, showPathValue, validate) -import ValueEditor (valueForm) - --- TODO Handle the Unsupported case. --- TODO Handle the FormMaybe case. --- TODO Force Hex fields to comply to [0-9a-fA-F]. -actionArgumentForm - :: forall p i - . Int - -> (FormEvent -> i) - -> FormArgument - -> HTML p i -actionArgumentForm index wrapper argument = - div [ class_ wasValidated ] - [ wrapper <$> actionArgumentField [ show index ] false argument ] - -actionArgumentField - :: forall p - . Array String - -> Boolean - -> FormArgument - -> HTML p FormEvent -actionArgumentField _ _ (Fix FormUnitF) = Bootstrap.empty - -actionArgumentField ancestors _ arg@(Fix (FormBoolF b)) = - formCheck_ - [ input - [ type_ InputCheckbox - , id elementId - , classes (Array.cons formCheckInput (actionArgumentClass ancestors)) - , checked b - , onChecked (SetField <<< SetBoolField) - ] - , label - [ class_ formCheckLabel - , for elementId - ] - [ text (if b then "True" else "False") ] - , validationFeedback (joinPath ancestors <$> validate arg) - ] - where - elementId = String.joinWith "-" ancestors - -actionArgumentField ancestors _ arg@(Fix (FormIntF n)) = - div_ - [ input - [ type_ InputNumber - , classes (Array.cons formControl (actionArgumentClass ancestors)) - , value $ maybe "" show n - , required true - , placeholder "Int" - , onValueInput (SetField <<< SetIntField <<< Int.fromString) - ] - , validationFeedback (joinPath ancestors <$> validate arg) - ] - -actionArgumentField ancestors _ arg@(Fix (FormIntegerF n)) = - div_ - [ input - [ type_ InputNumber - , classes (Array.cons formControl (actionArgumentClass ancestors)) - , value $ maybe "" BigInt.toString n - , required true - , placeholder "Integer" - , onValueInput (SetField <<< SetBigIntField <<< BigInt.fromString) - ] - , validationFeedback (joinPath ancestors <$> validate arg) - ] - -actionArgumentField ancestors _ arg@(Fix (FormStringF s)) = - div_ - [ input - [ type_ InputText - , classes (Array.cons formControl (actionArgumentClass ancestors)) - , value $ fromMaybe "" s - -- empty text inputs give `Just ""` as a value, which might be wanted, - -- so don't mark these fields as required - , required false - , placeholder "String" - , onValueInput (SetField <<< SetStringField) - ] - , validationFeedback (joinPath ancestors <$> validate arg) - ] - -actionArgumentField ancestors _ arg@(Fix (FormRadioF options s)) = - formGroup_ - [ div_ (radioItem <$> options) - , validationFeedback (joinPath ancestors <$> validate arg) - ] - where - radioItem :: String -> HTML p FormEvent - radioItem option = - let - elementId = String.joinWith "-" (ancestors <> [ option ]) - in - formCheck_ - [ input - [ type_ InputRadio - , id elementId - , classes (Array.cons formCheckInput (actionArgumentClass ancestors)) - , name option - , value option - , required (s == Nothing) - , onValueInput (SetField <<< SetRadioField) - , checked (Just option == s) - ] - , label - [ class_ formCheckLabel - , for elementId - ] - [ text option ] - ] - -actionArgumentField ancestors _ arg@(Fix (FormHexF s)) = - div_ - [ input - [ type_ InputText - , classes (Array.cons formControl (actionArgumentClass ancestors)) - , value $ fromMaybe "" s - , required true - , placeholder "String" - , onValueInput (SetField <<< SetHexField) - ] - , validationFeedback (joinPath ancestors <$> validate arg) - ] - -actionArgumentField ancestors _ (Fix (FormTupleF subFieldA subFieldB)) = - div_ - [ formGroup_ - [ SetSubField 1 <$> actionArgumentField (Array.snoc ancestors "_1") true subFieldA ] - , formGroup_ - [ SetSubField 2 <$> actionArgumentField (Array.snoc ancestors "_2") true subFieldB ] - ] - -actionArgumentField ancestors isNested (Fix (FormArrayF _ subFields)) = - div_ - [ Keyed.div [ nesting isNested ] - (mapWithIndex subFormContainer subFields) - , button - [ classes [ btn, btnInfo ] - , onClick $ const AddSubField - ] - [ icon Plus ] - ] - where - subFormContainer i field = - show i - /\ formGroup_ - [ row_ - [ col10_ - [ SetSubField i <$> actionArgumentField (Array.snoc ancestors (show i)) true field ] - , col2_ - [ button - [ classes [ btn, btnLink ] - , onClick $ const $ RemoveSubField i - ] - [ icon Trash ] - ] - ] - ] - -actionArgumentField ancestors isNested (Fix (FormObjectF subFields)) = - div [ nesting isNested ] - (mapWithIndex (\i field -> map (SetSubField i) (subForm field)) subFields) - where - subForm (name /\ arg) = - ( formGroup_ - [ label [ for name ] [ text name ] - , actionArgumentField (Array.snoc ancestors name) true arg - ] - ) - -actionArgumentField _ isNested (Fix (FormPOSIXTimeRangeF interval)) = - div [ class_ formGroup, nesting isNested ] - [ label [ for "interval" ] [ text "Interval" ] - , formRow_ - [ label [ for "ivFrom", classes [ col, colFormLabel ] ] [ text "From" ] - , label [ for "ivTo", classes [ col, colFormLabel ] ] [ text "To" ] - ] - , formRow_ - [ let - extensionLens :: Lens' (Interval POSIXTime) (Extended POSIXTime) - extensionLens = _Interval <<< _ivFrom <<< _LowerBoundExtended - - inclusionLens :: Lens' (Interval POSIXTime) Boolean - inclusionLens = _Interval <<< _ivFrom <<< _LowerBoundInclusive - in - div [ classes [ col, extentFieldClass ] ] - [ inputGroup_ - [ inputGroupPrepend_ - [ extentFieldExtendedButton extensionLens NegInf - , extentFieldInclusionButton inclusionLens StepBackward Reverse - ] - , extentFieldInput extensionLens - ] - ] - , let - extensionLens :: Lens' (Interval POSIXTime) (Extended POSIXTime) - extensionLens = _Interval <<< _ivTo <<< _UpperBoundExtended - - inclusionLens :: Lens' (Interval POSIXTime) Boolean - inclusionLens = _Interval <<< _ivTo <<< _UpperBoundInclusive - in - div [ classes [ col, extentFieldClass ] ] - [ inputGroup_ - [ extentFieldInput extensionLens - , inputGroupAppend_ - [ extentFieldInclusionButton inclusionLens StepForward Play - , extentFieldExtendedButton extensionLens PosInf - ] - ] - ] - ] - , small - [ classes [ formText, textMuted ] ] - [ text $ humaniseTimeInterval interval - ] - ] - where - extentFieldClass = ClassName "extent-field" - - extentFieldInclusionButton :: Lens' (Interval POSIXTime) Boolean -> Icon -> Icon -> HTML p FormEvent - extentFieldInclusionButton inclusionLens inclusionIcon exclusionIcon = - button - [ classes [ btn, btnSmall, btnPrimary ] - , onClick $ const $ SetField $ SetPOSIXTimeRangeField $ over inclusionLens not interval - ] - [ icon - $ - if view inclusionLens interval then - inclusionIcon - else - exclusionIcon - ] - - extentFieldExtendedButton :: Lens' (Interval POSIXTime) (Extended POSIXTime) -> Extended POSIXTime -> HTML p FormEvent - extentFieldExtendedButton extensionLens value = - button - [ classes - [ btn - , btnSmall - , if view extensionLens interval == value then - btnPrimary - else - btnInfo - ] - , onClick $ const $ SetField $ SetPOSIXTimeRangeField $ set extensionLens value interval - ] - [ icon Infinity ] - - extentFieldInput :: Lens' (Interval POSIXTime) (Extended POSIXTime) -> HTML p FormEvent - extentFieldInput extensionLens = - input - [ type_ InputNumber - , class_ formControl - , HP.min zero - , value - $ case view extensionLens interval of - Finite (POSIXTime time) -> show time.getPOSIXTime - _ -> mempty - , onValueInput $ BigInt.fromString - >>> case _ of - Just n -> - SetField - $ SetPOSIXTimeRangeField - $ set extensionLens (Finite (POSIXTime { getPOSIXTime: n })) interval - Nothing -> SetField $ SetPOSIXTimeRangeField interval - ] - -actionArgumentField _ isNested (Fix (FormValueF value)) = - div - [ nesting isNested ] - [ valueForm (SetField <<< SetValueField) value ] - -actionArgumentField _ _ (Fix (FormMaybeF dataType child)) = - div_ - [ text "Unsupported Maybe" - , code_ [ text $ show dataType ] - , code_ [ text $ show child ] - ] - -actionArgumentField _ _ (Fix (FormUnsupportedF description)) = - div_ - [ text "Unsupported" - , code_ [ text description ] - ] - -actionArgumentClass :: Array String -> Array ClassName -actionArgumentClass ancestors = - [ ClassName "action-argument" - , ClassName $ "action-argument-" <> Array.intercalate "-" ancestors - ] - -validationFeedback :: forall p i. Array (WithPath ValidationError) -> HTML p i -validationFeedback [] = validFeedback_ [] - -validationFeedback errors = invalidFeedback_ (div_ <<< pure <<< text <<< showPathValue <$> errors) - -nesting :: forall r i. Boolean -> IProp ("class" :: String | r) i -nesting true = classes [ ClassName "nested" ] - -nesting false = classes [] diff --git a/plutus-playground-client/src/Simulator/View.purs b/plutus-playground-client/src/Simulator/View.purs deleted file mode 100644 index 79f5eace16..0000000000 --- a/plutus-playground-client/src/Simulator/View.purs +++ /dev/null @@ -1,225 +0,0 @@ -module Simulator.View - ( simulatorTitle - , simulationsPane - , simulationsNav - , simulatorTitleRefLabel - , simulationsErrorRefLabel - ) where - -import Action.View (actionsPane) -import Action.Validation (actionIsValid) -import Bootstrap (active, alertDanger_, btn, empty, floatRight, nav, navItem, navLink) -import Component.ErrorPane (errorPane) -import Cursor (Cursor, current) -import Cursor as Cursor -import Data.Array as Array -import Data.Either (Either(..)) -import Data.Lens (_Right, view) -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Maybe (Maybe(..)) -import Data.String as String -import Halogen (RefLabel(RefLabel)) -import Halogen.HTML (ClassName(ClassName), HTML, a, button, code_, div, div_, h1_, li, p_, pre_, span, text, ul) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (class_, classes, disabled, id, ref) -import Icons (Icon(..), icon) -import Language.Haskell.Interpreter (CompilationError(..)) -import Language.Haskell.Interpreter as PI -import Plutus.V1.Ledger.Value (Value) -import Network.RemoteData (RemoteData(..), _Success) -import MainFrame.Lenses (_functionSchema, _result) -import MainFrame.Types (FullSimulation, HAction(..), View(..), SimulatorAction, WebCompilationResult, WebEvaluationResult) -import Playground.Types (PlaygroundError(..), Simulation(..), SimulatorWallet) -import Prelude (const, not, pure, show, (#), ($), (<$>), (<<<), (<>), (==), (>)) -import Wallet.View (walletsPane) - -simulatorTitle :: forall p. HTML p HAction -simulatorTitle = - div - [ class_ $ ClassName "main-header" - , ref simulatorTitleRefLabel - ] - [ h1_ [ text "Simulator" ] - , a - [ class_ btn - , onClick $ const $ ChangeView Editor - ] - [ text "< Return to Editor" ] - ] - -simulationsPane :: forall p. Value -> Maybe Int -> WebCompilationResult -> Cursor FullSimulation -> HTML p HAction -simulationsPane initialValue actionDrag compilationResult simulations = case current simulations of - Just { simulation: Simulation { simulationWallets, simulationActions }, evaluationResult } -> - div - [ class_ $ ClassName "simulations" ] - [ simulationsNav simulations - , div - [ class_ $ ClassName "simulation" ] - [ div - [ classes [ ClassName "simulation-controls", floatRight ] ] - [ evaluateActionsButton simulationWallets simulationActions evaluationResult - , viewTransactionsButton evaluationResult - ] - , walletsPane endpointSignatures initialValue simulationWallets - , actionsPane actionDrag simulationWallets simulationActions - , div - [ classes [ ClassName "simulation-controls" ] ] - [ evaluateActionsButton simulationWallets simulationActions evaluationResult - , viewTransactionsButton evaluationResult - ] - , case evaluationResult of - Failure error -> errorPane error - Success (Left error) -> actionsErrorPane error - _ -> empty - ] - ] - Nothing -> - div - [ class_ $ ClassName "simulations" ] - [ p_ [ text "Return to the Editor and compile a contract to get started." ] ] - where - endpointSignatures = view (_Success <<< _Right <<< _Newtype <<< _result <<< _functionSchema) compilationResult - -simulationsNav :: forall p. Cursor FullSimulation -> HTML p HAction -simulationsNav simulations = - ul - [ classes [ nav, ClassName "nav-tabs" ] - ] - ( ( simulations - # Cursor.mapWithIndex (simulationNavItem (Cursor.length simulations > 1) (Cursor.getIndex simulations)) - # Cursor.toArray - # Array.concat - ) - <> [ addSimulationControl ] - ) - -simulationNavItem :: forall p. Boolean -> Int -> Int -> FullSimulation -> Array (HTML p HAction) -simulationNavItem canClose activeIndex index { simulation: Simulation { simulationName } } = - [ li - [ id $ "simulation-nav-item-" <> show index - , class_ navItem - ] - [ a - [ classes navLinkClasses - , onClick $ const $ SetSimulationSlot index - ] - [ text simulationName ] - , if canClose then - button - [ classes [ btn, navItemButtonClass ] - , onClick $ const $ RemoveSimulationSlot index - ] - [ icon Close ] - else - empty - ] - ] - where - navLinkClasses = if activeIndex == index then [ navLink, active ] else [ navLink ] - -addSimulationControl :: forall p. HTML p HAction -addSimulationControl = - li - [ id "simulation-nav-item-add" - , class_ navItem - ] - [ span - [ class_ navLink ] - [ button - [ classes [ btn, navItemButtonClass ] - , onClick $ const $ AddSimulationSlot - ] - [ icon Plus ] - ] - ] - -evaluateActionsButton :: forall p. Array SimulatorWallet -> Array SimulatorAction -> WebEvaluationResult -> HTML p HAction -evaluateActionsButton simulationWallets simulationActions evaluationResult = - button - [ classes [ btn, ClassName "btn-green" ] - , disabled $ not valid - , onClick $ const EvaluateActions - ] - [ btnText evaluationResult valid ] - where - valid = (Array.all <<< actionIsValid) simulationWallets simulationActions - - btnText Loading _ = icon Spinner - - btnText _ false = text "Fix Errors" - - btnText _ _ = text "Evaluate" - -viewTransactionsButton :: forall p. WebEvaluationResult -> HTML p HAction -viewTransactionsButton evaluationResult = - button - [ classes [ btn, ClassName "btn-turquoise" ] - , disabled isDisabled - , onClick $ const $ ChangeView Transactions - ] - [ text "Transactions" ] - where - isDisabled = case evaluationResult of - Success _ -> false - _ -> true - -actionsErrorPane :: forall p i. PlaygroundError -> HTML p i -actionsErrorPane error = - div - [ class_ $ ClassName "error-pane" - , ref simulationsErrorRefLabel - ] - [ alertDanger_ - ( (div_ <<< pure) - <$> (showPlaygroundError error <> [ text "Please try again or contact support for assistance." ]) - ) - ] - ------------------------------------------------------------- --- | There's a few errors that make sense to display nicely, others should not occur so lets --- | not deal with them. -showPlaygroundError :: forall p i. PlaygroundError -> Array (HTML p i) -showPlaygroundError (CompilationErrors errors) = - [ text "Compilation Errors" ] - <> (showCompilationError <$> errors) - -showPlaygroundError (InterpreterError (PI.TimeoutError error)) = - [ text "Interpreter Timed Out" - , code_ [ text error ] - ] - -showPlaygroundError (InterpreterError (PI.CompilationErrors errors)) = - [ text "Interpreter Errors" ] - <> (showCompilationError <$> errors) - -showPlaygroundError (RollupError error) = - [ text "Error Calculating Final Blockchain State" - , code_ [ text error ] - ] - -showPlaygroundError (OtherError error) = - [ text "Unknown Evaluation Error" - , code_ [ text error ] - ] - -showPlaygroundError (JsonDecodingError { expected, decodingError, input }) = - [ text "Decoding Error" - , code_ [ text $ "Expected: " <> expected ] - , code_ [ text $ "Error: " <> decodingError ] - , code_ [ text $ "Input: " <> input ] - ] - -showCompilationError :: forall p i. CompilationError -> HTML p i -showCompilationError (RawError error) = code_ [ text error ] - -showCompilationError (CompilationError { text: errors }) = pre_ [ text (String.joinWith "\n" errors) ] - ------------------------------------------------------------- -simulatorTitleRefLabel :: RefLabel -simulatorTitleRefLabel = RefLabel "simulations" - -simulationsErrorRefLabel :: RefLabel -simulationsErrorRefLabel = RefLabel "simulation-errors" - -navItemButtonClass :: ClassName -navItemButtonClass = ClassName "simulation-nav-item-control" diff --git a/plutus-playground-client/src/StaticData.purs b/plutus-playground-client/src/StaticData.purs deleted file mode 100644 index 2785f29342..0000000000 --- a/plutus-playground-client/src/StaticData.purs +++ /dev/null @@ -1,35 +0,0 @@ -module StaticData - ( mkContractDemos - , lookupContractDemo - , bufferLocalStorageKey - , keybindingsLocalStorageKey - ) where - -import Prologue -import Data.Argonaut.Decode (JsonDecodeError) -import Data.Argonaut.Extra (parseDecodeJson) -import Data.Foldable as Foldable -import Data.Lens (Lens', view) -import Data.Lens.Iso.Newtype (_Newtype) -import Data.Lens.Record (prop) -import Type.Proxy (Proxy(..)) -import Data.Traversable (class Foldable) -import LocalStorage (Key(..)) -import Playground.Types (ContractDemo) -import Playground.Usecases (contractDemos) - -mkContractDemos :: Either JsonDecodeError (Array ContractDemo) -mkContractDemos = do - parseDecodeJson contractDemos - -lookupContractDemo :: forall f. Foldable f => String -> f ContractDemo -> Maybe ContractDemo -lookupContractDemo key = Foldable.find (\demo -> view _contractDemoName demo == key) - -_contractDemoName :: Lens' ContractDemo String -_contractDemoName = _Newtype <<< prop (Proxy :: _ "contractDemoName") - -bufferLocalStorageKey :: Key -bufferLocalStorageKey = Key "PlutusPlaygroundBuffer" - -keybindingsLocalStorageKey :: Key -keybindingsLocalStorageKey = Key "EditorPreferences.KeyBindings" diff --git a/plutus-playground-client/src/Transaction/View.purs b/plutus-playground-client/src/Transaction/View.purs deleted file mode 100644 index b90939eca5..0000000000 --- a/plutus-playground-client/src/Transaction/View.purs +++ /dev/null @@ -1,263 +0,0 @@ -module Transaction.View - ( evaluationPane - , extractAmount - ) where - -import Bootstrap (btn, nbsp) -import Chain.Types (State, _value) -import Chain.View (chainView) -import Chartist (ChartistData, ChartistItem, ChartistOptions, ChartistPoint, toChartistData) -import Chartist as Chartist -import Data.Array as Array -import Data.Array.Extra (collapse) -import Data.BigInt.Argonaut (BigInt) -import Data.BigInt.Argonaut as BigInt -import Data.Lens (_2, preview, to, toListOf, traversed, view) -import Data.Lens.Index (ix) -import Data.List (List) -import Data.Maybe (Maybe, fromMaybe) -import Data.Newtype (wrap) -import Data.Semiring (zero) -import Data.Set (Set) -import Data.Set as Set -import Data.Tuple (Tuple(Tuple)) -import Data.Tuple.Nested ((/\)) -import Effect.Aff.Class (class MonadAff) -import Halogen (ComponentHTML) -import Halogen.Chartist (chartist) -import Halogen.HTML (ClassName(ClassName), HTML, button, br_, code_, div, div_, h2_, h3_, p_, pre_, slot, text) -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (class_, classes) -import Icons (Icon(..), icon) -import PlutusTx.AssocMap as AssocMap -import MainFrame.Lenses (_balancesChartSlot) -import MainFrame.Types (ChildSlots, HAction(..), View(..)) -import Playground.Lenses (_tokenName, _contractInstanceTag) -import Playground.Types (EvaluationResult(EvaluationResult), SimulatorWallet) -import Plutus.Trace.Emulator.Types (ContractInstanceLog(..)) -import Ledger.Address (PaymentPubKeyHash(..)) -import Ledger.Slot (Slot(..)) -import Plutus.V1.Ledger.Tx (TxId(TxId)) -import Plutus.V1.Ledger.Value (CurrencySymbol, TokenName) -import Prelude (const, map, show, unit, ($), (<$>), (<<<), (<>)) -import Wallet.Emulator.Chain (ChainEvent(..)) -import Plutus.ChainIndex.ChainIndexLog (ChainIndexLog(..)) -import Wallet.Emulator.MultiAgent (EmulatorEvent'(..)) -import Wallet.Emulator.MultiAgent as MultiAgent -import Wallet.Emulator.NodeClient (NodeClientEvent(..)) -import Wallet.Emulator.Wallet (Wallet(..), WalletEvent(..)) -import Wallet.Lenses (_simulatorWalletBalance, _simulatorWalletWallet, _walletId) - -evaluationPane :: forall m. MonadAff m => State -> EvaluationResult -> ComponentHTML HAction ChildSlots m -evaluationPane state (EvaluationResult { emulatorLog, emulatorTrace, fundsDistribution, resultRollup, walletKeys }) = - div - [ class_ $ ClassName "transactions" ] - [ div - [ class_ $ ClassName "transactions-header" ] - [ h2_ [ text "Transactions" ] - , button - [ classes [ btn ] - , onClick $ const $ ChangeView Simulations - ] - [ icon Close ] - ] - , ChainAction <$> chainView namingFn state (wrap resultRollup) - , div - [ class_ $ ClassName "final-balances" ] - [ h3_ [ text "Final Balances" ] - , slot - _balancesChartSlot - unit - (chartist balancesChartOptions) - (balancesToChartistData fundsDistribution) - HandleBalancesChartMessage - ] - , div - [ class_ $ ClassName "logs" ] - [ h3_ [ text "Logs" ] - , case emulatorLog of - [] -> p_ [ text "No logs to display." ] - logs -> pre_ ((emulatorEventPane <<< eveEvent) <$> logs) - ] - , div - [ class_ $ ClassName "trace" ] - [ h3_ [ text "Trace" ] - , code_ [ pre_ [ text emulatorTrace ] ] - ] - ] - where - namingFn pkh = - preview - ( ix (PaymentPubKeyHash { unPaymentPubKeyHash: pkh }) - <<< _walletId - <<< to (\n -> "Wallet " <> BigInt.toString n) - ) - (AssocMap.Map walletKeys) - -eveEvent :: forall a. MultiAgent.EmulatorTimeEvent a -> a -eveEvent (MultiAgent.EmulatorTimeEvent { _eteEvent }) = _eteEvent - -emulatorEventPane :: forall i p. EmulatorEvent' -> HTML p i -emulatorEventPane (ChainIndexEvent _ (InsertionSuccess tip p)) = - div_ - [ text $ "Chain index successful insertion: New tip is " - <> show tip - <> ". " - <> show p - ] - -emulatorEventPane (ChainIndexEvent _ (RollbackSuccess tip)) = - div_ - [ text $ "Chain index successful rollback. New tip is" - <> show tip - ] - -emulatorEventPane (ChainIndexEvent _ (Err ciError)) = - div_ - [ text $ "Chain index error: " - <> show ciError - ] - -emulatorEventPane (ChainIndexEvent _ (TxNotFound txid)) = - div_ - [ text $ "Transaction not found with id " - <> show txid - ] - -emulatorEventPane (ChainIndexEvent _ (TxOutNotFound ref)) = - div_ - [ text $ "Transaction output not from reference " - <> show ref - ] - -emulatorEventPane (ChainIndexEvent _ TipIsGenesis) = - div_ - [ text $ "Chain index tip is genesis" - ] - -emulatorEventPane (ChainIndexEvent _ (NoDatumScriptAddr txout)) = - div_ - [ text $ "The following transaction output from script address does not have a datum: " - <> show txout - ] - -emulatorEventPane (ClientEvent _ (TxSubmit (TxId txId) _)) = - div_ - [ text $ "Submitting transaction: " <> txId.getTxId ] - -emulatorEventPane (ChainEvent (TxnValidate (TxId txId) _ _)) = - div_ - [ text $ "Validating transaction: " <> txId.getTxId ] - -emulatorEventPane (ChainEvent (TxnValidationFail _ (TxId txId) _ error _ _)) = - div [ class_ $ ClassName "error" ] - [ text $ "Validation failed: " <> txId.getTxId - , br_ - , nbsp - , text $ show error - ] - -emulatorEventPane (ChainEvent (SlotAdd (Slot slot))) = - div [ class_ $ ClassName "info" ] - [ text $ "Add slot " <> BigInt.toString slot.getSlot ] - --- TODO: convert Wallet back to WalletNumber? -emulatorEventPane (WalletEvent (Wallet walletId) (GenericLog logMessageText)) = - div [ class_ $ ClassName "error" ] - [ text $ "Message from wallet " <> show walletId.getWalletId <> ": " <> logMessageText ] - -emulatorEventPane (WalletEvent (Wallet walletId) logMessage) = - div [ class_ $ ClassName "error" ] - [ text $ "Message from wallet " <> show walletId.getWalletId <> ": " <> show logMessage ] - -emulatorEventPane (InstanceEvent (ContractInstanceLog { _cilMessage, _cilTag })) = - div_ - [ text $ (view _contractInstanceTag _cilTag) <> ": " <> show _cilMessage ] - --- TODO: Figure out which of the remaining log messages we want to display. --- (Note that most of the remaining log messages aren't produced at the --- default "info" log level, so we're unlikely to see them here in the frontend --- anyway). -emulatorEventPane _ = div [] [] - ------------------------------------------------------------- -formatWalletId :: SimulatorWallet -> String -formatWalletId wallet = "Wallet " <> BigInt.toString (view (_simulatorWalletWallet <<< _walletId) wallet) - -extractAmount :: Tuple CurrencySymbol TokenName -> SimulatorWallet -> Maybe BigInt -extractAmount (Tuple currencySymbol tokenName) = - preview - ( _simulatorWalletBalance - <<< _value - <<< ix currencySymbol - <<< ix tokenName - ) - -balancesToChartistData :: Array SimulatorWallet -> ChartistData -balancesToChartistData wallets = toChartistData $ toChartistItem <$> wallets - where - toChartistItem :: SimulatorWallet -> ChartistItem - toChartistItem wallet = - { label: formatWalletId wallet - , points: toChartistPoint wallet <$> Set.toUnfoldable allCurrencies - } - - toChartistPoint :: SimulatorWallet -> Tuple CurrencySymbol TokenName -> ChartistPoint - toChartistPoint wallet key = - { meta: view (_2 <<< _tokenName) key - , value: BigInt.toNumber $ fromMaybe zero $ extractAmount key wallet - } - - allValues :: List (AssocMap.Map CurrencySymbol (AssocMap.Map TokenName BigInt)) - allValues = - toListOf - ( traversed - <<< _simulatorWalletBalance - <<< _value - ) - wallets - - allCurrencies :: Set (Tuple CurrencySymbol TokenName) - allCurrencies = - Set.fromFoldable - $ map (\(c /\ t /\ _) -> c /\ t) - $ Array.concat - $ map collapse - $ Array.fromFoldable allValues - -balancesChartOptions :: ChartistOptions -balancesChartOptions = - { seriesBarDistance: 45 - , chartPadding: - { top: 30 - , bottom: 30 - , right: 30 - , left: 30 - } - , axisY: Chartist.intAutoScaleAxis - , plugins: - [ Chartist.tooltipPlugin - , Chartist.axisTitlePlugin - { axisX: - { axisTitle: "Wallet" - , axisClass: "ct-x-axis-title" - , offset: - { x: 0 - , y: 40 - } - , textAnchor: "middle" - , flipTitle: false - } - , axisY: - { axisTitle: "Final Balance" - , axisClass: "ct-y-axis-title" - , offset: - { x: 0 - , y: 30 - } - , textAnchor: "middle" - , flipTitle: true - } - } - ] - } diff --git a/plutus-playground-client/src/Validation.purs b/plutus-playground-client/src/Validation.purs deleted file mode 100644 index f03f9788f4..0000000000 --- a/plutus-playground-client/src/Validation.purs +++ /dev/null @@ -1,128 +0,0 @@ -module Validation where - -import Prologue -import Data.Array (elem, mapWithIndex) -import Data.Array as Array -import Data.Foldable (class Foldable) -import Data.Functor.Foldable (Fix) -import Data.Generic.Rep (class Generic) -import Data.Lens (Lens', view) -import Data.Lens.Record (prop) -import Type.Proxy (Proxy(..)) -import Matryoshka (Algebra, cata) -import Playground.Types (ContractCall(..), _FunctionSchema) -import Schema (FormArgumentF(..)) - -isValid :: forall a. Validation a => a -> Boolean -isValid = Array.null <<< validate - -class Validation a where - validate :: a -> Array (WithPath ValidationError) - -data ValidationError - = Required - | Invalid - | Unsupported - -derive instance eqValidationError :: Eq ValidationError - -derive instance genericValidationError :: Generic ValidationError _ - -instance showValidationError :: Show ValidationError where - show Required = "Required" - show Invalid = "Invalid" - show Unsupported = "Unsupported" - ------------------------------------------------------------- -newtype WithPath a = WithPath { path :: Array String, value :: a } - -derive instance eqWithPath :: Eq a => Eq (WithPath a) - -derive instance functorWithPath :: Functor WithPath - -instance showWithPath :: Show a => Show (WithPath a) where - show (WithPath { path, value }) = Array.intercalate "." path <> ": " <> show value - -showPathValue :: forall a. Show a => WithPath a -> String -showPathValue (WithPath { value }) = show value - -noPath :: forall a. a -> WithPath a -noPath value = WithPath { path: [], value } - -withPath :: forall a f. Foldable f => f String -> a -> WithPath a -withPath path value = WithPath { path: Array.fromFoldable path, value } - -addPath :: forall a. String -> WithPath a -> WithPath a -addPath parent (WithPath { path, value }) = WithPath { path: Array.cons parent path, value } - -joinPath :: forall a. Array String -> WithPath a -> WithPath a -joinPath ancestors (WithPath { path, value }) = WithPath { path: ancestors <> path, value } - ------------------------------------------------------------- -instance formArgumentValidation :: Validation (Fix FormArgumentF) where - validate = cata algebra - where - algebra :: Algebra FormArgumentF (Array (WithPath ValidationError)) - algebra (FormUnitF) = [] - - algebra (FormBoolF _) = [] - - algebra (FormIntF (Just _)) = [] - - algebra (FormIntF Nothing) = [ noPath Required ] - - algebra (FormIntegerF (Just _)) = [] - - algebra (FormIntegerF Nothing) = [ noPath Required ] - - algebra (FormStringF (Just _)) = [] - - algebra (FormStringF Nothing) = [ noPath Required ] - - algebra (FormHexF (Just _)) = [] - - algebra (FormHexF Nothing) = [ noPath Required ] - - algebra (FormRadioF options (Just x)) = - if x `elem` options then - [] - else - [ noPath Invalid ] - - algebra (FormRadioF _ Nothing) = [ noPath Required ] - - algebra (FormTupleF xs ys) = - Array.concat - [ addPath "_1" <$> xs - , addPath "_2" <$> ys - ] - - algebra (FormMaybeF _ Nothing) = [ noPath Required ] - - algebra (FormMaybeF _ (Just x)) = addPath "_Just" <$> x - - algebra (FormArrayF _ xs) = Array.concat $ mapWithIndex (\i values -> addPath (show i) <$> values) xs - - algebra (FormObjectF xs) = Array.concat $ map (\(Tuple name values) -> addPath name <$> values) xs - - algebra (FormValueF _) = [] - - algebra (FormPOSIXTimeRangeF _) = [] - - algebra (FormUnsupportedF _) = [ noPath Unsupported ] - ------------------------------------------------------------- -instance simulatorActionValidation :: Validation (ContractCall (Fix FormArgumentF)) where - validate (AddBlocks _) = [] - validate (AddBlocksUntil _) = [] - validate (PayToWallet _) = [] - validate (CallEndpoint call) = validate arg - where - arg :: Fix FormArgumentF - arg = view (_argumentValues <<< _FunctionSchema <<< _argument) call - -_argument :: forall r a. Lens' { argument :: a | r } a -_argument = prop (Proxy :: _ "argument") - -_argumentValues :: forall r a. Lens' { argumentValues :: a | r } a -_argumentValues = prop (Proxy :: _ "argumentValues") diff --git a/plutus-playground-client/src/ValueEditor.purs b/plutus-playground-client/src/ValueEditor.purs deleted file mode 100644 index 2422dbde5d..0000000000 --- a/plutus-playground-client/src/ValueEditor.purs +++ /dev/null @@ -1,99 +0,0 @@ -module ValueEditor where - -import Prelude hiding (div, min) -import Bootstrap (col, colFormLabel, col_, formControl, formGroup, formRow_) -import Data.Array (mapWithIndex) -import Data.Array as Array -import Data.BigInt.Argonaut (BigInt) -import Data.BigInt.Argonaut as BigInt -import Data.Generic.Rep (class Generic) -import Data.Show.Generic (genericShow) -import Data.Lens (view) -import Data.Maybe (fromMaybe) -import Data.Newtype (unwrap) -import Data.Tuple (Tuple(..), fst) -import Data.Tuple.Nested ((/\)) -import Halogen.HTML (ClassName(ClassName), HTML, div, input, label, text) -import Halogen.HTML.Elements.Keyed as Keyed -import Halogen.HTML.Events (onValueInput) -import Halogen.HTML.Properties (InputType(InputNumber), classes, min, placeholder, required, type_, value) -import PlutusTx.AssocMap as AssocMap -import Plutus.V1.Ledger.Value (CurrencySymbol, TokenName, Value(Value)) -import Playground.Lenses (_currencySymbol, _tokenName) - -data ValueEvent = SetBalance CurrencySymbol TokenName BigInt - -derive instance genericValueEvent :: Generic ValueEvent _ - -instance showValueEvent :: Show ValueEvent where - show = genericShow - -valueForm :: forall p i. (ValueEvent -> i) -> Value -> HTML p i -valueForm handler (Value { getValue: balances }) = - Keyed.div_ - ( Array.concat - ( mapWithIndex (currencyRow handler) - ( Array.sortWith fst - $ unwrap balances - ) - ) - ) - -currencyRow - :: forall p i - . (ValueEvent -> i) - -> Int - -> Tuple CurrencySymbol (AssocMap.Map TokenName BigInt) - -> Array (Tuple String (HTML p i)) -currencyRow handler currencyIndex (Tuple currencySymbol tokenBalances) = - mapWithIndex (balanceRow handler currencyIndex currencySymbol) - (Array.sortWith fst $ unwrap tokenBalances) - -balanceRow - :: forall p i - . (ValueEvent -> i) - -> Int - -> CurrencySymbol - -> Int - -> Tuple TokenName BigInt - -> Tuple String (HTML p i) -balanceRow handler currencyIndex currencySymbol tokenIndex (Tuple tokenName amount) = - (show currencyIndex <> "-" <> show tokenIndex) - /\ div - [ classes - [ formGroup - , ClassName "balance" - , ClassName ("balance-" <> show currencyIndex <> show tokenIndex) - ] - ] - [ formRow_ - $ - [ label - [ classes [ col, colFormLabel ] ] - [ text - $ case view _currencySymbol currencySymbol, view _tokenName tokenName of - "", "" -> "Lovelace" - _, other -> other - ] - , col_ - [ input - [ type_ InputNumber - , classes [ formControl, ClassName "balance-amount" ] - , value $ BigInt.toString amount - , required true - , placeholder "Amount" - , min zero - , onValueInput - $ \str -> - -- default to 0 in case of empty or invalid input - -- (for reasons I have yet to fathom, this doesn't work when you delete "0"; - -- until I get to the bottom of that, this is at least an improvement) - let - newAmount = fromMaybe zero $ BigInt.fromString str - in - do - handler $ SetBalance currencySymbol tokenName newAmount - ] - ] - ] - ] diff --git a/plutus-playground-client/src/Wallet/Lenses.purs b/plutus-playground-client/src/Wallet/Lenses.purs deleted file mode 100644 index c355c90127..0000000000 --- a/plutus-playground-client/src/Wallet/Lenses.purs +++ /dev/null @@ -1,28 +0,0 @@ -module Wallet.Lenses - ( _simulatorWalletWallet - , _simulatorWalletBalance - , _walletId - , _pubKey - ) where - -import Data.BigInt.Argonaut (BigInt) -import Data.Lens (Iso', Lens', iso) -import Data.Lens.Record (prop) -import Type.Proxy (Proxy(..)) -import Playground.Types (SimulatorWallet, _SimulatorWallet) -import Ledger.Crypto (PubKey, _PubKey) -import Plutus.V1.Ledger.Value (Value) -import Prelude ((<<<)) -import Ledger.CardanoWallet (WalletNumber, _WalletNumber) - -_simulatorWalletWallet :: Lens' SimulatorWallet WalletNumber -_simulatorWalletWallet = _SimulatorWallet <<< prop (Proxy :: _ "simulatorWalletWallet") - -_simulatorWalletBalance :: Lens' SimulatorWallet Value -_simulatorWalletBalance = _SimulatorWallet <<< prop (Proxy :: _ "simulatorWalletBalance") - -_walletId :: Iso' WalletNumber BigInt -_walletId = _WalletNumber <<< iso _.getWallet { getWallet: _ } - -_pubKey :: Lens' PubKey String -_pubKey = _PubKey <<< prop (Proxy :: _ "getPubKey") diff --git a/plutus-playground-client/src/Wallet/View.purs b/plutus-playground-client/src/Wallet/View.purs deleted file mode 100644 index ee75c37813..0000000000 --- a/plutus-playground-client/src/Wallet/View.purs +++ /dev/null @@ -1,136 +0,0 @@ -module Wallet.View - ( walletsPane - , walletIdPane - ) where - -import Bootstrap (btn, btnSecondary, btnSmall, card, cardBody_, cardTitle_, floatRight) -import Data.Array (mapWithIndex) -import Data.Array as Array -import Data.BigInt.Argonaut as BigInt -import Data.Lens (view) -import Data.Tuple (Tuple(..)) -import Halogen.HTML (ClassName(ClassName), HTML, br_, button, div, div_, h2_, h3_, h4_, p_, span, text) -import Halogen.HTML.Elements.Keyed as Keyed -import Halogen.HTML.Events (onClick) -import Halogen.HTML.Properties (class_, classes) -import Icons (Icon(..), icon) -import Ledger.CardanoWallet (WalletNumber(..)) -import MainFrame.Types (HAction(..), WalletEvent(..)) -import Playground.Lenses (_endpointDescription, _getEndpointDescription) -import Playground.Types (ContractCall(..), FunctionSchema, SimulatorWallet(..), _FunctionSchema) -import Plutus.V1.Ledger.Value (Value) -import Prelude (const, show, ($), (<), (<>), (<$>), (<<<)) -import Schema (FormSchema) -import Schema.Types (ActionEvent(..), SimulationAction(..), Signatures, toArgument) -import ValueEditor (valueForm) -import Wallet.Lenses (_simulatorWalletWallet) - -walletsPane :: forall p. Signatures -> Value -> Array SimulatorWallet -> HTML p HAction -walletsPane signatures initialValue simulatorWallets = - div - [ class_ $ ClassName "wallets" ] - [ h2_ [ text "Wallets" ] - , p_ [ text "Add some initial wallets, then click one of your function calls inside the wallet to begin a chain of actions." ] - , Keyed.div [ class_ $ ClassName "wallet-list" ] allWalletPanes - ] - where - allWalletPanes = - if Array.length simulatorWalletPanes < 10 then - Array.snoc simulatorWalletPanes addWalletPane - else - simulatorWalletPanes - - simulatorWalletPanes = mapWithIndex (walletPane signatures initialValue) simulatorWallets - -walletPane :: forall p. Signatures -> Value -> Int -> SimulatorWallet -> Tuple String (HTML p HAction) -walletPane signatures initialValue walletIndex simulatorWallet@(SimulatorWallet { simulatorWalletWallet, simulatorWalletBalance }) = - Tuple (show walletIndex) - $ div - [ classes [ card, walletClass ] ] - [ cardBody_ - [ button - [ classes [ btn, floatRight, ClassName "close-button" ] - , onClick $ const $ ModifyWallets $ RemoveWallet walletIndex - ] - [ icon Close ] - , cardTitle_ [ h3_ [ walletIdPane simulatorWalletWallet ] ] - , h4_ [ text "Opening Balances" ] - , valueForm (ModifyWallets <<< ModifyBalance walletIndex) simulatorWalletBalance - , br_ - , h4_ [ text "Available functions" ] - , div - [ class_ $ ClassName "available-actions" ] - [ ChangeSimulation <$> div_ (actionButton initialValue simulatorWallet <$> signatures) - , ChangeSimulation <$> div_ [ addPayToWalletButton initialValue simulatorWallet ] - ] - ] - ] - --- this function is exported so that action panes can show their associated wallet -walletIdPane :: forall p i. WalletNumber -> HTML p i -walletIdPane (WalletNumber { getWallet }) = - span [ class_ $ ClassName "wallet-id" ] - [ text $ "Wallet " <> BigInt.toString getWallet ] - -addWalletPane :: forall p. Tuple String (HTML p HAction) -addWalletPane = - Tuple "add-wallet" - $ div - [ classes [ card, walletClass, ClassName "add-wallet" ] - , onClick $ const $ ModifyWallets AddWallet - ] - [ cardBody_ - [ icon Plus - , div_ [ text "Add Wallet" ] - ] - ] - -actionButton :: forall p. Value -> SimulatorWallet -> FunctionSchema FormSchema -> HTML p SimulationAction -actionButton initialValue simulatorWallet functionSchema = - button - [ classes [ btn, btnSecondary, btnSmall, actionButtonClass ] - , onClick $ const $ ModifyActions $ AddAction - $ CallEndpoint - { argumentValues: toArgument initialValue <$> functionSchema - , caller: view _simulatorWalletWallet simulatorWallet - } - ] - [ span - [ class_ actionButtonTextClass ] - [ text $ view (_FunctionSchema <<< _endpointDescription <<< _getEndpointDescription) functionSchema ] - , span - [ class_ actionButtonIconClass ] - [ icon Plus ] - ] - -addPayToWalletButton :: forall p. Value -> SimulatorWallet -> HTML p SimulationAction -addPayToWalletButton initialValue simulatorWallet = - button - [ classes [ btn, btnSecondary, btnSmall, actionButtonClass ] - , onClick $ const $ ModifyActions $ AddAction - $ PayToWallet - { sender: view _simulatorWalletWallet simulatorWallet - , recipient: view _simulatorWalletWallet simulatorWallet - , amount: initialValue - } - ] - [ span - [ class_ actionButtonTextClass ] - [ text "Pay to Wallet" ] - , span - [ class_ actionButtonIconClass ] - [ icon Plus ] - ] - ------------------------------------------------------------- -walletClass :: ClassName -walletClass = ClassName "wallet" - -actionButtonClass :: ClassName -actionButtonClass = ClassName "action-button" - -actionButtonTextClass :: ClassName -actionButtonTextClass = ClassName "action-button-text" - -actionButtonIconClass :: ClassName -actionButtonIconClass = ClassName "action-button-icon" diff --git a/plutus-playground-client/static/body.scss b/plutus-playground-client/static/body.scss deleted file mode 100644 index 937ebb3739..0000000000 --- a/plutus-playground-client/static/body.scss +++ /dev/null @@ -1,39 +0,0 @@ -.main { - .main-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: .5rem 0; - - h1 { - font-size: 1.3125rem; - font-weight: bold; - color: $blue; - margin-bottom: 0; - } - - .btn, - .btn:hover { - color: $blue; - text-decoration: underline; - } - - .hidden { - visibility: hidden; - } - } - - .main-body { - flex: 1; - margin-bottom: 1rem; - - &.editor { - border-top: 1px solid $gray-border-color; - } - - &.simulator { - background: $gray-100; - border: 1px solid $gray-border-color; - } - } -} diff --git a/plutus-playground-client/static/bootstrap.scss b/plutus-playground-client/static/bootstrap.scss deleted file mode 100644 index 3b86a9b7ab..0000000000 --- a/plutus-playground-client/static/bootstrap.scss +++ /dev/null @@ -1,36 +0,0 @@ -@import './node_modules/bootstrap/scss/functions'; -@import './node_modules/bootstrap/scss/variables'; -@import './node_modules/bootstrap/scss/mixins'; -@import './node_modules/bootstrap/scss/root'; -@import './node_modules/bootstrap/scss/reboot'; -@import './node_modules/bootstrap/scss/type'; -@import './node_modules/bootstrap/scss/images'; -@import './node_modules/bootstrap/scss/code'; -@import './node_modules/bootstrap/scss/grid'; -@import './node_modules/bootstrap/scss/tables'; -@import './node_modules/bootstrap/scss/forms'; -@import './node_modules/bootstrap/scss/buttons'; -@import './node_modules/bootstrap/scss/transitions'; -@import './node_modules/bootstrap/scss/dropdown'; -@import './node_modules/bootstrap/scss/button-group'; -@import './node_modules/bootstrap/scss/input-group'; -@import './node_modules/bootstrap/scss/custom-forms'; -@import './node_modules/bootstrap/scss/nav'; -@import './node_modules/bootstrap/scss/navbar'; -@import './node_modules/bootstrap/scss/card'; -// @import './node_modules/bootstrap/scss/breadcrumb'; -// @import './node_modules/bootstrap/scss/pagination'; -@import './node_modules/bootstrap/scss/badge'; -// @import './node_modules/bootstrap/scss/jumbotron'; -@import './node_modules/bootstrap/scss/alert'; -// @import './node_modules/bootstrap/scss/progress'; -// @import './node_modules/bootstrap/scss/media'; -@import './node_modules/bootstrap/scss/list-group'; -@import './node_modules/bootstrap/scss/close'; -@import './node_modules/bootstrap/scss/modal'; -// @import './node_modules/bootstrap/scss/tooltip'; -// @import './node_modules/bootstrap/scss/popover'; -// @import './node_modules/bootstrap/scss/carousel'; -@import './node_modules/bootstrap/scss/utilities'; -@import './node_modules/bootstrap/scss/print'; -@import './node_modules/bootstrap/scss/spinners'; diff --git a/plutus-playground-client/static/chain.scss b/plutus-playground-client/static/chain.scss deleted file mode 100644 index c13c1eb414..0000000000 --- a/plutus-playground-client/static/chain.scss +++ /dev/null @@ -1,176 +0,0 @@ -@mixin entry-background($entry-color, $entry-background-color) { - &.card { - border-color: $entry-background-color; - } - - th, .card-header { - color: $entry-color; - background-color: $entry-background-color; - - .clipboard .btn-link { - color: $entry-color; - } - } -} - -@mixin chain ( - $balances-table-background-color, - $balances-table-border-color, - - $entry-border-width, - $entry-border-color, - $entry-active-border-color, - $entry-inner-border-color, - $entry-separator-color, - $entry-footer-background-color, - $entry-arrow-width, - $entry-arrow-color, - - $entry-color, - $entry-detail-color-fee, - $entry-detail-color-not-found, - $entry-detail-color-forge, - $entry-detail-color-wallet, - $entry-detail-color-script, -) { - .chain { - .card-footer { - background-color: $entry-footer-background-color !important; - border-top: solid 1px $entry-inner-border-color; - } - - .detail { - .card-header { - border-bottom: solid 1px $entry-inner-border-color; - } - } - - .card { - border: solid $entry-border-width $entry-border-color; - - &.active { - border-color: $entry-active-border-color; - } - - .triangle-right { - position: absolute; - right: -1 * ((2 * $entry-border-width) + $entry-arrow-width); - top: 0; - - height: 0; - width: 0; - - border-style: solid; - border-width: 10px 0 10px $entry-arrow-width; - border-color: transparent transparent transparent $entry-arrow-color; - } - } - - .clipboard .btn-link { - color: $gray-600; - } - - .amount { - text-align: right; - vertical-align: middle; - } - - .slot-empty { - display: flex; - justify-content: center; - align-items: center; - } - - .entry { - line-height: 1.2rem; - - .card-header { - font-size: 1rem; - } - - .card-header, - .card-footer { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - } - - .card-header, - .card-body, - .card-footer { - padding-left: 0.8rem; - padding-right: 0.8rem; - } - - .card-body { - padding-top: 0.5rem; - padding-bottom: 0.5rem; - hr { - margin-top: 0.2rem; - margin-bottom: 0.2rem; - border-top-color: $entry-separator-color; - } - } - } - - .fee { - @include entry-background($entry-color, $entry-detail-color-fee); - } - .not-found { - @include entry-background($entry-color, $entry-detail-color-not-found); - } - .forge { - @include entry-background($entry-color, $entry-detail-color-forge); - } - .wallet { - @include entry-background($entry-color, $entry-detail-color-wallet); - } - .script { - @include entry-background($entry-color, $entry-detail-color-script); - } - - overflow: hidden; - - &.animation .detail { - opacity: 0; - position: relative; - left: 0; - } - - &.chain-focus-older .detail { - left: -100%; - } - - &.chain-focus-newer .detail { - left: 100%; - } - - &.animation-done .detail { - opacity: 1; - transition: opacity 250ms, left 250ms; - left: 0; - } - - .balances-table { - tr { - height: 3rem; - } - - tbody tr th:first-child { - max-width: 12rem; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - - thead { - background-color: $balances-table-background-color; - border-bottom: solid 2px $balances-table-border-color; - } - th, td { - border-color: $balances-table-border-color; - border-width: 1px; - padding: 0.5rem 0.8rem; - } - } - } -} diff --git a/plutus-playground-client/static/chartist.scss b/plutus-playground-client/static/chartist.scss deleted file mode 100644 index 539fe0495a..0000000000 --- a/plutus-playground-client/static/chartist.scss +++ /dev/null @@ -1,41 +0,0 @@ -.ct-chart { - .chartist-tooltip { - color: $white; - background-color: $chart-tooltip; - - &:before { - border-top-color: $chart-tooltip; - } - } - - .ct-chart-bar { - background-color: $chart-bg; - - .ct-x-axis-title, - .ct-y-axis-title { - fill: $chart-title; - } - - .ct-label { - color: $chart-label; - } - - .ct-grid.ct-vertical, - .ct-grid.ct-horizontal { - stroke: $chart-grid-stroke; - stroke-dasharray: none; - } - - .ct-bar { - stroke-width: 30px; - } - - .ct-series-a .ct-bar { stroke: $red; } - .ct-series-b .ct-bar { stroke: $pink; } - .ct-series-c .ct-bar { stroke: $orange; } - .ct-series-d .ct-bar { stroke: $yellow; } - .ct-series-e .ct-bar { stroke: $green; } - .ct-series-f .ct-bar { stroke: $blue; } - .ct-series-g .ct-bar { stroke: $indigo; } - } -} diff --git a/plutus-playground-client/static/editor.scss b/plutus-playground-client/static/editor.scss deleted file mode 100644 index 4ec6463286..0000000000 --- a/plutus-playground-client/static/editor.scss +++ /dev/null @@ -1,155 +0,0 @@ -.editor { - display: flex; - flex-direction: column; - position: relative; - - .editor-controls { - display: flex; - justify-content: space-between; - padding: .5rem 0; - - .key-bindings { - display: flex; - align-items: baseline; - - label { - margin-right: 1rem; - margin-bottom: 0; - white-space: nowrap; - } - } - - .editor-buttons { - button { - width: 7em; - - &:not(:first-child) { - margin-left: 1rem; - } - } - } - } - - .code-editor { - flex: 1; - display: flex; - flex-direction: column; - border: 1px solid $gray-border-color; - - .monaco-editor-container { - min-height: 400px; - flex: 1; - } - - #statusline { - background-color: $gray-lighter-background-color; - border-top: 1px solid $gray-border-color; - padding: 0 .5em; - margin-bottom: 0; - - &.hidden { - display: none; - } - } - } - - $feedback-header-height: 19px; - $feedback-body-height: 200px; - $feedback-padding: 1em; - - .editor-feedback-container { - height: $feedback-header-height; - } - - .editor-feedback { - position: absolute; - bottom: 0; - max-height: $feedback-header-height + $feedback-body-height; - width: 100%; - overflow-y: hidden; - display: flex; - flex-direction: column; - border: 1px solid $gray-border-color; - font-family: $font-family-monospace; - - @for $n from 1 through 100 { - &.expanded-#{$n} { - max-height: $feedback-header-height + $feedback-body-height + $n; - } - } - - &.minimised { - height: $feedback-header-height + 1px; // +1 for the border - overflow: hidden; - - .editor-feedback-resize-bar { - height: 0; - } - } - - a, a:hover { - text-decoration: underline; - } - - .editor-feedback-resize-bar { - height: 4px; - background: $gray-border-color; - cursor: ns-resize; - } - - .editor-feedback-header { - height: $feedback-header-height; - display: flex; - justify-content: space-between; - align-items: center; - background: $gray-background-color; - - p { - margin: 0; - padding: 0 $feedback-padding; - } - - } - - .editor-feedback-body { - height: 100%; - overflow-y: auto; - background: lighten($red, 50%); - } - - .card { - border: 0; - border-radius: 0; - } - - .card-header:first-child { - border-radius: 0; - } - - .raw-error, - .compilation-error { - .card-header { - background: $red; - color: $white; - padding: 0 $feedback-padding; - } - - .card-body { - background: lighten($red, 50%); - } - } - - .card-body { - padding: ($feedback-padding / 2) $feedback-padding; - - code, - pre { - font-size: inherit; // don't overshrink the text - } - - pre { - margin: 0; - } - } - } -} diff --git a/plutus-playground-client/static/favicon.ico b/plutus-playground-client/static/favicon.ico deleted file mode 100644 index e8dfec8c04..0000000000 Binary files a/plutus-playground-client/static/favicon.ico and /dev/null differ diff --git a/plutus-playground-client/static/gist.scss b/plutus-playground-client/static/gist.scss deleted file mode 100644 index 6158bb82e9..0000000000 --- a/plutus-playground-client/static/gist.scss +++ /dev/null @@ -1,96 +0,0 @@ -.gist-controls { - position: relative; - $label-width: 3.5rem; - $gist-id-input-width: 14rem; - $button-width: 5rem; - $button-margin: .5rem; - $arrow-width: 12px; - - label { - width: $label-width; - color: $gray-text-color; - } - - .form-control { - width: $gist-id-input-width; - } - - .btn { - width: $button-width; - margin-left: $button-margin; - - &.double-width { - width: ($button-width * 2) + $button-margin; - } - } - - .gist-link, - .error-pane { - position: absolute; - z-index: 10; - top: 44px; - left: $label-width; - width: $gist-id-input-width; - border: 1px solid $green; - border-radius: 4px; - background: lighten($green, 50%); - padding: .25em .5em; - color: $green; - font-size: .8125rem; - - &::before, - &::after { - content: ""; - position: absolute; - border-left: $arrow-width solid transparent; - border-right: $arrow-width solid transparent; - left: 10%; - margin-left: -$arrow-width; - } - - &::before { - border-bottom: $arrow-width solid $green; - top: -$arrow-width; - } - - &::after { - border-bottom: $arrow-width solid lighten($green, 50%); - top: -($arrow-width - 1px); - z-index: 11; - } - } - - .error-pane { - z-index: 20; - border-color: $red; - background: lighten($red, 50%); - color: $red; - width: $gist-id-input-width + ($button-margin + $button-width) * 2; - - &::before { - border-bottom-color: $red; - } - - &::after { - border-bottom-color: lighten($red, 50%); - z-index: 21; - } - - .alert { - background: transparent; - border: 0; - padding: 0; - margin: 0; - - p { - margin: 0; - } - } - - .btn { - width: 1em; - padding: 0; - color: $red; - } - } -} diff --git a/plutus-playground-client/static/images/plutus-logo.svg b/plutus-playground-client/static/images/plutus-logo.svg deleted file mode 100644 index cf968f0850..0000000000 --- a/plutus-playground-client/static/images/plutus-logo.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - diff --git a/plutus-playground-client/static/layout.scss b/plutus-playground-client/static/layout.scss deleted file mode 100644 index 2bdf0f1748..0000000000 --- a/plutus-playground-client/static/layout.scss +++ /dev/null @@ -1,91 +0,0 @@ -body { - height: 100vh; - min-width: 768px; - display: flex; - flex-direction: column; -} - -.frame { - flex: 1; - display: flex; - flex-direction: column; - color: $black; - - a { - cursor: pointer; - } - - button[disabled] { - cursor: not-allowed; - } - - .btn-green { - @include button-variant($green, $green); - } - - .btn-turquoise { - @include button-variant($turquoise, $turquoise); - } - - .release-banner { - text-transform: uppercase; - text-align: center; - font-size: 1.1em; - padding: .5rem; - background: $blue; - color: $gray-background-color; - border-bottom: 1px solid $gray-border-color; - } - - .header, - .footer { - background: $gray-background-color; - - .nav-link { - color: inherit; - text-decoration: underline; - - &:hover { - color: $blue; - } - } - } - - .header { - .navbar-brand { - display: flex; - align-items: center; - font-size: 1.125rem; - text-transform: uppercase; - padding: 0; - - img { - margin-right: 1rem; - } - } - - .navbar-nav { - font-size: .875rem; - } - } - - .sub-header { - // further styles in subheader.scss and gist.scss - position: relative; - border-bottom: 1px solid $gray-border-color; - border-top: 1px solid $gray-border-color; - padding: .25rem 1rem; - } - - > .main { - // further general styles in body.scss - // further specific styles in editor.scss, simulations.scss, and transactions.scss - flex: 1; - display: flex; - flex-direction: column; - } - - .footer { - border-top: 1px solid $gray-border-color; - } -} diff --git a/plutus-playground-client/static/main.scss b/plutus-playground-client/static/main.scss deleted file mode 100644 index 1126c49ae7..0000000000 --- a/plutus-playground-client/static/main.scss +++ /dev/null @@ -1,12 +0,0 @@ -@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;700'); - -@import 'variables.scss'; -@import './bootstrap.scss'; - -@import 'layout.scss'; -@import 'subheader.scss'; -@import 'gist.scss'; -@import 'body.scss'; -@import 'editor.scss'; -@import 'simulations.scss'; -@import 'transactions.scss'; diff --git a/plutus-playground-client/static/simulations.scss b/plutus-playground-client/static/simulations.scss deleted file mode 100644 index baff6f9a64..0000000000 --- a/plutus-playground-client/static/simulations.scss +++ /dev/null @@ -1,197 +0,0 @@ -.simulations { - .nav-tabs { - background: $gray-background-color; - border-color: $blue; - border-width: 2px; - - .nav-item { - position: relative; - margin-bottom: -2px; - - // it's surprisingly fiddly getting the borders right - // this works, but there might be a more elegant solution... - &::after { - position: absolute; - content: " "; - height: calc(100% - 2px); - width: 1px; - background: $gray-border-color; - top: 0; - left: -1px; - z-index: 0; - } - } - - .nav-link { - position: relative; - z-index: 1; - cursor: default; - border-width: 2px; - border-radius: 0; - color: inherit; - margin-left: -1px; - height: 100%; - - &:not(:last-child) { - padding-right: 3em; // leave room for the close button - } - - &:hover { - border-color: transparent; - } - - &.active { - border-color: $blue; - border-bottom-color: transparent; - background: $gray-100; - } - } - } - - .simulation-nav-item-control { - display: inline-block; - padding: 0 .5em; - - &:not(:first-child) { - position: absolute; - top: .75em; - right: .75em; - z-index: 2; - } - - &:hover { - background: $gray-accent-color; - } - } - - .error-pane { - margin-top: 1rem; - - .alert { - margin: 0; - } - } -} - -.simulation { - padding: 1rem; - - .simulation-controls { - display: flex; - - button { - width: 8rem; - - &:not(:first-child) { - margin-left: 1rem; - } - } - } -} - -.wallets, -.actions { - margin-bottom: 1rem; - - h3 { - font-size: 1.1rem; - } - - h4 { - font-size: 1rem; - margin-bottom: .75em; - } -} - -.actions-being-dragged { - .action { - opacity: 0.75; - } -} - - -.wallet-list, -.action-list { - display: grid; - grid-template-columns: repeat(auto-fill, 309px); // 309px means 3 fit exactly on 1024px screen - grid-gap: 1rem; -} - -.wallet, -.action { - .close-button { - margin: -0.5rem -0.5rem 0 0; - - &:hover { - background: $gray-accent-color; - } - } - - .form-control { - // otherwise flex-wrap is not necessarily triggered, and some inputs become unreadably small - min-width: 6rem; - } - - .form-group:last-child { - margin-bottom: 0; - } -} - -.wallet { - .available-actions > div { - display: flex; - flex-wrap: wrap; - margin: -0.125rem; - - &:not(:first-child) { - margin-top: .125rem; - } - - .action-button { - flex: 1; - margin: .125rem; - display: flex; - } - - .action-button-text { - flex: 1; - } - - .action-button-icon { - margin-left: .5rem; - } - } -} - -.action { - position: relative; - - .action-label { - position: absolute; - top: -0.75rem; - left: 128px; - width: 40px; - text-align: center; - background: $white; - border-radius: $border-radius-sm; - border: 1px solid $gray-400; - } - - .wait-type-options { - border: 1px solid $gray-border-color; - border-radius: $border-radius; - padding: .4em; - margin-bottom: .5rem; - } -} - -.add-wallet, -.add-wait-action { - cursor: pointer; - align-self: flex-start; - text-align: center; -} - -.action-invalid-wallet { - border: solid 1px $red; -} diff --git a/plutus-playground-client/static/subheader.scss b/plutus-playground-client/static/subheader.scss deleted file mode 100644 index 38ba0e1e73..0000000000 --- a/plutus-playground-client/static/subheader.scss +++ /dev/null @@ -1,86 +0,0 @@ -.sub-header { - $menu-breakpoint: 1024px; - $menu-left-offset: -0.8rem; - - .menu-button { - background: transparent; - font-size: 1.25rem; - width: 3rem; - margin-left: $menu-left-offset; - border-radius: 0; - transition: initial; - - &.open { - box-shadow: $box-shadow - } - - @media (min-width: $menu-breakpoint) { - display: none; - } - } - - .menu { - .navbar-text { - font-weight: 600; - } - - .nav-link { - color: $gray-text-color; - text-decoration: underline; - - &.active, - &:hover { - color: $blue; - text-decoration: underline; - } - } - - @media (max-width: $menu-breakpoint - 1px) { - display: none; - position: absolute; - z-index: 20; - top: 3rem; - left: 1rem + $menu-left-offset; - width: 14rem; - padding: .5rem 1rem; - box-shadow: $box-shadow; - background: #fff; - - // hide the overlapping box shadow between the button and the menu - &::before { - position: absolute; - width: 3rem; - background: #fff; - height: 4px; - content: " "; - top: -2px; - left: 0; - } - - .navbar-nav { - flex-direction: column; - border-top: 1px solid $gray-border-color; - margin-top: .5rem; - padding-left: .5rem; - } - - .nav-item { - padding: .25rem 0; - - &:not(:last-child) { - border-bottom: 1px solid $gray-border-color; - } - } - - &.open { - display: block; - } - } - - @media (min-width: $menu-breakpoint) { - .navbar-text { - margin-right: 1rem; - } - } - } -} diff --git a/plutus-playground-client/static/transactions.scss b/plutus-playground-client/static/transactions.scss deleted file mode 100644 index ec004fc0aa..0000000000 --- a/plutus-playground-client/static/transactions.scss +++ /dev/null @@ -1,206 +0,0 @@ -// chart.scss variables -$chart-bg: $gray-100; -$chart-tooltip: $gray-900; -$chart-title: $gray-900; -$chart-label: $gray-900; -$chart-grid-stroke: $gray-500; -@import './chartist.scss'; -@import './chain.scss'; - -.transactions { - border: 1px solid $gray-border-color; - box-shadow: $box-shadow; - padding: 1rem; - - .transactions-header { - display: flex; - justify-content: space-between; - align-items: flex-start; - padding-bottom: .5rem; - border-bottom: 1px solid #d0cfcf; - margin-bottom: 1rem; - - h2 { - margin-bottom: 0; - } - } - - .chain, - .final-balances, - .logs { - margin-bottom: 1rem; - } - - @include chain ( - $balances-table-background-color: $gray-background-color, - $balances-table-border-color: $gray-border-color, - - $entry-border-width: 2px, - $entry-border-color: $gray-border-color, - $entry-active-border-color: $blue, - $entry-inner-border-color: transparent, - $entry-separator-color: $gray-border-color, - $entry-footer-background-color: $gray-background-color, - $entry-arrow-width: 15px, - $entry-arrow-color: $blue, - - $entry-color: $white, - $entry-detail-color-fee: $pink, - $entry-detail-color-not-found: $red, - $entry-detail-color-forge: $cyan, - $entry-detail-color-wallet: $green, - $entry-detail-color-script: $yellow, - ); - - .chain { - h2 { - // temporary: make h2 look like h3 - // (rather than change the view in web-common) - @extend .h3; - } - - p { - font-size: $font-size-sm; - } - - .blocks, - .detail { - margin-bottom: 1rem; - } - - .transaction { - margin-bottom: 1rem; - } - - .card { - margin-bottom: .5rem; - border-radius: 0; - - .card-header:first-child { - border-radius: 0; - } - - &.clickable { - cursor: pointer; - - &:hover { - border-color: $blue; - } - } - } - - .balances-table { - thead { - background-color: $gray-200; - border-bottom: none; - } - } - } - - //.final-balances {} - - .logs, - .trace { - code pre { - // bootstrap's code and pre styles both shrink font size: don't shrink it twice - font-size: inherit; - } - - pre { - border: solid 1px $gray-border-color; - border-radius: 4px; - background-color: white; - padding: 1rem; - white-space: pre-wrap; - // Extra indentation for all but the first line of a paragraph. - padding-left: 2.25rem; - text-indent: -1rem; - - .info { - font-weight: bold; - - &:before { - content: "==== "; - } - &:after { - content: " ===="; - } - } - - .error { - color: $red; - } - } - } - - .trace { - pre { - margin-bottom: 0; - } - } -} - - -/* -// this doesn't seem to be doing anything - -table.balance-map { - overflow: hidden; - border: 2px solid $gray-700; - - thead { - h3 { - font-size: 0.6rem; - } - } - - tbody { - tr:hover { - background-color: $gray-800; - - .balance-remainder::after { - content: ""; - position: absolute; - background-color: $gray-800; - bottom: 0; - left: -10%; - height: 10000px; - width: 120%; - z-index: -1; - } - } - } - - .forge { - .balance { - border-color: lighten($green, 20%); - background-color: $green; - } - } - - .balance { - position: relative; - border: solid 1px $gray-300; - background-color: $gray-200; - padding: 3px 8px; - min-width: 5rem; - - &.balance-remainder { - background: url(tx-arrows.svg); - background-repeat: no-repeat; - background-position: center; - background-size: contain; - border: none; - } - - &.balance-no-currencies { - background-color: transparent; - border: none; - } - - & div:first-child { - border-top: none; - } - } -} -*/ diff --git a/plutus-playground-client/static/tx-arrows.svg b/plutus-playground-client/static/tx-arrows.svg deleted file mode 100644 index ab7f837a03..0000000000 --- a/plutus-playground-client/static/tx-arrows.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - tx-arrows - Created with Sketch. - - - - diff --git a/plutus-playground-client/static/variables.scss b/plutus-playground-client/static/variables.scss deleted file mode 100644 index 451dc3bf20..0000000000 --- a/plutus-playground-client/static/variables.scss +++ /dev/null @@ -1,19 +0,0 @@ -// color palette -$gray-text-color: #656464; -$gray-background-color: #e7e7e9; -$gray-lighter-background-color: #f7f9fc; -$gray-border-color: #d0cfcf; -$gray-accent-color: #9d9c9c; -$black: #333; -$blue: #1e73ad; -$turquoise: #1dabbc; -$red: #ae3125; // #bb2c2c // #de3241 -$yellow: #f0ad4e; -$green: #2dbb69; - -// customise bootstrap variables -$font-family-sans-serif: 'Open Sans', sans-serif; -$font-size-base: 0.8125rem; - -// other site-wide styles -$box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, .5); diff --git a/plutus-playground-client/test/ChainTests.purs b/plutus-playground-client/test/ChainTests.purs deleted file mode 100644 index 5004d34968..0000000000 --- a/plutus-playground-client/test/ChainTests.purs +++ /dev/null @@ -1,112 +0,0 @@ -module ChainTests - ( all - ) where - -import Prologue -import Data.Array (mapWithIndex) -import Data.BigInt.Argonaut as BigInt -import Data.Tuple.Nested ((/\)) -import Ledger.CardanoWallet (WalletNumber(..)) -import Playground.Types (SimulatorWallet(..)) -import Plutus.V1.Ledger.Value (CurrencySymbol(..), TokenName(..), Value(..)) -import PlutusTx.AssocMap as AssocMap -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldEqual) -import Transaction.View (extractAmount) - -all :: Spec Unit -all = - describe "Chain" do - extractAmountsTests - -extractAmountsTests :: Spec Unit -extractAmountsTests = - describe "extractAmount" do - it "All present" - $ map (extractAmount (currencies /\ usdToken)) wallets - `shouldEqual` - [ Just (BigInt.fromInt 10) - , Just (BigInt.fromInt 40) - , Just (BigInt.fromInt 70) - ] - it "All missing" - $ map (extractAmount (currencies /\ adaToken)) wallets - `shouldEqual` - [ Nothing - , Nothing - , Nothing - ] - it "Mixed" do - map (extractAmount (currencies /\ eurToken)) wallets - `shouldEqual` - [ Just (BigInt.fromInt 20) - , Just (BigInt.fromInt 50) - , Nothing - ] - map (extractAmount (ada /\ adaToken)) wallets - `shouldEqual` - [ Nothing - , Just (BigInt.fromInt 30) - , Just (BigInt.fromInt 60) - ] - -wallets :: Array SimulatorWallet -wallets = - mapWithIndex - ( \id value -> - SimulatorWallet - { simulatorWalletWallet: WalletNumber { getWallet: BigInt.fromInt id } - , simulatorWalletBalance: value - } - ) - values - -values :: Array Value -values = - [ Value - { getValue: - AssocMap.Map - [ currencies - /\ AssocMap.Map - [ usdToken /\ BigInt.fromInt 10 - , eurToken /\ BigInt.fromInt 20 - ] - ] - } - , Value - { getValue: - AssocMap.Map - [ ada /\ AssocMap.Map [ adaToken /\ BigInt.fromInt 30 ] - , currencies - /\ AssocMap.Map - [ usdToken /\ BigInt.fromInt 40 - , eurToken /\ BigInt.fromInt 50 - ] - ] - } - , Value - { getValue: - AssocMap.Map - [ ada /\ AssocMap.Map [ adaToken /\ BigInt.fromInt 60 ] - , currencies - /\ AssocMap.Map - [ usdToken /\ BigInt.fromInt 70 - ] - ] - } - ] - -ada :: CurrencySymbol -ada = CurrencySymbol { unCurrencySymbol: "" } - -currencies :: CurrencySymbol -currencies = CurrencySymbol { unCurrencySymbol: "Currency" } - -adaToken :: TokenName -adaToken = TokenName { unTokenName: "" } - -usdToken :: TokenName -usdToken = TokenName { unTokenName: "USDToken" } - -eurToken :: TokenName -eurToken = TokenName { unTokenName: "EURToken" } diff --git a/plutus-playground-client/test/EditorTests.purs b/plutus-playground-client/test/EditorTests.purs deleted file mode 100644 index f865423918..0000000000 --- a/plutus-playground-client/test/EditorTests.purs +++ /dev/null @@ -1,20 +0,0 @@ -module EditorTests - ( all - ) where - -import Prologue -import Data.Traversable (for_) -import Editor.Types (allKeyBindings, readKeyBindings) -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldEqual) - -all :: Spec Unit -all = - describe "Editor" do - readShowKeyBindingsTests - -readShowKeyBindingsTests :: Spec Unit -readShowKeyBindingsTests = - it "readShowKeyBindingsTests" do - for_ allKeyBindings \keyBindings -> - readKeyBindings (show keyBindings) `shouldEqual` keyBindings diff --git a/plutus-playground-client/test/GistsTests.purs b/plutus-playground-client/test/GistsTests.purs deleted file mode 100644 index 0befbd0c8f..0000000000 --- a/plutus-playground-client/test/GistsTests.purs +++ /dev/null @@ -1,40 +0,0 @@ -module GistsTests - ( all - ) where - -import Prologue -import Gist (GistId(..)) -import Gists.Types (parseGistUrl) -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldEqual) - -all :: Spec Unit -all = - describe "Gists" do - parseGistUrlTests - -parseGistUrlTests :: Spec Unit -parseGistUrlTests = - describe "parseGistUrlTests" do - let - gistId = GistId "9d8feacacd8c4b553f870c4448483938" - it "Ref" do - parseGistUrl "9d8feacacd8c4b553f870c4448483938" - `shouldEqual` - Right gistId - it "Direct link" do - parseGistUrl "https://gist.github.com/9d8feacacd8c4b553f870c4448483938" - `shouldEqual` - Right gistId - it "User link" do - parseGistUrl "https://gist.github.com/krisajenkins/9d8feacacd8c4b553f870c4448483938" - `shouldEqual` - Right gistId - it "No ID" do - parseGistUrl "https://gist.github.com/" - `shouldEqual` - Left "Could not parse Gist Url" - it "Too long" do - parseGistUrl "aaaabbbbccccddddeeeeffff000011112" - `shouldEqual` - Left "Could not parse Gist Url" diff --git a/plutus-playground-client/test/Main.js b/plutus-playground-client/test/Main.js deleted file mode 100644 index 8a470307ba..0000000000 --- a/plutus-playground-client/test/Main.js +++ /dev/null @@ -1,14 +0,0 @@ -/*eslint-env node*/ -/*global exports require global*/ - -window = {}; -document = {}; - -require('chartist-plugin-tooltips'); -require('chartist-plugin-axistitle'); - -global = { - plutusLogo: "PLACEHOLDER" -}; - -exports.forDeps = function () {}; diff --git a/plutus-playground-client/test/Main.purs b/plutus-playground-client/test/Main.purs deleted file mode 100644 index e8e2378c87..0000000000 --- a/plutus-playground-client/test/Main.purs +++ /dev/null @@ -1,29 +0,0 @@ -module Test.Main where - -import Prologue -import ChainTests as ChainTests -import Data.BigInt.Argonaut (withJsonPatch) -import EditorTests as EditorTests -import Effect (Effect) -import Effect.Aff (launchAff_) -import GistsTests as GistsTests -import MainFrameTests as MainFrameTests -import Schema.TypesTests as Schema.TypesTests -import StaticDataTests as StaticDataTests -import Test.Spec (around_) -import Test.Spec.Reporter (consoleReporter) -import Test.Spec.Runner (runSpec) - -foreign import forDeps :: Effect Unit - -main :: Effect Unit -main = - launchAff_ do - runSpec [ consoleReporter ] - $ around_ withJsonPatch do - ChainTests.all - EditorTests.all - GistsTests.all - StaticDataTests.all - MainFrameTests.all - Schema.TypesTests.all diff --git a/plutus-playground-client/test/MainFrameTests.purs b/plutus-playground-client/test/MainFrameTests.purs deleted file mode 100644 index b889b20c32..0000000000 --- a/plutus-playground-client/test/MainFrameTests.purs +++ /dev/null @@ -1,285 +0,0 @@ -module MainFrameTests - ( all - ) where - -import Prologue - -import Animation (class MonadAnimate) -import Clipboard (class MonadClipboard) -import Control.Monad.Except (except) -import Control.Monad.Except.Trans (class MonadThrow, throwError) -import Control.Monad.Rec.Class (class MonadRec, Step(..), tailRecM) -import Control.Monad.State (StateT(..), execStateT, state) -import Control.Monad.State.Class (class MonadState, get) -import Control.Monad.State.Extra (zoomStateT) -import Control.Monad.Trans.Class (lift) -import Cursor as Cursor -import Data.Argonaut (Json, JsonDecodeError, encodeJson) -import Data.Argonaut.Decode (printJsonDecodeError) -import Data.Argonaut.Extra (parseDecodeJson) -import Data.Bifunctor (lmap) -import Data.Either (either) -import Data.HTTP.Method (Method(..)) -import Data.Lens (Lens', _1, _2, _Just, _Left, assign, preview, set, use, view, (^.)) -import Data.Lens.At (at) -import Data.Lens.Index (ix) -import Data.Lens.Record (prop) -import Data.Map (Map) -import Data.Map as Map -import Data.Newtype (class Newtype, unwrap) -import Data.Traversable (traverse_) -import Editor.Types (State(..)) as Editor -import Effect.Class (class MonadEffect, liftEffect) -import Effect.Exception (Error, error) -import Gist (Gist, GistId(..), gistId) -import Gists.Types (GistAction(..)) -import Halogen.Monaco (KeyBindings(..)) as Editor -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult, SourceCode(..)) -import MainFrame.Lenses (_authStatus, _contractDemoEditorContents, _createGistResult, _currentView, _simulations) -import MainFrame.MonadApp (class MonadApp) -import MainFrame.State (handleAction, mkInitialState) -import MainFrame.Types (HAction(..), State, View(Editor, Simulations)) -import Network.RemoteData (isFailure, isNotAsked, isSuccess) -import Node.Encoding (Encoding(..)) -import Node.FS.Sync as FS -import Playground.Gists (playgroundGistFile) -import Playground.Server as Server -import Playground.Types (CompilationResult, ContractDemo, EvaluationResult) -import Servant.PureScript (class MonadAjax, segmentsToPathAbsolute) -import StaticData (bufferLocalStorageKey, lookupContractDemo, mkContractDemos) -import Test.QuickCheck (()) -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (fail, shouldEqual, shouldSatisfy) -import Test.Spec.QuickCheck (quickCheck) -import Type.Proxy (Proxy(..)) -import URI.Extra.QueryPairs as QueryPairs -import URI.Host as Host -import URI.RelativePart (_relPath) -import URI.RelativeRef (_relPart) -import URI.RelativeRef as RelativeRef - -all :: Spec Unit -all = - describe "MainFrame" do - evalTests - ------------------------------------------------------------- -type World = - { gists :: Map GistId Gist - , editorContents :: Maybe SourceCode - , localStorage :: Map String String - , evaluationResult :: Either String EvaluationResult - , compilationResult :: (Either String (Either InterpreterError (InterpreterResult CompilationResult))) - } - -_gists :: forall r a. Lens' { gists :: a | r } a -_gists = prop (Proxy :: _ "gists") - -_editorContents :: forall r a. Lens' { editorContents :: a | r } a -_editorContents = prop (Proxy :: _ "editorContents") - -_localStorage :: forall r a. Lens' { localStorage :: a | r } a -_localStorage = prop (Proxy :: _ "localStorage") - --- | A dummy implementation of `MonadApp`, for testing the main handleAction loop. -newtype MockApp m a = MockApp (StateT (Tuple World State) m a) - -derive instance newtypeMockApp :: Newtype (MockApp m a) _ - -derive newtype instance functorMockApp :: Functor m => Functor (MockApp m) - -derive newtype instance applicativeMockApp :: Monad m => Applicative (MockApp m) - -derive newtype instance applyMockApp :: Monad m => Apply (MockApp m) - -derive newtype instance bindMockApp :: Monad m => Bind (MockApp m) - -derive newtype instance monadMockApp :: Monad m => Monad (MockApp m) - -instance monadStateMockApp :: Monad m => MonadState State (MockApp m) where - state = MockApp <<< zoomStateT _2 <<< state - -instance Monad m => MonadAjax JsonDecodeError Json String (MockApp m) where - request req = do - let mMethod = preview _Left req.method - let mUri = preview (_relPart <<< _relPath <<< _Just) req.uri - jsonResult <- case mMethod, mUri of - Just GET, Just [ "oauth", "status" ] -> - pure $ encodeJson { _authStatusAuthRole: "GithubUser" } - Just GET, Just [ "gists", gistId ] -> do - Tuple { gists } _ <- lift $ MockApp $ get - case Map.lookup (GistId gistId) gists of - Nothing -> throwError $ "Not found: " <> gistId - Just gist -> pure $ encodeJson gist - Just POST, Just [ "contract" ] -> do - Tuple { compilationResult } _ <- lift $ MockApp $ get - except $ map encodeJson $ compilationResult - _, _ -> throwError - $ "Resource not mocked: " - <> show mMethod - <> " " - <> RelativeRef.print - { printUserInfo: identity - , printHosts: Host.print - , printPath: identity - , printRelPath: Left <<< segmentsToPathAbsolute - , printQuery: QueryPairs.print identity identity - , printFragment: identity - } - req.uri - except $ lmap printJsonDecodeError $ req.decode jsonResult - -instance monadAppMockApp :: Monad m => MonadApp (MockApp m) where - editorGetContents = - MockApp do - editorContents <- use (_1 <<< _editorContents) - pure editorContents - editorSetContents contents _ = - MockApp - $ assign (_1 <<< _editorContents) (Just contents) - editorHandleAction _ = pure unit - editorSetAnnotations _ = pure unit - -- - saveBuffer contents = - MockApp - $ assign (_1 <<< _localStorage <<< at (unwrap bufferLocalStorageKey)) (Just contents) - preventDefault _ = pure unit - setDropEffect _ _ = pure unit - setDataTransferData _ _ _ = pure unit - readFileFromDragEvent _ = pure "TEST" - -- - getOauthStatus = Server.getOauthStatus - getGistByGistId = Server.getGistsByGistId - postEvaluation = Server.postEvaluate - postGist = Server.postGists - postGistByGistId = Server.postGistsByGistId - postContract = Server.postContract - resizeEditor = pure unit - resizeBalancesChart = pure unit - scrollIntoView _ = pure unit - -instance monadRecMockApp :: Monad m => MonadRec (MockApp m) where - tailRecM step a = do - v <- step a - case v of - Loop cont -> tailRecM step cont - Done result -> pure result - --- | The mock app makes no attempt to animate anything, and just calls the embedded `action`. -instance monadAnimateMockApp :: MonadAnimate (MockApp m) State where - animate _ action = action - -instance monadClipboardMockApp :: Monad m => MonadClipboard (MockApp m) where - copy _ = pure unit - -execMockApp :: forall m. MonadThrow Error m => World -> Array HAction -> m (Tuple World State) -execMockApp world queries = do - initialState <- - mkInitialState - ( Editor.State - { keyBindings: Editor.DefaultBindings - , feedbackPaneMinimised: false - , lastCompiledCode: Nothing - , currentCodeIsCompiled: false - , feedbackPaneDragStart: Nothing - , feedbackPaneExtend: 0 - , feedbackPanePreviousExtend: 0 - } - ) - state <- - execStateT - (unwrap (traverse_ handleAction queries :: MockApp m Unit)) - (Tuple world initialState) - pure state - ------------------------------------------------------------- -mockWorld :: World -mockWorld = - { gists: Map.empty - , editorContents: Nothing - , localStorage: Map.empty - , compilationResult: Left "Not mocked" - , evaluationResult: Left "Not mocked" - } - -evalTests :: Spec Unit -evalTests = - describe "handleAction" do - it "CheckAuthStatus" do - Tuple _ finalState <- execMockApp mockWorld [ CheckAuthStatus ] - (finalState ^. _authStatus) `shouldSatisfy` isSuccess - it "ChangeView" do - quickCheck \aView -> do - let - result = execMockApp mockWorld [ ChangeView aView ] - case result of - Right (Tuple _ finalState) -> (aView == view _currentView finalState) "Unexpected final view." - Left err -> false show err - describe "LoadGist" do - it "Bad URL" do - Tuple _ finalState <- - execMockApp mockWorld - [ GistAction $ SetGistUrl "9cfe" - , GistAction LoadGist - ] - (finalState ^. _createGistResult) `shouldSatisfy` isNotAsked - it "Invalid URL" do - Tuple _ finalState <- - execMockApp mockWorld - [ GistAction $ SetGistUrl "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - , GistAction LoadGist - ] - (finalState ^. _createGistResult) `shouldSatisfy` isFailure - it "Gist loaded successfully" do - contents <- liftEffect $ FS.readTextFile UTF8 "test/gist1.json" - case parseDecodeJson contents of - Left err -> fail $ printJsonDecodeError err - Right gist -> do - Tuple finalWorld finalState <- - execMockApp - (set (_gists <<< at (view gistId gist)) (Just gist) mockWorld) - [ GistAction $ SetGistUrl (unwrap (view gistId gist)) - , GistAction LoadGist - ] - (finalState ^. _createGistResult) `shouldSatisfy` isSuccess - Cursor.length (view _simulations finalState) `shouldEqual` 2 - case view playgroundGistFile gist of - Nothing -> fail "Could not read gist content. Sample it data may be incorrect." - Just sourceFile -> do - view _editorContents finalWorld `shouldEqual` Just (SourceCode sourceFile) - preview (_localStorage <<< ix (unwrap bufferLocalStorageKey)) finalWorld - `shouldEqual` - Just sourceFile - it "Loading a script works." do - Tuple finalWorld _ <- - ( execMockApp (set _editorContents Nothing mockWorld) - [ LoadScript "Game" ] - ) - contractDemos :: Array ContractDemo <- - either - (throwError <<< error <<< printJsonDecodeError) - pure - mkContractDemos - finalWorld.editorContents - `shouldEqual` - (view _contractDemoEditorContents <$> lookupContractDemo "Game" contractDemos) - it "Loading a script switches back to the editor." do - loadCompilationResponse1 - >>= \compilationResult -> do - Tuple _ finalState <- - execMockApp (mockWorld { compilationResult = Right $ Right compilationResult }) - [ ChangeView Simulations - , LoadScript "Game" - ] - view _currentView finalState `shouldEqual` Editor - -loadCompilationResponse1 - :: forall m - . MonadEffect m - => MonadThrow Error m - => m (InterpreterResult CompilationResult) -loadCompilationResponse1 = do - contents <- liftEffect $ FS.readTextFile UTF8 "generated/compilation_response.json" - case parseDecodeJson contents of - Left err -> throwError $ error $ printJsonDecodeError err - Right value -> pure value diff --git a/plutus-playground-client/test/Schema/TypesTests.purs b/plutus-playground-client/test/Schema/TypesTests.purs deleted file mode 100644 index f23d54f2ad..0000000000 --- a/plutus-playground-client/test/Schema/TypesTests.purs +++ /dev/null @@ -1,260 +0,0 @@ -module Schema.TypesTests - ( all - ) where - -import Prologue -import Control.Monad.Error.Class (class MonadThrow) -import Data.Argonaut.Core (Json, stringify) -import Data.BigInt.Argonaut as BigInt -import Data.Functor.Foldable (Fix(..)) -import Data.List (List(..), (:)) -import Data.List.NonEmpty (NonEmptyList(..)) -import Data.NonEmpty ((:|)) -import Effect.Aff (Aff) -import Effect.Exception (Error) -import Ledger.CardanoWallet (WalletNumber(..)) -import Playground.Types (ContractCall(..), FunctionSchema(..), KnownCurrency(..)) -import Plutus.V1.Ledger.Value (CurrencySymbol(..), TokenName(..), Value(..)) -import PlutusTx.AssocMap as AssocMap -import Schema (FormSchema(..), FormArgumentF(..)) -import Schema.Types (FormArgument, formArgumentToJson, mkInitialValue, toArgument) -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldEqual) -import Validation (ValidationError(..), validate, withPath) -import Wallet.Types (EndpointDescription(..)) - -all :: Spec Unit -all = - describe "Schema.Types" do - validateSpec - toArgumentSpec - formArgumentToJsonSpec - mkInitialValueSpec - -validateSpec :: Spec Unit -validateSpec = do - it "No validation errors" do - isValid $ AddBlocks { blocks: one } - isValid $ makeTestAction $ Fix $ FormIntF (Just 5) - isValid $ makeTestAction $ Fix $ FormIntegerF (Just (BigInt.fromInt 5)) - isValid $ makeTestAction $ Fix $ FormStringF (Just "TEST") - isValid $ makeTestAction $ Fix $ FormTupleF (Fix $ FormIntF (Just 5)) (Fix $ FormIntF (Just 6)) - isValid $ makeTestAction $ Fix $ FormArrayF FormSchemaInt [] - isValid $ makeTestAction $ Fix $ FormObjectF [] - -- - it "Validation errors" do - validate (makeTestAction $ Fix $ FormUnsupportedF "Test case.") `shouldEqual` [ withPath [] Unsupported ] - validate (makeTestAction $ Fix $ FormIntF Nothing) `shouldEqual` [ withPath [] Required ] - validate (makeTestAction $ Fix $ FormIntegerF Nothing) `shouldEqual` [ withPath [] Required ] - validate (makeTestAction $ Fix $ FormStringF Nothing) `shouldEqual` [ withPath [] Required ] - validate (makeTestAction $ Fix $ FormTupleF (Fix $ FormIntF Nothing) (Fix $ FormUnsupportedF "Test.")) - `shouldEqual` - [ withPath [ "_1" ] Required - , withPath [ "_2" ] Unsupported - ] - validate (makeTestAction $ Fix $ FormTupleF (Fix $ FormIntF Nothing) (Fix $ FormIntF (Just 5))) `shouldEqual` [ withPath [ "_1" ] Required ] - validate (makeTestAction $ Fix $ FormTupleF (Fix $ FormIntF (Just 5)) (Fix $ FormIntF Nothing)) - `shouldEqual` - [ withPath [ "_2" ] Required ] - validate - ( makeTestAction - $ Fix - $ FormArrayF FormSchemaInt - [ Fix $ FormIntF (Just 5) - , Fix $ FormIntF (Just 6) - , Fix $ FormIntF Nothing - , Fix $ FormIntF (Just 7) - ] - ) - `shouldEqual` - [ withPath [ "2" ] Required ] - ( validate - ( makeTestAction - $ Fix - $ FormObjectF - [ Tuple "name" (Fix $ FormStringF Nothing) - , Tuple "test" (Fix $ FormIntF (Just 5)) - ] - ) - ) - `shouldEqual` - [ withPath [ "name" ] Required ] - -toArgumentSpec :: Spec Unit -toArgumentSpec = do - describe "toArgument" do - let - initialValue :: Value - initialValue = - Value - { getValue: - AssocMap.Map - [ ( Tuple - (CurrencySymbol { unCurrencySymbol: "12345" }) - ( AssocMap.Map - [ Tuple - (TokenName { unTokenName: "ADA" }) - (BigInt.fromInt 100) - ] - ) - ) - ] - } - it "FormIntF" do - toArgument initialValue FormSchemaInt `shouldEqual` Fix (FormIntF Nothing) - it "Value" do - toArgument initialValue FormSchemaValue `shouldEqual` Fix (FormValueF initialValue) - -makeTestAction :: FormArgument -> ContractCall FormArgument -makeTestAction argument = - CallEndpoint - { caller: - WalletNumber { getWallet: one } - , argumentValues: - FunctionSchema - { endpointDescription: EndpointDescription { getEndpointDescription: "test" } - , argument - } - } - -isValid :: ContractCall FormArgument -> Aff Unit -isValid = validate >>> flip shouldEqual [] - -formArgumentToJsonSpec :: Spec Unit -formArgumentToJsonSpec = do - describe "FormArgument to JSON" do - it "Ints" do - equalJson - Nothing - (formArgumentToJson (Fix $ FormIntF Nothing)) - equalJson - (Just "5") - (formArgumentToJson (Fix $ FormIntF (Just 5))) - it "BigInts" do - equalJson - Nothing - (formArgumentToJson (Fix $ FormIntegerF Nothing)) - equalJson - (Just "5") - (formArgumentToJson (Fix $ FormIntegerF (Just (BigInt.fromInt 5)))) - it "Strings" do - equalJson - Nothing - (formArgumentToJson (Fix $ FormStringF Nothing)) - equalJson - (Just "\"Test\"") - (formArgumentToJson (Fix $ FormStringF (Just "Test"))) - it "Tuples" do - equalJson - Nothing - (formArgumentToJson (Fix $ FormTupleF (Fix $ FormIntF Nothing) (Fix $ FormStringF Nothing))) - equalJson - Nothing - (formArgumentToJson (Fix $ FormTupleF (Fix $ FormIntF Nothing) (Fix $ FormStringF (Just "Test")))) - equalJson - Nothing - (formArgumentToJson (Fix $ FormTupleF (Fix $ FormIntF (Just 5)) (Fix $ FormStringF Nothing))) - equalJson - (Just "[5,\"Test\"]") - (formArgumentToJson (Fix $ FormTupleF (Fix $ FormIntF (Just 5)) (Fix $ FormStringF (Just "Test")))) - it "Arrays" do - equalJson - (Just "[1,2,3]") - ( formArgumentToJson - ( Fix - $ FormArrayF FormSchemaInt - [ Fix $ FormIntF (Just 1) - , Fix $ FormIntF (Just 2) - , Fix $ FormIntF (Just 3) - ] - ) - ) - it "Values" do - equalJson - ( Just - "{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},4]]]]}" - ) - ( formArgumentToJson - ( Fix - $ FormValueF - ( Value - { getValue: - AssocMap.Map - [ Tuple - (CurrencySymbol { unCurrencySymbol: "" }) - ( AssocMap.Map - [ Tuple - (TokenName { unTokenName: "" }) - (BigInt.fromInt 4) - ] - ) - ] - } - ) - ) - ) - it "Objects" do - equalJson - (Just "{\"name\":\"Tester\",\"arg\":20}") - ( formArgumentToJson - ( Fix - $ FormObjectF - [ Tuple "name" $ Fix (FormStringF (Just "Tester")) - , Tuple "arg" $ Fix (FormIntF (Just 20)) - ] - ) - ) - -mkInitialValueSpec :: Spec Unit -mkInitialValueSpec = - describe "mkInitialValue" do - it "balance" do - mkInitialValue - [ KnownCurrency - { hash: "" - , friendlyName: "Ada" - , knownTokens: - NonEmptyList $ TokenName { unTokenName: "" } :| Nil - } - , KnownCurrency - { hash: "Currency" - , friendlyName: "Currencies" - , knownTokens: - NonEmptyList - $ TokenName { unTokenName: "USDToken" } - :| TokenName { unTokenName: "EURToken" } - : Nil - } - ] - (BigInt.fromInt 10) - `shouldEqual` - Value - { getValue: - AssocMap.Map - [ Tuple ada $ AssocMap.Map [ Tuple adaToken $ BigInt.fromInt 10 ] - , Tuple - currencies - $ AssocMap.Map - [ Tuple usdToken $ BigInt.fromInt 10 - , Tuple eurToken $ BigInt.fromInt 10 - ] - ] - } - -ada :: CurrencySymbol -ada = CurrencySymbol { unCurrencySymbol: "" } - -currencies :: CurrencySymbol -currencies = CurrencySymbol { unCurrencySymbol: "Currency" } - -adaToken :: TokenName -adaToken = TokenName { unTokenName: "" } - -usdToken :: TokenName -usdToken = TokenName { unTokenName: "USDToken" } - -eurToken :: TokenName -eurToken = TokenName { unTokenName: "EURToken" } - -equalJson :: forall m. MonadThrow Error m => Maybe String -> Maybe Json -> m Unit -equalJson expected actual = (stringify <$> actual) `shouldEqual` expected diff --git a/plutus-playground-client/test/StaticDataTests.purs b/plutus-playground-client/test/StaticDataTests.purs deleted file mode 100644 index 618ab9b4d0..0000000000 --- a/plutus-playground-client/test/StaticDataTests.purs +++ /dev/null @@ -1,20 +0,0 @@ -module StaticDataTests - ( all - ) where - -import Prologue -import Data.Either (isRight) -import StaticData (mkContractDemos) -import Test.Spec (Spec, describe, it) -import Test.Spec.Assertions (shouldSatisfy) - -all :: Spec Unit -all = - describe "StaticData" do - simulationDecodingSpec - -simulationDecodingSpec :: Spec Unit -simulationDecodingSpec = - describe "Simulation Decoding" do - it "contractDemos" do - mkContractDemos `shouldSatisfy` isRight diff --git a/plutus-playground-client/test/authstatus.json b/plutus-playground-client/test/authstatus.json deleted file mode 100644 index e7d7af92fd..0000000000 --- a/plutus-playground-client/test/authstatus.json +++ /dev/null @@ -1 +0,0 @@ -{"_authStatusAuthRole":"GithubUser"} diff --git a/plutus-playground-client/test/evaluation_error1.json b/plutus-playground-client/test/evaluation_error1.json deleted file mode 100644 index 6ac6e26b79..0000000000 --- a/plutus-playground-client/test/evaluation_error1.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "tag": "CompilationError", - "text": [ - " error:", - " • Couldn't match type ‘()’ with ‘SimulatorWallet ()’", - " Expected type: Either PlaygroundError (SimulatorWallet ())", - " Actual type: Either PlaygroundError ()", - " • In the second argument of ‘(<$>)’, namely ‘(submitInvalidTxn)’", - " In the expression:", - " (runWalletActionAndProcessPending", - " ([Wallet {getWallet = 1}, Wallet {getWallet = 2}])", - " (Wallet {getWallet = 1})", - " <$> (submitInvalidTxn))", - " In the second argument of ‘runTrace’, namely", - " ‘[(runWalletActionAndProcessPending", - " ([Wallet {getWallet = 1}, Wallet {getWallet = 2}])", - " (Wallet {getWallet = 1})", - " <$> (submitInvalidTxn))]’" - ], - "row": 2, - "column": 185, - "filename": "" - } -] diff --git a/plutus-playground-client/test/gist1.json b/plutus-playground-client/test/gist1.json deleted file mode 100644 index d94b7d24a9..0000000000 --- a/plutus-playground-client/test/gist1.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "_gistTruncated": false, - "_gistOwner": { - "_ownerHtmlUrl": "https://github.com/krisajenkins", - "_ownerLogin": "krisajenkins" - }, - "_gistHtmlUrl": "https://gist.github.com/e9211312651592539055e14b711e2103", - "_gistFiles": { - "Playground.hs": { - "_gistFileTruncated": false, - "_gistFileContent": "\n-- A game with two players. Player 1 thinks of a secret word\n-- and uses its hash, and the game validator script, to lock\n-- some funds (the prize) in a pay-to-script transaction output.\n-- Player 2 guesses the word by attempting to spend the transaction\n-- output. If the guess is correct, the validator script releases the funds.\n-- If it isn't, the funds stay locked.\nimport Control.Applicative ((<|>))\nimport Control.Monad (void)\nimport qualified Data.ByteString.Lazy.Char8 as C\nimport qualified PlutusTx as PlutusTx\nimport PlutusTx.Prelude hiding (pure, (<$>))\nimport Ledger (Address, DataScript (DataScript), PendingTx,\n RedeemerScript (RedeemerScript), ValidatorScript, mkValidatorScript, scriptAddress)\nimport Ledger.Ada (Ada)\nimport qualified Ledger.Ada as Ada\nimport Ledger.Typed.Scripts (wrapValidator)\nimport Plutus.Contract.Tx\nimport Playground.Contract\nimport Prelude (Eq, Ord, Show)\n\n------------------------------------------------------------\n\nnewtype HashedString = HashedString ByteString deriving newtype PlutusTx.IsData\n\nPlutusTx.makeLift ''HashedString\n\nnewtype ClearString = ClearString ByteString deriving newtype PlutusTx.IsData\n\nPlutusTx.makeLift ''ClearString\n\ntype Schema =\n BlockchainActions\n .\\/ Endpoint \"lock\" LockParams\n .\\/ Endpoint \"guess\" GuessParams\n\n-- | The validator (datascript -> redeemer -> PendingTx -> Bool)\nvalidateGuess :: HashedString -> ClearString -> PendingTx -> Bool\nvalidateGuess (HashedString actual) (ClearString guess') _ = actual == sha2_256 guess'\n\n-- | The validator script of the game.\ngameValidator :: ValidatorScript\ngameValidator = Ledger.mkValidatorScript $$(PlutusTx.compile [|| validator ||])\n where validator = wrapValidator validateGuess\n\n-- create a data script for the guessing game by hashing the string\n-- and lifting the hash to its on-chain representation\ngameDataScript :: String -> DataScript\ngameDataScript =\n Ledger.DataScript . PlutusTx.toData . HashedString . sha2_256 . C.pack\n\n-- create a redeemer script for the guessing game by lifting the\n-- string to its on-chain representation\ngameRedeemerScript :: String -> RedeemerScript\ngameRedeemerScript =\n Ledger.RedeemerScript . PlutusTx.toData . ClearString . C.pack\n\n-- | The address of the game (the hash of its validator script)\ngameAddress :: Address\ngameAddress = Ledger.scriptAddress gameValidator\n\n-- | Parameters for the \"lock\" endpoint\ndata LockParams = LockParams\n { secretWord :: String\n , amount :: Ada\n }\n deriving stock (Prelude.Eq, Prelude.Ord, Prelude.Show, Generic)\n deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument)\n\n-- | Parameters for the \"guess\" endpoint\nnewtype GuessParams = GuessParams\n { guessWord :: String\n }\n deriving stock (Prelude.Eq, Prelude.Ord, Prelude.Show, Generic)\n deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument)\n\n-- | The \"guess\" contract endpoint. See note [Contract endpoints]\nguess :: AsContractError e => Contract Schema e ()\nguess = do\n GuessParams theGuess <- endpoint @\"guess\" @GuessParams\n mp <- utxoAt gameAddress\n let redeemer = gameRedeemerScript theGuess\n tx = collectFromScript mp gameValidator redeemer\n void (submitTx tx)\n\n-- | The \"lock\" contract endpoint. See note [Contract endpoints]\nlock :: AsContractError e => Contract Schema e ()\nlock = do\n LockParams secret amt <- endpoint @\"lock\" @LockParams\n let\n vl = Ada.toValue amt\n dataValue = gameDataScript secret\n tx = payToScript vl (Ledger.scriptAddress gameValidator) dataValue\n void (submitTx tx)\n\ngame :: AsContractError e => Contract Schema e ()\ngame = guess <|> lock\n\n{- Note [Contract endpoints]\n\nA contract endpoint is a function that uses the wallet API to interact with the\nblockchain. We can look at contract endpoints from two different points of view.\n\n1. Contract users\n\nContract endpoints are the visible interface of the contract. They provide a\nUI (HTML form) for entering the parameters of the actions we may take as part\nof the contract.\n\n2. Contract authors\n\nAs contract authors we define endpoints as functions that return a value of\ntype 'MockWallet ()'. This type indicates that the function uses the wallet API\nto produce and spend transaction outputs on the blockchain.\n\nEndpoints can have any number of parameters: 'lock' has two\nparameters, 'guess' has one and 'startGame' has none. For each endpoint we\ninclude a call to 'mkFunction' at the end of the contract definition. This\ncauses the Haskell compiler to generate a schema for the endpoint. The Plutus\nPlayground then uses this schema to present an HTML form to the user where the\nparameters can be entered.\n\n-}\n\nendpoints :: AsContractError e => Contract Schema e ()\nendpoints = game\n\nmkSchemaDefinitions ''Schema\n\nmyCurrency :: KnownCurrency\nmyCurrency = KnownCurrency \"b0b0\" \"MyCurrency\" ( \"USDToken\" :| [\"EURToken\"])\n$(mkKnownCurrencies ['myCurrency])\n", - "_gistFileLanguage": "Haskell", - "_gistFileType": "text/plain", - "_gistFileFilename": "Playground.hs" - }, - "Simulation.json": { - "_gistFileTruncated": false, - "_gistFileContent": "[0,[{\"simulationWallets\":[{\"simulatorWalletWallet\":{\"getWallet\":1},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}},{\"simulatorWalletWallet\":{\"getWallet\":2},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}},{\"simulatorWalletWallet\":{\"getWallet\":3},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}}],\"simulationName\":\"Basic Game\",\"simulationId\":1,\"simulationActions\":[{\"caller\":{\"getWallet\":1},\"argumentValues\":{\"endpointDescription\":{\"getEndpointDescription\":\"lock\"},\"argument\":{\"contents\":[[\"secretWord\",{\"contents\":\"Plutus\",\"tag\":\"FormStringF\"}],[\"amount\",{\"contents\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},50]]]]},\"tag\":\"FormValueF\"}]],\"tag\":\"FormObjectF\"}},\"tag\":\"CallEndpoint\"},{\"blocks\":1,\"tag\":\"AddBlocks\"},{\"caller\":{\"getWallet\":2},\"argumentValues\":{\"endpointDescription\":{\"getEndpointDescription\":\"guess\"},\"argument\":{\"contents\":[[\"guessWord\",{\"contents\":\"Plutus\",\"tag\":\"FormStringF\"}]],\"tag\":\"FormObjectF\"}},\"tag\":\"CallEndpoint\"},{\"blocks\":1,\"tag\":\"AddBlocks\"}]},{\"simulationWallets\":[{\"simulatorWalletWallet\":{\"getWallet\":1},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}},{\"simulatorWalletWallet\":{\"getWallet\":2},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}},{\"simulatorWalletWallet\":{\"getWallet\":3},\"simulatorWalletBalance\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},100]]]]}}],\"simulationName\":\"One Bad Guess\",\"simulationId\":2,\"simulationActions\":[{\"caller\":{\"getWallet\":1},\"argumentValues\":{\"endpointDescription\":{\"getEndpointDescription\":\"lock\"},\"argument\":{\"contents\":[[\"secretWord\",{\"contents\":\"Plutus\",\"tag\":\"FormStringF\"}],[\"amount\",{\"contents\":{\"getValue\":[[{\"unCurrencySymbol\":\"\"},[[{\"unTokenName\":\"\"},50]]]]},\"tag\":\"FormValueF\"}]],\"tag\":\"FormObjectF\"}},\"tag\":\"CallEndpoint\"},{\"blocks\":1,\"tag\":\"AddBlocks\"},{\"caller\":{\"getWallet\":2},\"argumentValues\":{\"endpointDescription\":{\"getEndpointDescription\":\"guess\"},\"argument\":{\"contents\":[[\"guessWord\",{\"contents\":\"Marlowe\",\"tag\":\"FormStringF\"}]],\"tag\":\"FormObjectF\"}},\"tag\":\"CallEndpoint\"},{\"blocks\":1,\"tag\":\"AddBlocks\"},{\"caller\":{\"getWallet\":3},\"argumentValues\":{\"endpointDescription\":{\"getEndpointDescription\":\"guess\"},\"argument\":{\"contents\":[[\"guessWord\",{\"contents\":\"Plutus\",\"tag\":\"FormStringF\"}]],\"tag\":\"FormObjectF\"}},\"tag\":\"CallEndpoint\"},{\"blocks\":1,\"tag\":\"AddBlocks\"}]}]]", - "_gistFileLanguage": "JSON", - "_gistFileType": "application/json", - "_gistFileFilename": "Simulation.json" - } - }, - "_gistId": "e9211312651592539055e14b711e2103", - "_gistCreatedAt": "2010-04-14T02:15:15Z", - "_gistUpdatedAt": "2011-06-20T11:34:15Z", - "_gistDescription": "Hello World Examples", - "_gistGitPushUrl": "https://gist.github.com/e9211312651592539055e14b711e2103.git" -} diff --git a/plutus-playground-client/test/known_currency.json b/plutus-playground-client/test/known_currency.json deleted file mode 100644 index 00ea31b2d8..0000000000 --- a/plutus-playground-client/test/known_currency.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "hash": "", - "friendlyName": "Ada", - "knownTokens": [ - { - "unTokenName": "" - } - ] -} diff --git a/plutus-playground-client/test/token_names.json b/plutus-playground-client/test/token_names.json deleted file mode 100644 index 9c3352b13b..0000000000 --- a/plutus-playground-client/test/token_names.json +++ /dev/null @@ -1 +0,0 @@ -[{"unTokenName":"USDToken"},{"unTokenName":"EURToken"}] diff --git a/plutus-playground-client/test/value1.json b/plutus-playground-client/test/value1.json deleted file mode 100644 index d5bcec28f3..0000000000 --- a/plutus-playground-client/test/value1.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "getValue": [ - [ - { - "unCurrencySymbol": "0" - }, - [ - [ - { - "unTokenName": "ADA" - }, - 100 - ] - ] - ], - [ - { - "unCurrencySymbol": "1" - }, - [ - [ - { - "unTokenName": "USD" - }, - 40 - ] - ] - ], - [ - { - "unCurrencySymbol": "2" - }, - [ - [ - { - "unTokenName": "EUR" - }, - 40 - ] - ] - ] - ] -} diff --git a/plutus-playground-client/test/value_ada.json b/plutus-playground-client/test/value_ada.json deleted file mode 100644 index 0d13d3e45b..0000000000 --- a/plutus-playground-client/test/value_ada.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "getValue": [ - [ - { - "unCurrencySymbol": "" - }, - [ - [ - { - "unTokenName": "" - }, - 50 - ] - ] - ] - ] -} diff --git a/plutus-playground-client/test/value_posixtime.json b/plutus-playground-client/test/value_posixtime.json deleted file mode 100644 index c5b431b6cb..0000000000 --- a/plutus-playground-client/test/value_posixtime.json +++ /dev/null @@ -1 +0,0 @@ -50 \ No newline at end of file diff --git a/plutus-playground-client/test/value_ratio.json b/plutus-playground-client/test/value_ratio.json deleted file mode 100644 index 3169929f69..0000000000 --- a/plutus-playground-client/test/value_ratio.json +++ /dev/null @@ -1 +0,0 @@ -[1,2] \ No newline at end of file diff --git a/plutus-playground-client/webpack.config.js b/plutus-playground-client/webpack.config.js deleted file mode 100644 index 77e92a43ef..0000000000 --- a/plutus-playground-client/webpack.config.js +++ /dev/null @@ -1,104 +0,0 @@ -"use strict"; - -const HtmlWebpackPlugin = require("html-webpack-plugin"); -const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin"); -const path = require("path"); - -const isDevelopment = process.env.NODE_ENV === "development"; - -const devtool = isDevelopment ? "eval-source-map" : false; - -module.exports = { - devtool, - devServer: { - contentBase: path.join(__dirname, "dist"), - compress: true, - port: 8009, - https: true, - stats: "errors-warnings", - proxy: { - "/api": { - target: "http://localhost:8080", - }, - }, - }, - entry: "./entry.js", - output: { - filename: "[name].[contenthash].js", - path: path.join(__dirname, "dist"), - pathinfo: true, - clean: true, - }, - optimization: { - runtimeChunk: 'single', - splitChunks: { - cacheGroups: { - vendor: { - test: /[\\/]node_modules[\\/]/, - name: 'vendors', - chunks: 'all', - }, - }, - }, - }, - module: { - rules: [ - { - test: /\.tsx?$/, - loader: "ts-loader", - }, - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, "css-loader"], - }, - { - test: /\.scss$/, - use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"], - }, - { - test: /\.(png|svg|jpg|jpeg|gif)$/i, - type: "asset/resource", - }, - { - test: /\.(woff|woff2|eot|ttf|otf)$/i, - type: "asset/resource", - }, - ], - }, - resolve: { - modules: [ - "node_modules", - // We need this entry for node to be able to locate `node_modules` from - // client directory when modules are referenced from inside `web-common`. - path.resolve(__dirname, "./node_modules"), - ], - alias: { - static: path.resolve(__dirname, "./static"), - src: path.resolve(__dirname, "./src"), - }, - extensions: [".js", ".ts", ".tsx"], - }, - resolveLoader: { - modules: [ - "node_modules", - path.resolve(__dirname, "."), - ], - }, - plugins: [ - new HtmlWebpackPlugin({ - template: `${process.env.WEB_COMMON_SRC}/static/index.html`, - favicon: "static/favicon.ico", - title: "Plutus Playground", - productName: "plutus-playground", - googleAnalyticsId: isDevelopment ? "UA-XXXXXXXXX-X" : "G-9FPZ01J8E4", - segmentAnalyticsId: isDevelopment ? "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" : "0CEePM8LJUSpPoo2QGrXHDw4GKg4JFBo", - }), - new MiniCssExtractPlugin({ - filename: "[name].[contenthash].css", - }), - new MonacoWebpackPlugin({ - languages: ["haskell"], - }), - ], -}; diff --git a/plutus-playground-server/ARCHITECTURE.adoc b/plutus-playground-server/ARCHITECTURE.adoc deleted file mode 100644 index 465687040f..0000000000 --- a/plutus-playground-server/ARCHITECTURE.adoc +++ /dev/null @@ -1,7 +0,0 @@ -=== `plutus-playground-server` - -This packages contains the server that backs the Plutus Playground by -compiling user code and evaluating their simulations. - -It also defines an executable that generate Purescript bindings for the types that -the Purescript code needs. \ No newline at end of file diff --git a/plutus-playground-server/LICENSE b/plutus-playground-server/LICENSE deleted file mode 100644 index 0c8a80022e..0000000000 --- a/plutus-playground-server/LICENSE +++ /dev/null @@ -1,53 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/plutus-playground-server/NOTICE b/plutus-playground-server/NOTICE deleted file mode 100644 index 63df78b657..0000000000 --- a/plutus-playground-server/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2022 Input Output Global, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/plutus-playground-server/README.md b/plutus-playground-server/README.md deleted file mode 100644 index c30163b267..0000000000 --- a/plutus-playground-server/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# Building - -## Server - -### stack - -```sh -stack build plutus-playground-server -stack exec -- plutus-playground-server psgenerator ./plutus-playground-client/generated -stack exec -- plutus-playground-server webserver -``` - -### nix - -From the `nix-shell` simply run: -```sh -plutus-playground-server -``` -If it doesn't exist, `plutus-playground-server` will generate the PureScript files inside `plutus-playground-client/generated` which are needed by the client to work properly. To re-generate the files on demand, pass a `-g` flag like so `plutus-playground-server -g`. - -## Testing - -Tests should be run with nix: - -```sh -nix build -L -f default.nix plutus-apps.haskell.packages.plutus-playground-server.checks -``` - -You can then see the test output by looking in `result/test-stdout`: - -```sh -cat result/test-stdout -``` diff --git a/plutus-playground-server/app/Main.hs b/plutus-playground-server/app/Main.hs deleted file mode 100644 index 151ce40848..0000000000 --- a/plutus-playground-server/app/Main.hs +++ /dev/null @@ -1,78 +0,0 @@ -{-# LANGUAGE ApplicativeDo #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module Main - ( main - ) where - -import Control.Monad.IO.Class (MonadIO, liftIO) -import Control.Monad.Logger (logInfoN, runStderrLoggingT) -import Data.Text qualified as Text -import Data.Time.Units (Second) -import Options.Applicative (CommandFields, Mod, Parser, argument, auto, command, customExecParser, disambiguate, - fullDesc, help, helper, idm, info, long, metavar, option, optional, prefs, progDesc, short, - showDefault, showHelpOnEmpty, showHelpOnError, str, subparser, value) -import PSGenerator qualified -import Webserver qualified - -data Command - = Webserver { _port :: !Int, _maxInterpretationTime :: !Second } - | PSGenerator { _outputDir :: !FilePath } - deriving (Show, Eq) - -commandLineParser :: Parser (Maybe FilePath, Command) -commandLineParser = (,) <$> configFileParser <*> commandParser - -configFileParser :: Parser (Maybe FilePath) -configFileParser = optional $ - option - str - (long "config" <> metavar "CONFIG_FILE" <> help "Config file location.") - -commandParser :: Parser Command -commandParser = subparser $ webserverCommandParser <> psGeneratorCommandParser - -psGeneratorCommandParser :: Mod CommandFields Command -psGeneratorCommandParser = - command "psgenerator" $ - flip info (fullDesc <> progDesc "Generate the frontend's PureScript files.") $ do - _outputDir <- - argument - str - (metavar "OUTPUT_DIR" <> - help "Output directory to write PureScript files to.") - pure PSGenerator {..} - -webserverCommandParser :: Mod CommandFields Command -webserverCommandParser = - command "webserver" $ - flip info fullDesc $ do - _port <- - option - auto - (short 'p' <> long "port" <> help "Webserver port number" <> - showDefault <> - value 8080) - _maxInterpretationTime <- - option - auto - (short 'i' <> long "interpretation" <> help "Max interpretation time (seconds)" <> - showDefault <> - value 80) - pure Webserver {..} - -runCommand :: MonadIO m => Maybe FilePath -> Command -> m () -runCommand secrets Webserver {..} = liftIO $ Webserver.run _port _maxInterpretationTime secrets -runCommand _ PSGenerator {..} = liftIO $ PSGenerator.generate _outputDir - -main :: IO () -main = do - options <- - customExecParser - (prefs $ disambiguate <> showHelpOnEmpty <> showHelpOnError) - (info (helper <*> commandLineParser) idm) - runStderrLoggingT $ do - logInfoN $ "Running: " <> Text.pack (show options) - uncurry runCommand options diff --git a/plutus-playground-server/app/PSGenerator.hs b/plutus-playground-server/app/PSGenerator.hs deleted file mode 100644 index 466f0215e5..0000000000 --- a/plutus-playground-server/app/PSGenerator.hs +++ /dev/null @@ -1,296 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} - -module PSGenerator - ( generate - ) where - -import Auth qualified -import Control.Applicative ((<|>)) -import Control.Lens (itraverse, set, (&)) -import Control.Monad (void) -import Control.Monad.Catch (MonadMask) -import Control.Monad.Except (MonadError, runExceptT) -import Control.Monad.Except.Extras (mapError) -import Control.Monad.Freer.Extras.Log qualified as Log -import Control.Monad.IO.Class (MonadIO) -import Crowdfunding qualified -import CrowdfundingSimulations qualified -import Data.Aeson (ToJSON, toJSON) -import Data.Aeson qualified as JSON -import Data.Aeson.Encode.Pretty qualified as JSON -import Data.ByteString qualified as BS -import Data.ByteString.Lazy qualified as BSL -import Data.Monoid () -import Data.Proxy (Proxy (Proxy)) -import Data.Text (Text) -import Data.Text.Encoding qualified as T (decodeUtf8, encodeUtf8) -import Data.Time.Units (Second) -import ErrorHandling qualified -import ErrorHandlingSimulations qualified -import Game qualified -import GameSimulations qualified -import HelloWorld qualified -import HelloWorldSimulations qualified -import Interpreter qualified as Webghc -import Language.Haskell.Interpreter (CompilationError, InterpreterError, InterpreterResult (InterpreterResult), - SourceCode (SourceCode), Warning, result, warnings) -import Language.PureScript.Bridge (BridgePart, Language (Haskell), SumType, argonaut, buildBridge, equal, genericShow, - mkSumType, order) -import Language.PureScript.Bridge.TypeParameters (A) -import Ledger.CardanoWallet qualified as CW -import Ledger.Tx.CardanoAPI (ToCardanoError) -import PSGenerator.Common qualified -import Playground.API qualified as API -import Playground.Interpreter qualified as PI -import Playground.Types (CompilationResult (CompilationResult), ContractCall, ContractDemo (ContractDemo), - Evaluation (Evaluation), EvaluationResult, FunctionSchema, KnownCurrency, - PlaygroundError (InterpreterError), Simulation (Simulation), SimulatorAction, SimulatorWallet, - contractDemoContext, contractDemoEditorContents, contractDemoName, contractDemoSimulations, - functionSchema, knownCurrencies, program, simulationActions, simulationWallets, sourceCode, - wallets) -import Playground.Usecases (crowdFunding, errorHandling, game, starter, vesting) -import Playground.Usecases qualified as Usecases -import Plutus.Contract.Checkpoint (CheckpointKey, CheckpointLogMsg) -import Schema (FormSchema, formArgumentToJson) -import Servant ((:<|>)) -import Servant.PureScript (HasBridge, Settings, addTypes, apiModuleName, defaultBridge, defaultSettings, - generateWithSettings, languageBridge) -import Starter qualified -import StarterSimulations qualified -import System.FilePath (()) -import Vesting qualified -import VestingSimulations qualified -import Wallet.API (WalletAPIError) -import Wallet.Emulator.Chain qualified as EM -import Wallet.Emulator.LogMessages qualified as EM -import Wallet.Emulator.MultiAgent qualified as EM -import Wallet.Emulator.NodeClient qualified as EM -import Wallet.Emulator.Wallet qualified as EM -import Wallet.Rollup.Types (AnnotatedTx, BeneficialOwner, DereferencedInput, SequenceId, TxKey) - -myBridge :: BridgePart -myBridge = - PSGenerator.Common.aesonBridge <|> - PSGenerator.Common.containersBridge <|> - PSGenerator.Common.languageBridge <|> - PSGenerator.Common.ledgerBridge <|> - PSGenerator.Common.servantBridge <|> - PSGenerator.Common.miscBridge <|> - defaultBridge - -data MyBridge - -myBridgeProxy :: Proxy MyBridge -myBridgeProxy = Proxy - -instance HasBridge MyBridge where - languageBridge _ = buildBridge myBridge - -myTypes :: [SumType 'Haskell] -myTypes = - PSGenerator.Common.ledgerTypes <> - PSGenerator.Common.playgroundTypes <> - [ genericShow $ equal $ argonaut $ mkSumType @CompilationResult - , genericShow $ equal $ argonaut $ mkSumType @Warning - , genericShow $ equal $ argonaut $ mkSumType @SourceCode - , equal $ genericShow $ argonaut $ mkSumType @EM.Wallet - , equal $ genericShow $ argonaut $ mkSumType @CW.WalletNumber - , genericShow $ equal $ argonaut $ mkSumType @Simulation - , genericShow $ equal $ argonaut $ mkSumType @ContractDemo - , genericShow $ equal $ argonaut $ mkSumType @SimulatorWallet - , genericShow $ argonaut $ mkSumType @CompilationError - , genericShow $ argonaut $ mkSumType @Evaluation - , genericShow $ argonaut $ mkSumType @EvaluationResult - , genericShow $ argonaut $ mkSumType @EM.EmulatorEvent' - , genericShow $ argonaut $ mkSumType @(EM.EmulatorTimeEvent A) - , genericShow $ argonaut $ mkSumType @EM.ChainEvent - , equal $ order $ genericShow $ argonaut $ mkSumType @Log.LogLevel - , genericShow $ argonaut $ mkSumType @(Log.LogMessage A) - , genericShow $ argonaut $ mkSumType @EM.WalletEvent - , genericShow $ argonaut $ mkSumType @EM.NodeClientEvent - , genericShow $ argonaut $ mkSumType @PlaygroundError - , equal $ genericShow $ argonaut $ mkSumType @WalletAPIError - , equal $ genericShow $ argonaut $ mkSumType @ToCardanoError - , order $ genericShow $ argonaut $ mkSumType @SequenceId - , equal $ genericShow $ argonaut $ mkSumType @AnnotatedTx - , equal $ genericShow $ argonaut $ mkSumType @DereferencedInput - , order $ genericShow $ argonaut $ mkSumType @BeneficialOwner - , equal $ genericShow $ argonaut $ mkSumType @TxKey - , genericShow $ argonaut $ mkSumType @InterpreterError - , genericShow $ equal $ argonaut $ mkSumType @(InterpreterResult A) - , genericShow $ argonaut $ mkSumType @CheckpointLogMsg - , genericShow $ argonaut $ mkSumType @CheckpointKey - , genericShow $ argonaut $ mkSumType @EM.RequestHandlerLogMsg - , genericShow $ argonaut $ mkSumType @EM.TxBalanceMsg - ] - -mySettings :: Settings -mySettings = defaultSettings - & set apiModuleName "Playground.Server" - & addTypes myTypes - -multilineString :: Text -> Text -> Text -multilineString name value = - "\n\n" <> name <> " :: String\n" <> name <> " = \"\"\"" <> value <> "\"\"\"" - -jsonExport :: ToJSON a => Text -> a -> Text -jsonExport name value = - multilineString name (T.decodeUtf8 . BSL.toStrict $ JSON.encodePretty value) - -sourceCodeExport :: Text -> SourceCode -> Text -sourceCodeExport name (SourceCode value) = multilineString name value - -psModule :: Text -> Text -> Text -psModule name body = "module " <> name <> " where" <> body - ------------------------------------------------------------- -writeUsecases :: FilePath -> IO () -writeUsecases outputDir = do - let usecases = - sourceCodeExport "vesting" vesting <> - sourceCodeExport "game" game <> - sourceCodeExport "crowdFunding" crowdFunding <> - sourceCodeExport "errorHandling" errorHandling <> - sourceCodeExport "starter" starter <> - jsonExport "contractDemos" contractDemos - usecasesModule = psModule "Playground.Usecases" usecases - BS.writeFile - (outputDir "Playground" "Usecases.purs") - (T.encodeUtf8 usecasesModule) - ------------------------------------------------------------- -writeTestData :: FilePath -> IO () -writeTestData outputDir = do - let ContractDemo { contractDemoContext - , contractDemoSimulations - , contractDemoEditorContents - } = head contractDemos - BSL.writeFile - (outputDir "compilation_response.json") - (JSON.encodePretty contractDemoContext) - void $ - itraverse - (\index -> - writeSimulation - (outputDir "evaluation_response" <> - show index <> ".json") - contractDemoEditorContents) - contractDemoSimulations - -writeSimulation :: FilePath -> SourceCode -> Simulation -> IO () -writeSimulation filename sourceCode simulation = do - result <- runExceptT $ runSimulation sourceCode simulation - case result of - Left err -> fail $ "Error evaluating simulation: " <> show err - Right json -> BSL.writeFile filename json - -maxInterpretationTime :: Second -maxInterpretationTime = 80 - -runSimulation :: - (MonadMask m, MonadError PlaygroundError m, MonadIO m) - => SourceCode - -> Simulation - -> m BSL.ByteString -runSimulation sourceCode Simulation {simulationActions, simulationWallets} = do - let evaluation = - Evaluation - { sourceCode - , wallets = simulationWallets - , program = - toJSON . encodeToText $ toExpression <$> simulationActions - } - expr <- PI.evaluationToExpr evaluation - result <- mapError InterpreterError $ Webghc.compile maxInterpretationTime False (SourceCode expr) - interpreterResult <- PI.decodeEvaluation result - pure $ JSON.encodePretty interpreterResult - -encodeToText :: ToJSON a => a -> Text -encodeToText = T.decodeUtf8 . BSL.toStrict . JSON.encode - -toExpression :: SimulatorAction -> Maybe (ContractCall Text) -toExpression = traverse (fmap encodeToText . formArgumentToJson) - ------------------------------------------------------------- -generate :: FilePath -> IO () -generate outputDir = do - generateWithSettings - mySettings - outputDir - myBridgeProxy - (Proxy @(API.API :<|> Auth.FrontendAPI)) - writeUsecases outputDir - writeTestData outputDir - putStrLn $ "Done: " <> outputDir - ------------------------------------------------------------- -contractDemos :: [ContractDemo] -contractDemos = - [ mkContractDemo - "Hello, world" - Usecases.helloWorld - HelloWorldSimulations.simulations - HelloWorld.schemas - HelloWorld.registeredKnownCurrencies - , mkContractDemo - "Starter" - Usecases.starter - StarterSimulations.simulations - Starter.schemas - Starter.registeredKnownCurrencies - , mkContractDemo - "Game" - Usecases.game - GameSimulations.simulations - Game.schemas - Game.registeredKnownCurrencies - , mkContractDemo - "Vesting" - Usecases.vesting - VestingSimulations.simulations - Vesting.schemas - Vesting.registeredKnownCurrencies - , mkContractDemo - "Crowd Funding" - Usecases.crowdFunding - CrowdfundingSimulations.simulations - Crowdfunding.schemas - Crowdfunding.registeredKnownCurrencies - , mkContractDemo - "Error Handling" - Usecases.errorHandling - ErrorHandlingSimulations.simulations - ErrorHandling.schemas - ErrorHandling.registeredKnownCurrencies - ] - -mkContractDemo :: - Text - -> SourceCode - -> [Simulation] - -> [FunctionSchema FormSchema] - -> [KnownCurrency] - -> ContractDemo -mkContractDemo contractDemoName contractDemoEditorContents contractDemoSimulations functionSchema knownCurrencies = - ContractDemo - { contractDemoName - , contractDemoEditorContents - , contractDemoSimulations - , contractDemoContext = - InterpreterResult - { warnings = [] - , result = - CompilationResult - {functionSchema, knownCurrencies} - } - } diff --git a/plutus-playground-server/app/Types.hs b/plutus-playground-server/app/Types.hs deleted file mode 100644 index e9212a679d..0000000000 --- a/plutus-playground-server/app/Types.hs +++ /dev/null @@ -1,19 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} - -module Types - ( Config(..) - ) where - -import Auth qualified -import Data.Aeson (FromJSON, parseJSON, withObject, (.:)) - -newtype Config = Config - { _authConfig :: Auth.Config - } - -instance FromJSON Config where - parseJSON = - withObject "config" $ \o -> do - _authConfig <- o .: "auth" - pure Config {..} diff --git a/plutus-playground-server/app/Webserver.hs b/plutus-playground-server/app/Webserver.hs deleted file mode 100644 index 715f5aa91c..0000000000 --- a/plutus-playground-server/app/Webserver.hs +++ /dev/null @@ -1,23 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeOperators #-} - -module Webserver where - -import Data.Proxy (Proxy (Proxy)) -import Data.Time.Units (Second) -import Network.Wai.Handler.Warp as Warp -import Playground.Server (initializeServerContext) -import Playground.Server qualified as Server -import Servant (serve, (:<|>) ((:<|>))) -import Webghc.Server qualified as Webghc - -type API = Server.Web :<|> Webghc.API - -run :: Int -> Second -> Maybe FilePath -> IO () -run port maxInterpretationTime secrets = do - appConfig <- initializeServerContext maxInterpretationTime secrets - handlers <- Server.mkHandlers appConfig - let server = handlers :<|> Webghc.server 80 - Warp.run port (serve (Proxy @API) server) diff --git a/plutus-playground-server/playground.yaml.sample b/plutus-playground-server/playground.yaml.sample deleted file mode 100644 index 4a76cfdc68..0000000000 --- a/plutus-playground-server/playground.yaml.sample +++ /dev/null @@ -1,12 +0,0 @@ -auth: - # Your github OAuth App Credentials. - github-client-id: "" - github-client-secret: "" - - # You can generate a good signature by running `openssl rand -hex 40` and pasting the result here: - jwt-signature: "" - - # This should match the client-facing schema/host/port. - frontend-url: "https://localhost:8009" - # This is the path the API will call once authenticated - github-cb-path: "/#/gh-oauth-cb" diff --git a/plutus-playground-server/plutus-playground-server.cabal b/plutus-playground-server/plutus-playground-server.cabal deleted file mode 100644 index 6735f7978c..0000000000 --- a/plutus-playground-server/plutus-playground-server.cabal +++ /dev/null @@ -1,312 +0,0 @@ -cabal-version: 2.0 -name: plutus-playground-server -version: 1.0.0.0 -license: Apache-2.0 -license-files: - LICENSE - NOTICE - -maintainer: kris.jenkins@tweag.io -author: Kris Jenkins -homepage: https://github.com/input-output-hk/plutus-apps#readme -bug-reports: https://github.com/input-output-hk/plutus-apps/issues -description: - Please see the README on GitHub at - -build-type: Simple -data-files: - test/gists1.json - usecases/Crowdfunding.hs - usecases/ErrorHandling.hs - usecases/Game.hs - usecases/Starter.hs - usecases/Vesting.hs - -source-repository head - type: git - location: https://github.com/input-output-hk/plutus-apps - -flag defer-plugin-errors - description: - Defer errors from the plugin, useful for things like Haddock that can't handle it. - - default: False - manual: True - -library - exposed-modules: - Crowdfunding - CrowdfundingSimulations - ErrorHandling - ErrorHandlingSimulations - Game - GameSimulations - HelloWorld - HelloWorldSimulations - Playground.Interpreter - Playground.Server - Playground.Usecases - SimulationUtils - Starter - StarterSimulations - Vesting - VestingSimulations - - hs-source-dirs: src usecases - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - - -- See Plutus Tx readme for why we need the following flags: - -- -fobject-code -fno-ignore-interface-pragmas and -fno-omit-interface-pragmas - ghc-options: - -Wall -Wcompat -Wunused-packages -Wincomplete-uni-patterns - -Wincomplete-record-updates -Wno-missing-import-lists - -Wredundant-constraints -fobject-code -fno-ignore-interface-pragmas - -fno-omit-interface-pragmas - - -------------------- - -- Local components - -------------------- - build-depends: - playground-common >=1.0.0 - , plutus-contract >=1.0.0 - , plutus-ledger >=1.0.0 - , plutus-ledger-constraints >=1.0.0 - , plutus-script-utils >=1.0.0 - - -------------------------- - -- Other IOG dependencies - -------------------------- - build-depends: - plutus-ledger-api >=1.0.0 - , plutus-tx >=1.0.0 - - if !(impl(ghcjs) || os(ghcjs)) - build-depends: plutus-tx-plugin >=1.0.0 - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - aeson - , base >=4.7 && <5 - , bytestring - , containers - , data-default - , exceptions - , file-embed - , http-client - , http-conduit - , jwt - , lens - , monad-logger - , mtl - , newtype-generics - , regex-compat - , row-types - , servant >=0.16 - , servant-client - , servant-client-core - , servant-server - , template-haskell - , text - , time-units - , transformers - , wai-cors - , web-ghc - -library plutus-playground-usecases - hs-source-dirs: usecases - other-modules: - Crowdfunding - CrowdfundingSimulations - ErrorHandling - ErrorHandlingSimulations - Game - GameSimulations - HelloWorld - HelloWorldSimulations - SimulationUtils - Starter - StarterSimulations - Vesting - VestingSimulations - - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - - -- See Plutus Tx readme for why we need the following flags: - -- -fobject-code -fno-ignore-interface-pragmas and -fno-omit-interface-pragmas - ghc-options: - -Wall -Wcompat -Wunused-packages -Wincomplete-uni-patterns - -Wincomplete-record-updates -Wredundant-constraints - -Wno-missing-signatures -Wno-missing-import-lists -fobject-code - -fno-ignore-interface-pragmas -fno-omit-interface-pragmas - - -------------------- - -- Local components - -------------------- - build-depends: - playground-common >=1.0.0 - , plutus-contract >=1.0.0 - , plutus-ledger >=1.0.0 - , plutus-ledger-constraints >=1.0.0 - , plutus-script-utils >=1.0.0 - - -------------------- - -- IOG dependencies - -------------------- - build-depends: - plutus-ledger-api >=1.0.0 - , plutus-tx >=1.0.0 - - if !(impl(ghcjs) || os(ghcjs)) - build-depends: plutus-tx-plugin >=1.0.0 - - if flag(defer-plugin-errors) - ghc-options: -fplugin-opt PlutusTx.Plugin:defer-errors - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - aeson - , base >=4.7 && <5 - , bytestring - , containers - , data-default - , lens - , mtl - , row-types - , text - , transformers - -executable plutus-playground-server - main-is: Main.hs - hs-source-dirs: app usecases - other-modules: - Crowdfunding - CrowdfundingSimulations - ErrorHandling - ErrorHandlingSimulations - Game - GameSimulations - HelloWorld - HelloWorldSimulations - PSGenerator - SimulationUtils - Starter - StarterSimulations - Types - Vesting - VestingSimulations - Webserver - - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - - -- See Plutus Tx readme for why we need the following flags: - -- -fobject-code -fno-ignore-interface-pragmas and -fno-omit-interface-pragmas - ghc-options: - -threaded -rtsopts -with-rtsopts=-N -Wall -Wcompat - -Wincomplete-uni-patterns -Wincomplete-record-updates - -Wno-missing-import-lists -Wredundant-constraints -O0 -fobject-code - -fno-ignore-interface-pragmas -fno-omit-interface-pragmas - - -------------------- - -- Local components - -------------------- - build-depends: - freer-extras >=1.0.0 - , playground-common >=1.0.0 - , plutus-contract >=1.0.0 - , plutus-ledger >=1.0.0 - , plutus-ledger-constraints >=1.0.0 - , plutus-playground-server >=1.0.0 - , plutus-playground-usecases >=1.0.0 - , plutus-script-utils >=1.0.0 - - -------------------------- - -- Other IOG dependencies - -------------------------- - build-depends: - plutus-ledger-api >=1.0.0 - , plutus-tx >=1.0.0 - - if !(impl(ghcjs) || os(ghcjs)) - build-depends: plutus-tx-plugin >=1.0.0 - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - aeson - , aeson-pretty - , base >=4.7 && <5 - , bytestring - , containers - , data-default - , data-default-class - , exceptions - , filepath - , lens - , monad-logger - , mtl - , optparse-applicative - , purescript-bridge - , row-types - , servant - , servant-purescript - , servant-server - , text - , time-units - , transformers - , warp - , web-ghc - -test-suite plutus-playground-server-test - type: exitcode-stdio-1.0 - main-is: Spec.hs - hs-source-dirs: test - other-modules: - GistSpec - Paths_plutus_playground_server - Playground.InterpreterSpec - Playground.UsecasesSpec - - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - - -- We don't want "-threaded" and friends here as there are many tests with heavy GHC compilation. - -- This is a hack as one can fine-tune test cases better (like sequential tests) with in-code tasty dependencies. - -- See #4085. - ghc-options: - -Wall -Wcompat -Wincomplete-uni-patterns - -Wincomplete-record-updates -Wno-missing-import-lists - -Wredundant-constraints -fprint-potential-instances - - -------------------- - -- Local components - -------------------- - build-depends: - playground-common >=1.0.0 - , plutus-contract >=1.0.0 - , plutus-ledger >=1.0.0 - , plutus-playground-server >=1.0.0 - , plutus-playground-usecases >=1.0.0 - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - aeson - , base >=4.7 && <5 - , bytestring - , mtl - , newtype-generics - , tasty - , tasty-hunit - , text - , time-units - , transformers - , web-ghc diff --git a/plutus-playground-server/secrets.example.json b/plutus-playground-server/secrets.example.json deleted file mode 100644 index 417364781d..0000000000 --- a/plutus-playground-server/secrets.example.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "jwt-signature": "somebigstring", - "frontend-url": "https://localhost:8009", - "github-cb-path": "/#/gh-oauth-cb", - "github-client-id": "client-id", - "github-client-secret": "client-secret" -} \ No newline at end of file diff --git a/plutus-playground-server/src/Playground/Interpreter.hs b/plutus-playground-server/src/Playground/Interpreter.hs deleted file mode 100644 index fb9d0fc270..0000000000 --- a/plutus-playground-server/src/Playground/Interpreter.hs +++ /dev/null @@ -1,196 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} - -module Playground.Interpreter where - -import Control.Exception (IOException, try) -import Control.Monad.Catch (MonadMask) -import Control.Monad.Error.Class (MonadError, liftEither, throwError) -import Control.Monad.Except.Extras (mapError) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Control.Newtype.Generics qualified as Newtype -import Data.Aeson qualified as JSON -import Data.Bifunctor (first) -import Data.ByteString.Char8 qualified as BS8 -import Data.ByteString.Lazy.Char8 qualified as BSL -import Data.Text (Text) -import Data.Text qualified as Text -import Language.Haskell.Interpreter (CompilationError (CompilationError, RawError), - InterpreterError (CompilationErrors), InterpreterResult (InterpreterResult), - SourceCode (SourceCode), Warning (Warning), avoidUnsafe) -import Language.Haskell.TH (Ppr, Q, pprint, runQ) -import Language.Haskell.TH.Syntax (liftString) -import Playground.Types (CompilationResult (CompilationResult), Evaluation (program, sourceCode, wallets), - EvaluationResult, - PlaygroundError (InterpreterError, JsonDecodingError, OtherError, decodingError, expected, input)) -import Servant.Client (ClientEnv) -import Text.Regex qualified as Regex -import Webghc.Client (runscript) -import Webghc.Server (CompileRequest (CompileRequest)) -import Webghc.Server qualified as Webghc - -replaceModuleName :: Text -> Text -replaceModuleName script = - let scriptString = Text.unpack script - regex = Regex.mkRegex "module .* where" - in Text.pack $ Regex.subRegex regex scriptString "module Main where" - -ensureMinimumImports :: (MonadError InterpreterError m) => SourceCode -> m () -ensureMinimumImports script = - let scriptString = Text.unpack . Newtype.unpack $ script - regex = - Regex.mkRegex - "^import[ \t]+Playground.Contract([ ]*$|[ \t]+\\(.*printSchemas.*\\)|[ \t]+\\(.*printSchemas.*\\))" - mMatches = Regex.matchRegexAll regex scriptString - in case mMatches of - Just _ -> pure () - Nothing -> - let filename = "" - row = 1 - column = 1 - text = - [ "You need to import `printSchemas` in order to compile successfully, you can do this with either", - "`import Playground.Contract`", - "or", - "`import Playground.Contract (printSchemas)`" - ] - errors = [CompilationError filename row column text] - in throwError $ CompilationErrors errors - -ensureKnownCurrenciesExists :: Text -> Text -ensureKnownCurrenciesExists script = - let scriptString = Text.unpack script - regex = Regex.mkRegex "^\\$\\(mkKnownCurrencies \\[.*])" - mMatches = Regex.matchRegexAll regex scriptString - in case mMatches of - Nothing -> script <> "\n$(mkKnownCurrencies [])" - Just _ -> script - -mkCompileScript :: Text -> Text -mkCompileScript script = - replaceModuleName script - <> Text.unlines - [ "", - "$ensureKnownCurrencies", - "", - "main :: IO ()", - "main = printSchemas (schemas, registeredKnownCurrencies)" - ] - -checkCode :: MonadError InterpreterError m => SourceCode -> m () -checkCode source = do - avoidUnsafe source - ensureMinimumImports source - -getCompilationResult :: MonadError InterpreterError m => InterpreterResult String -> m (InterpreterResult CompilationResult) -getCompilationResult (InterpreterResult warnings result) = - let eSchema = JSON.eitherDecodeStrict . BS8.pack $ result - in case eSchema of - Left err -> - throwError . CompilationErrors . pure . RawError $ - "unable to decode compilation result: " <> Text.pack err - <> "\n" - <> Text.pack result - Right ([schema], currencies) -> do - let warnings' = - Warning - "It looks like you have not made any functions available, use `$(mkFunctions ['functionA, 'functionB])` to be able to use `functionA` and `functionB`" : - warnings - pure . InterpreterResult warnings' $ - CompilationResult [schema] currencies - Right (schemas, currencies) -> - pure . InterpreterResult warnings $ - CompilationResult schemas currencies - -compile :: - ( MonadMask m, - MonadIO m, - MonadError InterpreterError m - ) => - ClientEnv -> - SourceCode -> - m (InterpreterResult CompilationResult) -compile clientEnv source = do - -- There are a couple of custom rules required for compilation - checkCode source - result <- runscript clientEnv $ CompileRequest { - code = mkCompileScript (Newtype.unpack source), - implicitPrelude = False - } - getCompilationResult result - -evaluationToExpr :: (MonadError PlaygroundError m, MonadIO m) => Evaluation -> m Text -evaluationToExpr evaluation = do - let source = sourceCode evaluation - mapError InterpreterError $ avoidUnsafe source - expr <- mkExpr evaluation - pure $ mkRunScript source (Text.pack expr) - -decodeEvaluation :: MonadError PlaygroundError m => InterpreterResult String -> m (InterpreterResult EvaluationResult) -decodeEvaluation (InterpreterResult warnings result) = - let decodeResult = JSON.eitherDecodeStrict . BS8.pack $ result :: Either String (Either PlaygroundError EvaluationResult) - in case decodeResult of - Left err -> - throwError - JsonDecodingError - { expected = "EvaluationResult", - decodingError = err, - input = result - } - Right eResult -> - case eResult of - Left err -> throwError err - Right result' -> - pure $ InterpreterResult warnings result' - -evaluateSimulation :: - ( MonadMask m, - MonadIO m, - MonadError PlaygroundError m - ) => - ClientEnv -> - Evaluation -> - m (InterpreterResult EvaluationResult) -evaluateSimulation clientEnv evaluation = do - expr <- evaluationToExpr evaluation - result <- mapError InterpreterError $ runscript clientEnv $ CompileRequest { - code = expr, - implicitPrelude = False - } - decodeEvaluation result - -mkRunScript :: SourceCode -> Text -> Text -mkRunScript (SourceCode script) expr = - replaceModuleName script <> "\n\nmain :: IO ()" <> "\nmain = printJson $ " - <> expr - -mkExpr :: (MonadError PlaygroundError m, MonadIO m) => Evaluation -> m String -mkExpr evaluation = do - let programJson = liftString . BSL.unpack . JSON.encode $ program evaluation - simulatorWalletsJson = - liftString . BSL.unpack . JSON.encode $ wallets evaluation - printQ [|stage endpoints $(programJson) $(simulatorWalletsJson)|] - -printQ :: (MonadError PlaygroundError m, MonadIO m, Ppr a) => Q a -> m String -printQ q = do - str <- liftIO . fmap toPlaygroundError . try . runQ . fmap pprint $ q - liftEither str - where - toPlaygroundError :: Either IOException a -> Either PlaygroundError a - toPlaygroundError = first (OtherError . show) - -{-{- HLINT ignore getJsonString -}-} -getJsonString :: (MonadError PlaygroundError m) => JSON.Value -> m String -getJsonString (JSON.String s) = pure $ Text.unpack s -getJsonString v = - throwError - JsonDecodingError - { expected = "String", - input = BSL.unpack $ JSON.encode v, - decodingError = "Expected a String." - } diff --git a/plutus-playground-server/src/Playground/Server.hs b/plutus-playground-server/src/Playground/Server.hs deleted file mode 100644 index d92334c20e..0000000000 --- a/plutus-playground-server/src/Playground/Server.hs +++ /dev/null @@ -1,156 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeOperators #-} - -module Playground.Server where - -import Auth qualified -import Auth.Types (OAuthClientId (OAuthClientId), OAuthClientSecret (OAuthClientSecret)) -import Control.Monad.Except (ExceptT, runExceptT, throwError) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Control.Monad.Logger (LoggingT, runStderrLoggingT) -import Control.Monad.Reader (ReaderT, runReaderT) -import Data.Aeson (decodeFileStrict) -import Data.Bits (toIntegralSized) -import Data.ByteString.Lazy.Char8 qualified as BSL -import Data.Proxy (Proxy (Proxy)) -import Data.Text (Text) -import Data.Text qualified as Text -import Data.Time.Units (Second, toMicroseconds) -import Language.Haskell.Interpreter (InterpreterError (CompilationErrors), InterpreterResult, SourceCode) -import Language.Haskell.Interpreter qualified as Interpreter -import Network.HTTP.Client.Conduit (defaultManagerSettings, managerResponseTimeout, responseTimeoutMicro) -import Network.HTTP.Conduit (newManager) -import Network.Wai.Middleware.Cors (cors, simpleCorsResourcePolicy) -import Playground.Interpreter qualified as PI -import Playground.Types (CompilationResult, Evaluation, EvaluationResult, PlaygroundError) -import Playground.Usecases (vesting) -import Servant (Application, err400, errBody, hoistServer, serve) -import Servant.API (Get, JSON, Post, ReqBody, (:<|>) ((:<|>)), (:>)) -import Servant.Client (ClientEnv, mkClientEnv, parseBaseUrl) -import Servant.Server (Handler (Handler), Server, ServerError) -import System.Environment (lookupEnv) -import Web.JWT qualified as JWT - -type API - = "contract" :> ReqBody '[ JSON] SourceCode :> Post '[ JSON] (Either Interpreter.InterpreterError (InterpreterResult CompilationResult)) - :<|> "evaluate" :> ReqBody '[ JSON] Evaluation :> Post '[ JSON] (Either PlaygroundError EvaluationResult) - :<|> "health" :> Get '[ JSON] () - -type Web = "api" :> (API :<|> Auth.API) - -compileSourceCode :: - ClientEnv - -> SourceCode - -> Handler (Either InterpreterError (InterpreterResult CompilationResult)) -compileSourceCode clientEnv sourceCode = do - r <- liftIO . runExceptT $ PI.compile clientEnv sourceCode - case r of - Right vs -> pure . Right $ vs - Left (CompilationErrors errors) -> - pure . Left $ CompilationErrors errors - Left e -> throwError $ err400 {errBody = BSL.pack . show $ e} - -evaluateSimulation :: - ClientEnv -> Evaluation -> Handler (Either PlaygroundError EvaluationResult) -evaluateSimulation clientEnv evaluation = do - result <- - liftIO . runExceptT $ - PI.evaluateSimulation clientEnv evaluation - pure $ Interpreter.result <$> result - -checkHealth :: ClientEnv -> Handler () -checkHealth clientEnv = - compileSourceCode clientEnv vesting >>= \case - Left e -> throwError $ err400 {errBody = BSL.pack . show $ e} - Right _ -> pure () - -liftedAuthServer :: Auth.GithubEndpoints -> Auth.Config -> Server Auth.API -liftedAuthServer githubEndpoints config = - hoistServer (Proxy @Auth.API) liftAuthToHandler Auth.server - where - liftAuthToHandler :: - ReaderT (Auth.GithubEndpoints, Auth.Config) (LoggingT (ExceptT ServerError IO)) a -> - Handler a - liftAuthToHandler = - Handler . runStderrLoggingT . flip runReaderT (githubEndpoints, config) - -mkHandlers :: MonadIO m => AppConfig -> m (Server Web) -mkHandlers AppConfig {..} = do - liftIO $ putStrLn "Interpreter ready" - githubEndpoints <- liftIO Auth.mkGithubEndpoints - pure $ (compileSourceCode clientEnv :<|> evaluateSimulation clientEnv :<|> checkHealth clientEnv) :<|> liftedAuthServer githubEndpoints authConfig - -app :: Server Web -> Application -app handlers = - cors (const $ Just policy) $ serve (Proxy @Web) handlers - where - policy = - simpleCorsResourcePolicy - -data AppConfig = AppConfig { authConfig :: Auth.Config, clientEnv :: ClientEnv } - -initializeServerContext :: MonadIO m => Second -> Maybe FilePath -> m AppConfig -initializeServerContext maxInterpretationTime secrets = liftIO $ do - putStrLn "Initializing Context" - authConfig <- mkAuthConfig secrets - mWebghcURL <- lookupEnv "WEBGHC_URL" - webghcURL <- case mWebghcURL of - Just url -> parseBaseUrl url - Nothing -> do - let localhost = "http://localhost:8009" - putStrLn $ "WEBGHC_URL not set, using " <> localhost - parseBaseUrl localhost - manager <- newManager $ defaultManagerSettings - { managerResponseTimeout = maybe - (managerResponseTimeout defaultManagerSettings) - responseTimeoutMicro . toIntegralSized - $ toMicroseconds maxInterpretationTime - } - let clientEnv = mkClientEnv manager webghcURL - pure $ AppConfig authConfig clientEnv - -mkAuthConfig :: MonadIO m => Maybe FilePath -> m Auth.Config -mkAuthConfig (Just path) = do - mConfig <- liftIO $ decodeFileStrict path - case mConfig of - Just config -> pure config - Nothing -> do - liftIO $ putStrLn $ "failed to decode " <> path - mkAuthConfig Nothing -mkAuthConfig Nothing = liftIO $ do - putStrLn "Initializing Context" - githubClientId <- getEnvOrEmpty "GITHUB_CLIENT_ID" - githubClientSecret <- getEnvOrEmpty "GITHUB_CLIENT_SECRET" - jwtSignature <- getEnvOrEmpty "JWT_SIGNATURE" - frontendURL <- getEnvOrEmpty "FRONTEND_URL" - cbPath <- getEnvOrEmpty "GITHUB_CALLBACK_PATH" - pure Auth.Config - { _configJWTSignature = JWT.hmacSecret jwtSignature, - _configFrontendUrl = frontendURL, - _configGithubCbPath = cbPath, - _configGithubClientId = OAuthClientId githubClientId, - _configGithubClientSecret = OAuthClientSecret githubClientSecret - } - -getEnvOrEmpty :: String -> IO Text -getEnvOrEmpty name = do - mEnv <- lookupEnv name - case mEnv of - Just env -> pure $ Text.pack env - Nothing -> do - putStrLn $ "Warning: " <> name <> " not set" - pure mempty - -initializeApplication :: AppConfig -> IO Application -initializeApplication config = do - handlers <- mkHandlers config - pure $ app handlers diff --git a/plutus-playground-server/src/Playground/Usecases.hs b/plutus-playground-server/src/Playground/Usecases.hs deleted file mode 100644 index 0d56a82804..0000000000 --- a/plutus-playground-server/src/Playground/Usecases.hs +++ /dev/null @@ -1,39 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} - -module Playground.Usecases where - -import Data.ByteString (ByteString) -import Data.FileEmbed (embedFile, makeRelativeToProject) -import Data.Text qualified as T -import Data.Text.Encoding qualified as T -import Language.Haskell.Interpreter (SourceCode (SourceCode)) - -marker :: T.Text -marker = "TRIM TO HERE\n" - -strip :: T.Text -> T.Text -strip text = snd $ T.breakOnEnd marker text - -process :: ByteString -> SourceCode -process = SourceCode . strip . T.decodeUtf8 - -vesting :: SourceCode -vesting = process $(makeRelativeToProject "usecases/Vesting.hs" >>= embedFile) - -game :: SourceCode -game = process $(makeRelativeToProject "usecases/Game.hs" >>= embedFile) - -errorHandling :: SourceCode -errorHandling = - process $(makeRelativeToProject "usecases/ErrorHandling.hs" >>= embedFile) - -crowdFunding :: SourceCode -crowdFunding = - process $(makeRelativeToProject "usecases/Crowdfunding.hs" >>= embedFile) - -starter :: SourceCode -starter = process $(makeRelativeToProject "usecases/Starter.hs" >>= embedFile) - -helloWorld :: SourceCode -helloWorld = process $(makeRelativeToProject "usecases/HelloWorld.hs" >>= embedFile) diff --git a/plutus-playground-server/test/GistSpec.hs b/plutus-playground-server/test/GistSpec.hs deleted file mode 100644 index 7e13c140ca..0000000000 --- a/plutus-playground-server/test/GistSpec.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module GistSpec - ( tests - ) where - -import Data.Aeson (eitherDecode) -import Data.ByteString.Lazy qualified as LBS -import Data.Text () -import Gist (Gist) -import Paths_plutus_playground_server (getDataFileName) -import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (assertEqual, testCase) - -tests :: TestTree -tests = testGroup "Schema" [gistJsonHandlingTests] - -gistJsonHandlingTests :: TestTree -gistJsonHandlingTests = - testGroup - "Gist JSON handling" - [ testCase "Should be able to parse a github response" $ do - input1 <- LBS.readFile =<< getDataFileName "test/gists1.json" - let decoded :: Either String [Gist] = eitherDecode input1 - assertEqual "" (length <$> decoded) (Right 30) - ] diff --git a/plutus-playground-server/test/Playground/InterpreterSpec.hs b/plutus-playground-server/test/Playground/InterpreterSpec.hs deleted file mode 100644 index ed8f9c2d35..0000000000 --- a/plutus-playground-server/test/Playground/InterpreterSpec.hs +++ /dev/null @@ -1,70 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module Playground.InterpreterSpec - ( tests - ) where - -import Control.Monad.Except (runExceptT) -import Data.Aeson qualified as JSON -import Data.Aeson.Text qualified as JSON -import Data.Text (Text) -import Data.Text qualified as Text -import Data.Text.Lazy qualified as TL -import Language.Haskell.Interpreter (SourceCode (SourceCode)) -import Ledger.Ada qualified as Ada -import Playground.Interpreter (mkExpr, mkRunScript) -import Playground.Types (ContractCall (AddBlocks), Evaluation (Evaluation), PlaygroundError, SimulatorAction, - SimulatorWallet (SimulatorWallet), program, sourceCode, wallets) -import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (assertEqual, testCase) -import Wallet.Emulator.Types (WalletNumber (..)) - -tests :: TestTree -tests = testGroup "Playground.Interpreter" [mkRunScriptTest] - -mkRunScriptTest :: TestTree -mkRunScriptTest = - testGroup - "mkRunScript" - [ testCase "Should match a simple template" $ do - let program = - JSON.toJSON - ([AddBlocks 2, AddBlocks 4] :: [SimulatorAction]) - wallets = - [ SimulatorWallet (WalletNumber 1) (Ada.toValue 5) - , SimulatorWallet (WalletNumber 2) (Ada.toValue 10) - ] - expr :: Either PlaygroundError String <- - runExceptT $ - mkExpr - (Evaluation {sourceCode = sourceCode1, wallets, program}) - assertEqual - "" - (Right $ - Text.stripEnd $ - Text.unlines - [ "module Main where" - , "" - , "foo :: Int" - , "foo = 5" - , "" - , "" - , "main :: IO ()" - , "main = printJson $ stage endpoints " <> - toJSONString program <> - " " <> - toJSONString wallets - ]) - (mkRunScript sourceCode1 . Text.pack <$> expr) - ] - -sourceCode1 :: SourceCode -sourceCode1 = - SourceCode $ Text.unlines ["module Game where", "", "foo :: Int", "foo = 5"] - -toJSONString :: JSON.ToJSON a => a -> Text -toJSONString = - TL.toStrict . - JSON.encodeToLazyText . JSON.String . TL.toStrict . JSON.encodeToLazyText diff --git a/plutus-playground-server/test/Playground/UsecasesSpec.hs b/plutus-playground-server/test/Playground/UsecasesSpec.hs deleted file mode 100644 index f7c613bb28..0000000000 --- a/plutus-playground-server/test/Playground/UsecasesSpec.hs +++ /dev/null @@ -1,361 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-} - -module Playground.UsecasesSpec - ( tests - ) where - -import Control.Monad (unless) -import Control.Monad.Except (runExceptT) -import Control.Monad.Except.Extras (mapError) -import Control.Newtype.Generics (over) -import Crowdfunding (Contribution (Contribution), contribValue) -import Data.Aeson (ToJSON) -import Data.Aeson qualified as JSON -import Data.Aeson.Text qualified as JSON -import Data.Foldable (traverse_) -import Data.List (isPrefixOf) -import Data.List.NonEmpty (NonEmpty ((:|))) -import Data.Maybe (fromMaybe) -import Data.Text qualified as Text -import Data.Text.IO qualified as Text -import Data.Text.Lazy qualified as TL -import Data.Time.Units (Minute) -import Game (GuessParams (GuessParams), LockParams (LockParams), amount, guessWord, secretWord) -import Interpreter qualified as Webghc -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult (InterpreterResult, result), - SourceCode (SourceCode)) -import Ledger.Ada (adaValueOf, lovelaceValueOf) -import Ledger.Blockchain (OnChainTx (..)) -import Ledger.Scripts (ValidatorHash (ValidatorHash)) -import Ledger.Value (TokenName (TokenName), Value) -import Playground.Interpreter qualified as PI -import Playground.Types (CompilationResult (CompilationResult), - ContractCall (AddBlocks, AddBlocksUntil, CallEndpoint, PayToWallet), Evaluation (Evaluation), - EvaluationResult (EvaluationResult), Expression, FunctionSchema (FunctionSchema), - KnownCurrency (KnownCurrency), PlaygroundError (InterpreterError), - SimulatorWallet (SimulatorWallet), adaCurrency, argument, argumentValues, caller, emulatorLog, - endpointDescription, feesDistribution, fundsDistribution, program, resultRollup, - simulatorWalletBalance, simulatorWalletWallet, sourceCode, walletKeys, wallets) -import Playground.Usecases (crowdFunding, errorHandling, game, vesting) -import Schema (FormSchema (FormSchemaUnit, FormSchemaValue)) -import System.Environment (lookupEnv) -import Test.Tasty (TestTree, testGroup) -import Test.Tasty.HUnit (Assertion, assertBool, assertEqual, assertFailure, testCase) -import Wallet.Emulator.Types (WalletNumber (..), fromWalletNumber) -import Wallet.Rollup.Render (showBlockchain) -import Wallet.Rollup.Types (AnnotatedTx (..)) -import Wallet.Types (EndpointDescription (EndpointDescription)) - -tests :: TestTree -tests = - testGroup - "Playground.Usecases" - [ runningInNixBuildTest - , vestingTest - , gameTest - , errorHandlingTest - , crowdfundingTest - , knownCurrencyTest - ] - -maxInterpretationTime :: Minute -maxInterpretationTime = 2 - -w1, w2, w3, w4, w5 :: WalletNumber -w1 = WalletNumber 1 - -w2 = WalletNumber 2 - -w3 = WalletNumber 3 - -w4 = WalletNumber 4 - -w5 = WalletNumber 5 - -mkSimulatorWallet :: WalletNumber -> Value -> SimulatorWallet -mkSimulatorWallet simulatorWalletWallet simulatorWalletBalance = - SimulatorWallet {..} - --- Unfortunately it's currently not possible to get these tests to work outside of a nix build. --- Running `cabal test` will yield a lot of import errors because of missing modules. --- --- See the README.md for details on how to run the tests with nix. -runningInNixBuildTest :: TestTree -runningInNixBuildTest = - testGroup - "nixBuild" - [ testCase "needs to be executed via nix-build" $ do - nixBuildTop <- fromMaybe "" <$> lookupEnv "NIX_BUILD_TOP" - assertBool "UsecasesSpec will only work when executed as part of a nix build" (nixBuildTop == "/build" || "/private/tmp/nix-build" `isPrefixOf` nixBuildTop) - ] - -vestingTest :: TestTree -vestingTest = - testGroup - "vesting" - [ compilationChecks vesting - , testCase "should compile with the expected schema" $ do - Right (InterpreterResult _ (CompilationResult result _)) <- - compile vesting - assertEqual - "" - [ FunctionSchema - { endpointDescription = EndpointDescription "retrieve funds" - , argument = FormSchemaValue - } - , FunctionSchema - { endpointDescription = EndpointDescription "vest funds" - , argument = FormSchemaUnit - } - ] - result - , testCase "should run simple evaluation" $ - evaluate (mkEvaluation []) >>= - hasFundsDistribution - [ mkSimulatorWallet w1 hundredMLovelace - , mkSimulatorWallet w2 hundredMLovelace - ] - , testCase "should run simple wait evaluation" $ - evaluate (mkEvaluation [AddBlocks 10]) >>= - hasFundsDistribution - [ mkSimulatorWallet w1 hundredMLovelace - , mkSimulatorWallet w2 hundredMLovelace - ] - , testCase "should run vest funds evaluation" $ - evaluate vestFundsEval >>= - hasFundsDistribution - [ mkSimulatorWallet w1 hundredMLovelace - , mkSimulatorWallet w2 $ lovelaceValueOf 20_000_000 - ] - , testCase "should run vest and a partial retrieve of funds" $ - evaluate vestAndPartialRetrieveEval >>= - hasFundsDistribution - [ mkSimulatorWallet w1 $ lovelaceValueOf 150_000_000 - , mkSimulatorWallet w2 $ lovelaceValueOf 20_000_000 - ] - , testCase "should run vest and a full retrieve of funds" $ - evaluate vestAndFullRetrieveEval >>= - hasFundsDistribution - [ mkSimulatorWallet w1 $ lovelaceValueOf 180_000_000 - , mkSimulatorWallet w2 $ lovelaceValueOf 20_000_000 - ] - ] - where - hundredMLovelace = lovelaceValueOf 100_000_000 - mkEvaluation :: [Expression] -> Evaluation - mkEvaluation expressions = - Evaluation - { wallets = - [ mkSimulatorWallet w1 hundredMLovelace - , mkSimulatorWallet w2 hundredMLovelace - ] - , sourceCode = vesting - , program = toJSONString expressions - } - vestFundsEval = mkEvaluation [vestFunds w2, AddBlocks 1] - vestAndPartialRetrieveEval = - mkEvaluation - [vestFunds w2, AddBlocks 20, retrieveFunds w1 50_000_000, AddBlocks 2] - vestAndFullRetrieveEval = - mkEvaluation - [vestFunds w2, AddBlocks 40, retrieveFunds w1 80_000_000, AddBlocks 5] - vestFunds caller = callEndpoint "vest funds" caller () - retrieveFunds caller balance = - callEndpoint "retrieve funds" caller $ lovelaceValueOf balance - -gameTest :: TestTree -gameTest = - testGroup - "game" - [ compilationChecks game - , testCase "should keep the funds" $ - evaluate (mkEvaluation [lock w2 "abcde" twoAda, AddBlocks 1, guess w1 "ade", AddBlocks 1]) >>= - hasFundsDistribution - [ mkSimulatorWallet w1 tenAda - , mkSimulatorWallet w2 (adaValueOf 8) - ] - , testCase "should unlock the funds" $ - evaluate (mkEvaluation [lock w2 "abcde" twoAda, AddBlocks 1, guess w1 "abcde", AddBlocks 1]) >>= - hasFundsDistribution - [ mkSimulatorWallet w1 (adaValueOf 12) - , mkSimulatorWallet w2 (adaValueOf 8) - ] - , testCase "Sequential fund transfer - PayToWallet" $ - evaluate (payAll w3 w4 w5) >>= - hasFundsDistribution - [ mkSimulatorWallet w3 tenAda - , mkSimulatorWallet w4 tenAda - , mkSimulatorWallet w5 tenAda - ] - , testCase "Sequential fund transfer - PayToWallet" $ - evaluate (payAll w1 w2 w3) >>= - hasFundsDistribution - [ mkSimulatorWallet w1 tenAda - , mkSimulatorWallet w2 tenAda - , mkSimulatorWallet w3 tenAda - ] - ] - where - tenAda = adaValueOf 10 - sourceCode = game - wallets = [mkSimulatorWallet w1 tenAda, mkSimulatorWallet w2 tenAda] - mkEvaluation :: [Expression] -> Evaluation - mkEvaluation expressions = - Evaluation - {sourceCode = game, wallets, program = toJSONString expressions} - lock caller secretWord amount = - callEndpoint "lock" caller $ LockParams {secretWord, amount} - guess caller guessWord = - callEndpoint "guess" caller $ GuessParams {guessWord} - payAll a b c = - Evaluation - { sourceCode - , wallets = - [ mkSimulatorWallet a tenAda - , mkSimulatorWallet b tenAda - , mkSimulatorWallet c tenAda - ] - , program = - toJSONString - ([ PayToWallet a b nineAda - , PayToWallet b c nineAda - , PayToWallet c a nineAda - ] :: [Expression]) - } - nineAda = adaValueOf 9 - twoAda = adaValueOf 2 - -hasFundsDistribution :: - [SimulatorWallet] - -> Either PlaygroundError (InterpreterResult EvaluationResult) - -> Assertion -hasFundsDistribution _ (Left err) = assertFailure $ show err -hasFundsDistribution requiredDistribution (Right InterpreterResult {result = EvaluationResult {..}}) = do - let addFees fund fee = fund { simulatorWalletBalance = simulatorWalletBalance fund <> simulatorWalletBalance fee } - let noFeesDistribution = zipWith addFees fundsDistribution feesDistribution - unless (requiredDistribution == noFeesDistribution) $ do - Text.putStrLn $ - either id id $ showBlockchain - (fmap (fmap fromWalletNumber) walletKeys) - (fmap (fmap (\AnnotatedTx {tx, valid} -> if valid then Valid tx else Invalid tx)) resultRollup) - traverse_ print $ reverse emulatorLog - assertEqual "" requiredDistribution noFeesDistribution - -errorHandlingTest :: TestTree -errorHandlingTest = testGroup "errorHandling" [compilationChecks errorHandling] - -crowdfundingTest :: TestTree -crowdfundingTest = - testGroup - "crowdfunding" - [ compilationChecks crowdFunding - , testCase "should run successful campaign" $ - evaluate successfulCampaign >>= - hasFundsDistribution - [ mkSimulatorWallet w1 $ lovelaceValueOf 600_000_000 - , mkSimulatorWallet w2 $ lovelaceValueOf 190_000_000 - , mkSimulatorWallet w3 $ lovelaceValueOf 200_000_000 - , mkSimulatorWallet w4 $ lovelaceValueOf 210_000_000 - ] - ] - where - sourceCode = crowdFunding - successfulCampaign = - Evaluation - { wallets = - [ mkSimulatorWallet w1 $ lovelaceValueOf 300_000_000 - , mkSimulatorWallet w2 $ lovelaceValueOf 300_000_000 - , mkSimulatorWallet w3 $ lovelaceValueOf 300_000_000 - , mkSimulatorWallet w4 $ lovelaceValueOf 300_000_000 - ] - , program = - toJSONString - [ scheduleCollection w1 - , contribute w2 $ lovelaceValueOf 110_000_000 - , contribute w3 $ lovelaceValueOf 100_000_000 - , contribute w4 $ lovelaceValueOf 90_000_000 - , AddBlocks 1 - , AddBlocksUntil 41 - , AddBlocks 1 - ] - , sourceCode - } - scheduleCollection caller = callEndpoint "schedule collection" caller () - contribute caller contribValue = - callEndpoint "contribute" caller $ Contribution {contribValue} - -knownCurrencyTest :: TestTree -knownCurrencyTest = - testCase "should return registered known currencies" $ do - currencies <- compile source - hasKnownCurrency currencies - where - source = - SourceCode $ - Text.unlines - [ "import Playground.Contract" - , "import Data.Text" - , "import Data.List.NonEmpty (NonEmpty ((:|)))" - , "import Ledger.Value (TokenName(TokenName))" - , "import Ledger.Scripts (ValidatorHash (..))" - , "import Playground.Types (KnownCurrency (..))" - , "import PlutusTx.Prelude" - , "" - , "myCurrency :: KnownCurrency" - , "myCurrency = KnownCurrency (ValidatorHash \"\") \"MyCurrency\" (TokenName \"MyToken\" :| [])" - , "$(mkKnownCurrencies ['myCurrency])" - , "" - , "schemas = []" - , "iotsDefinitions = \"\"" - ] - expectedCurrencies = - [ adaCurrency - , KnownCurrency - (ValidatorHash "") - "MyCurrency" - (TokenName "MyToken" :| []) - ] - hasKnownCurrency (Right (InterpreterResult _ (CompilationResult _ currencies))) = - assertEqual "" expectedCurrencies currencies - hasKnownCurrency other = - assertFailure $ "Compilation failed: " <> show other - -compile :: - SourceCode - -> IO (Either InterpreterError (InterpreterResult CompilationResult)) -compile source = runExceptT $ do - PI.checkCode source - result <- Webghc.compile maxInterpretationTime False $ over SourceCode PI.mkCompileScript source - PI.getCompilationResult result - -evaluate :: - Evaluation - -> IO (Either PlaygroundError (InterpreterResult EvaluationResult)) -evaluate evaluation = runExceptT $ do - expr <- PI.evaluationToExpr evaluation - result <- mapError InterpreterError $ Webghc.compile maxInterpretationTime False (SourceCode expr) - PI.decodeEvaluation result - -compilationChecks :: SourceCode -> TestTree -compilationChecks source = - testCase "should compile" $ do - compiled <- compile source - case compiled of - Left err -> assertFailure $ "Compilation failed: " <> show err - Right _ -> pure () - --- | Encode a value in JSON, then make a JSON *string* from that -toJSONString :: ToJSON a => a -> JSON.Value -toJSONString = JSON.String . TL.toStrict . JSON.encodeToLazyText - -callEndpoint :: ToJSON a => EndpointDescription -> WalletNumber -> a -> Expression -callEndpoint endpointDescription caller param = - CallEndpoint - { caller - , argumentValues = - FunctionSchema {endpointDescription, argument = toJSONString param} - } diff --git a/plutus-playground-server/test/Spec.hs b/plutus-playground-server/test/Spec.hs deleted file mode 100644 index 77bc69e2ea..0000000000 --- a/plutus-playground-server/test/Spec.hs +++ /dev/null @@ -1,18 +0,0 @@ -module Main - ( main - ) where - -import GistSpec qualified -import Playground.InterpreterSpec qualified -import Playground.UsecasesSpec qualified -import Test.Tasty (defaultMain, testGroup) - -main :: IO () -main = - defaultMain $ - testGroup - "all tests" - [ GistSpec.tests - , Playground.UsecasesSpec.tests - , Playground.InterpreterSpec.tests - ] diff --git a/plutus-playground-server/test/gists1.json b/plutus-playground-server/test/gists1.json deleted file mode 100644 index 346e59dd1a..0000000000 --- a/plutus-playground-server/test/gists1.json +++ /dev/null @@ -1,1531 +0,0 @@ -[ - { - "url": "https://api.github.com/gists/d0a332fd11dda3e656bc37ba315ae6ba", - "forks_url": "https://api.github.com/gists/d0a332fd11dda3e656bc37ba315ae6ba/forks", - "commits_url": "https://api.github.com/gists/d0a332fd11dda3e656bc37ba315ae6ba/commits", - "id": "d0a332fd11dda3e656bc37ba315ae6ba", - "node_id": "MDQ6R2lzdGQwYTMzMmZkMTFkZGEzZTY1NmJjMzdiYTMxNWFlNmJh", - "git_pull_url": "https://gist.github.com/d0a332fd11dda3e656bc37ba315ae6ba.git", - "git_push_url": "https://gist.github.com/d0a332fd11dda3e656bc37ba315ae6ba.git", - "html_url": "https://gist.github.com/d0a332fd11dda3e656bc37ba315ae6ba", - "files": { - "index.js": { - "filename": "index.js", - "type": "application/javascript", - "language": "JavaScript", - "raw_url": "https://gist.githubusercontent.com/Gvetri/d0a332fd11dda3e656bc37ba315ae6ba/raw/f9fc81af03f1c0b29aca775c70f210d9ce9dc663/index.js", - "size": 2905 - } - }, - "public": true, - "created_at": "2019-01-18T10:50:03Z", - "updated_at": "2019-01-18T10:50:03Z", - "description": "Prueba", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/d0a332fd11dda3e656bc37ba315ae6ba/comments", - "owner": { - "login": "Gvetri", - "id": 8773754, - "node_id": "MDQ6VXNlcjg3NzM3NTQ=", - "avatar_url": "https://avatars0.githubusercontent.com/u/8773754?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/Gvetri", - "html_url": "https://github.com/Gvetri", - "followers_url": "https://api.github.com/users/Gvetri/followers", - "following_url": "https://api.github.com/users/Gvetri/following{/other_user}", - "gists_url": "https://api.github.com/users/Gvetri/gists{/gist_id}", - "starred_url": "https://api.github.com/users/Gvetri/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/Gvetri/subscriptions", - "organizations_url": "https://api.github.com/users/Gvetri/orgs", - "repos_url": "https://api.github.com/users/Gvetri/repos", - "events_url": "https://api.github.com/users/Gvetri/events{/privacy}", - "received_events_url": "https://api.github.com/users/Gvetri/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/05ad0b9e53dda291f7ef8f6fe70c13f3", - "forks_url": "https://api.github.com/gists/05ad0b9e53dda291f7ef8f6fe70c13f3/forks", - "commits_url": "https://api.github.com/gists/05ad0b9e53dda291f7ef8f6fe70c13f3/commits", - "id": "05ad0b9e53dda291f7ef8f6fe70c13f3", - "node_id": "MDQ6R2lzdDA1YWQwYjllNTNkZGEyOTFmN2VmOGY2ZmU3MGMxM2Yz", - "git_pull_url": "https://gist.github.com/05ad0b9e53dda291f7ef8f6fe70c13f3.git", - "git_push_url": "https://gist.github.com/05ad0b9e53dda291f7ef8f6fe70c13f3.git", - "html_url": "https://gist.github.com/05ad0b9e53dda291f7ef8f6fe70c13f3", - "files": { - "ami.tf": { - "filename": "ami.tf", - "type": "text/plain", - "language": "HCL", - "raw_url": "https://gist.githubusercontent.com/KotMeow/05ad0b9e53dda291f7ef8f6fe70c13f3/raw/cbccc210f864c031c87f2bc118b4caec0f2e6fa2/ami.tf", - "size": 146 - } - }, - "public": true, - "created_at": "2019-01-18T10:49:59Z", - "updated_at": "2019-01-18T10:49:59Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/05ad0b9e53dda291f7ef8f6fe70c13f3/comments", - "owner": { - "login": "KotMeow", - "id": 10243131, - "node_id": "MDQ6VXNlcjEwMjQzMTMx", - "avatar_url": "https://avatars3.githubusercontent.com/u/10243131?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/KotMeow", - "html_url": "https://github.com/KotMeow", - "followers_url": "https://api.github.com/users/KotMeow/followers", - "following_url": "https://api.github.com/users/KotMeow/following{/other_user}", - "gists_url": "https://api.github.com/users/KotMeow/gists{/gist_id}", - "starred_url": "https://api.github.com/users/KotMeow/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/KotMeow/subscriptions", - "organizations_url": "https://api.github.com/users/KotMeow/orgs", - "repos_url": "https://api.github.com/users/KotMeow/repos", - "events_url": "https://api.github.com/users/KotMeow/events{/privacy}", - "received_events_url": "https://api.github.com/users/KotMeow/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/2ddb94ea188a2d76cb1a71c56f4008a5", - "forks_url": "https://api.github.com/gists/2ddb94ea188a2d76cb1a71c56f4008a5/forks", - "commits_url": "https://api.github.com/gists/2ddb94ea188a2d76cb1a71c56f4008a5/commits", - "id": "2ddb94ea188a2d76cb1a71c56f4008a5", - "node_id": "MDQ6R2lzdDJkZGI5NGVhMTg4YTJkNzZjYjFhNzFjNTZmNDAwOGE1", - "git_pull_url": "https://gist.github.com/2ddb94ea188a2d76cb1a71c56f4008a5.git", - "git_push_url": "https://gist.github.com/2ddb94ea188a2d76cb1a71c56f4008a5.git", - "html_url": "https://gist.github.com/2ddb94ea188a2d76cb1a71c56f4008a5", - "files": { - "component.vue": { - "filename": "component.vue", - "type": "text/plain", - "language": "Vue", - "raw_url": "https://gist.githubusercontent.com/Insayt/2ddb94ea188a2d76cb1a71c56f4008a5/raw/1ae7b6e233f1dcce66fa599e903aef73a7d59ee6/component.vue", - "size": 43397 - } - }, - "public": true, - "created_at": "2019-01-18T10:49:49Z", - "updated_at": "2019-01-18T10:50:06Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/2ddb94ea188a2d76cb1a71c56f4008a5/comments", - "owner": { - "login": "Insayt", - "id": 5527516, - "node_id": "MDQ6VXNlcjU1Mjc1MTY=", - "avatar_url": "https://avatars0.githubusercontent.com/u/5527516?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/Insayt", - "html_url": "https://github.com/Insayt", - "followers_url": "https://api.github.com/users/Insayt/followers", - "following_url": "https://api.github.com/users/Insayt/following{/other_user}", - "gists_url": "https://api.github.com/users/Insayt/gists{/gist_id}", - "starred_url": "https://api.github.com/users/Insayt/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/Insayt/subscriptions", - "organizations_url": "https://api.github.com/users/Insayt/orgs", - "repos_url": "https://api.github.com/users/Insayt/repos", - "events_url": "https://api.github.com/users/Insayt/events{/privacy}", - "received_events_url": "https://api.github.com/users/Insayt/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/47a20a1313576f71a488e54d71b54d03", - "forks_url": "https://api.github.com/gists/47a20a1313576f71a488e54d71b54d03/forks", - "commits_url": "https://api.github.com/gists/47a20a1313576f71a488e54d71b54d03/commits", - "id": "47a20a1313576f71a488e54d71b54d03", - "node_id": "MDQ6R2lzdDQ3YTIwYTEzMTM1NzZmNzFhNDg4ZTU0ZDcxYjU0ZDAz", - "git_pull_url": "https://gist.github.com/47a20a1313576f71a488e54d71b54d03.git", - "git_push_url": "https://gist.github.com/47a20a1313576f71a488e54d71b54d03.git", - "html_url": "https://gist.github.com/47a20a1313576f71a488e54d71b54d03", - "files": { - "FilesSnapshot.xml": { - "filename": "FilesSnapshot.xml", - "type": "application/xml", - "language": "XML", - "raw_url": "https://gist.githubusercontent.com/choco-bot/47a20a1313576f71a488e54d71b54d03/raw/b8a10f376cc9df1eeafc5a7caabfd04b269e4e10/FilesSnapshot.xml", - "size": 4620 - }, - "Install.txt": { - "filename": "Install.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/47a20a1313576f71a488e54d71b54d03/raw/f1ff9d3713a524b5e3277a45dc554c87497e59aa/Install.txt", - "size": 20516 - }, - "Uninstall.txt": { - "filename": "Uninstall.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/47a20a1313576f71a488e54d71b54d03/raw/b0bcbda46abfabdcd2df7d3bde2783b984dc5795/Uninstall.txt", - "size": 27685 - }, - "_Summary.md": { - "filename": "_Summary.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/choco-bot/47a20a1313576f71a488e54d71b54d03/raw/34285b3e2132e80368fb1ea484f685511b7552fa/_Summary.md", - "size": 482 - } - }, - "public": true, - "created_at": "2019-01-18T10:49:21Z", - "updated_at": "2019-01-18T10:49:21Z", - "description": "aws-password-extractor v1.1.0 - Passed - Package Tests Results", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/47a20a1313576f71a488e54d71b54d03/comments", - "owner": { - "login": "choco-bot", - "id": 6270979, - "node_id": "MDQ6VXNlcjYyNzA5Nzk=", - "avatar_url": "https://avatars2.githubusercontent.com/u/6270979?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/choco-bot", - "html_url": "https://github.com/choco-bot", - "followers_url": "https://api.github.com/users/choco-bot/followers", - "following_url": "https://api.github.com/users/choco-bot/following{/other_user}", - "gists_url": "https://api.github.com/users/choco-bot/gists{/gist_id}", - "starred_url": "https://api.github.com/users/choco-bot/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/choco-bot/subscriptions", - "organizations_url": "https://api.github.com/users/choco-bot/orgs", - "repos_url": "https://api.github.com/users/choco-bot/repos", - "events_url": "https://api.github.com/users/choco-bot/events{/privacy}", - "received_events_url": "https://api.github.com/users/choco-bot/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/93c17f99bb3df72c6a5d9749e795f3cc", - "forks_url": "https://api.github.com/gists/93c17f99bb3df72c6a5d9749e795f3cc/forks", - "commits_url": "https://api.github.com/gists/93c17f99bb3df72c6a5d9749e795f3cc/commits", - "id": "93c17f99bb3df72c6a5d9749e795f3cc", - "node_id": "MDQ6R2lzdDkzYzE3Zjk5YmIzZGY3MmM2YTVkOTc0OWU3OTVmM2Nj", - "git_pull_url": "https://gist.github.com/93c17f99bb3df72c6a5d9749e795f3cc.git", - "git_push_url": "https://gist.github.com/93c17f99bb3df72c6a5d9749e795f3cc.git", - "html_url": "https://gist.github.com/93c17f99bb3df72c6a5d9749e795f3cc", - "files": { - "main.c": { - "filename": "main.c", - "type": "text/plain", - "language": "C", - "raw_url": "https://gist.githubusercontent.com/p-sam/93c17f99bb3df72c6a5d9749e795f3cc/raw/ea302a13b32635b52c0491d183b2fb842e52b94a/main.c", - "size": 1046 - }, - "web_wifi.c": { - "filename": "web_wifi.c", - "type": "text/plain", - "language": "C", - "raw_url": "https://gist.githubusercontent.com/p-sam/93c17f99bb3df72c6a5d9749e795f3cc/raw/6a017acb26341d91600451aee3c994f075ca4043/web_wifi.c", - "size": 1399 - }, - "web_wifi.h": { - "filename": "web_wifi.h", - "type": "text/plain", - "language": "C", - "raw_url": "https://gist.githubusercontent.com/p-sam/93c17f99bb3df72c6a5d9749e795f3cc/raw/41a58ac6932697d42d3bcf5c23678c939ade3b06/web_wifi.h", - "size": 387 - } - }, - "public": true, - "created_at": "2019-01-18T10:49:16Z", - "updated_at": "2019-01-18T10:49:16Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/93c17f99bb3df72c6a5d9749e795f3cc/comments", - "owner": { - "login": "p-sam", - "id": 17620180, - "node_id": "MDQ6VXNlcjE3NjIwMTgw", - "avatar_url": "https://avatars0.githubusercontent.com/u/17620180?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/p-sam", - "html_url": "https://github.com/p-sam", - "followers_url": "https://api.github.com/users/p-sam/followers", - "following_url": "https://api.github.com/users/p-sam/following{/other_user}", - "gists_url": "https://api.github.com/users/p-sam/gists{/gist_id}", - "starred_url": "https://api.github.com/users/p-sam/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/p-sam/subscriptions", - "organizations_url": "https://api.github.com/users/p-sam/orgs", - "repos_url": "https://api.github.com/users/p-sam/repos", - "events_url": "https://api.github.com/users/p-sam/events{/privacy}", - "received_events_url": "https://api.github.com/users/p-sam/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/ecb0fdee1e1997bc0d9fc2c40df96a79", - "forks_url": "https://api.github.com/gists/ecb0fdee1e1997bc0d9fc2c40df96a79/forks", - "commits_url": "https://api.github.com/gists/ecb0fdee1e1997bc0d9fc2c40df96a79/commits", - "id": "ecb0fdee1e1997bc0d9fc2c40df96a79", - "node_id": "MDQ6R2lzdGVjYjBmZGVlMWUxOTk3YmMwZDlmYzJjNDBkZjk2YTc5", - "git_pull_url": "https://gist.github.com/ecb0fdee1e1997bc0d9fc2c40df96a79.git", - "git_push_url": "https://gist.github.com/ecb0fdee1e1997bc0d9fc2c40df96a79.git", - "html_url": "https://gist.github.com/ecb0fdee1e1997bc0d9fc2c40df96a79", - "files": { - "LucasTest.java": { - "filename": "LucasTest.java", - "type": "text/plain", - "language": "Java", - "raw_url": "https://gist.githubusercontent.com/hkurokawa/ecb0fdee1e1997bc0d9fc2c40df96a79/raw/023f36c1b12f59fbbf9e93cd4a7f84497661175b/LucasTest.java", - "size": 614 - } - }, - "public": true, - "created_at": "2019-01-18T10:48:49Z", - "updated_at": "2019-01-18T10:48:49Z", - "description": "LucasTest", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/ecb0fdee1e1997bc0d9fc2c40df96a79/comments", - "owner": { - "login": "hkurokawa", - "id": 6446183, - "node_id": "MDQ6VXNlcjY0NDYxODM=", - "avatar_url": "https://avatars0.githubusercontent.com/u/6446183?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/hkurokawa", - "html_url": "https://github.com/hkurokawa", - "followers_url": "https://api.github.com/users/hkurokawa/followers", - "following_url": "https://api.github.com/users/hkurokawa/following{/other_user}", - "gists_url": "https://api.github.com/users/hkurokawa/gists{/gist_id}", - "starred_url": "https://api.github.com/users/hkurokawa/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/hkurokawa/subscriptions", - "organizations_url": "https://api.github.com/users/hkurokawa/orgs", - "repos_url": "https://api.github.com/users/hkurokawa/repos", - "events_url": "https://api.github.com/users/hkurokawa/events{/privacy}", - "received_events_url": "https://api.github.com/users/hkurokawa/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/1c2dceb0b4afd1be0407f225b26722cd", - "forks_url": "https://api.github.com/gists/1c2dceb0b4afd1be0407f225b26722cd/forks", - "commits_url": "https://api.github.com/gists/1c2dceb0b4afd1be0407f225b26722cd/commits", - "id": "1c2dceb0b4afd1be0407f225b26722cd", - "node_id": "MDQ6R2lzdDFjMmRjZWIwYjRhZmQxYmUwNDA3ZjIyNWIyNjcyMmNk", - "git_pull_url": "https://gist.github.com/1c2dceb0b4afd1be0407f225b26722cd.git", - "git_push_url": "https://gist.github.com/1c2dceb0b4afd1be0407f225b26722cd.git", - "html_url": "https://gist.github.com/1c2dceb0b4afd1be0407f225b26722cd", - "files": { - "interview-is-web.md": { - "filename": "interview-is-web.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/abeldotam/1c2dceb0b4afd1be0407f225b26722cd/raw/43ac601c21f37828aec3edfadc79a87e358c54f4/interview-is-web.md", - "size": 7444 - } - }, - "public": true, - "created_at": "2019-01-18T10:48:47Z", - "updated_at": "2019-01-18T10:48:47Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/1c2dceb0b4afd1be0407f225b26722cd/comments", - "owner": { - "login": "abeldotam", - "id": 5216201, - "node_id": "MDQ6VXNlcjUyMTYyMDE=", - "avatar_url": "https://avatars1.githubusercontent.com/u/5216201?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/abeldotam", - "html_url": "https://github.com/abeldotam", - "followers_url": "https://api.github.com/users/abeldotam/followers", - "following_url": "https://api.github.com/users/abeldotam/following{/other_user}", - "gists_url": "https://api.github.com/users/abeldotam/gists{/gist_id}", - "starred_url": "https://api.github.com/users/abeldotam/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/abeldotam/subscriptions", - "organizations_url": "https://api.github.com/users/abeldotam/orgs", - "repos_url": "https://api.github.com/users/abeldotam/repos", - "events_url": "https://api.github.com/users/abeldotam/events{/privacy}", - "received_events_url": "https://api.github.com/users/abeldotam/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/8bb6e9c2a81f348a06218420e3b6094a", - "forks_url": "https://api.github.com/gists/8bb6e9c2a81f348a06218420e3b6094a/forks", - "commits_url": "https://api.github.com/gists/8bb6e9c2a81f348a06218420e3b6094a/commits", - "id": "8bb6e9c2a81f348a06218420e3b6094a", - "node_id": "MDQ6R2lzdDhiYjZlOWMyYTgxZjM0OGEwNjIxODQyMGUzYjYwOTRh", - "git_pull_url": "https://gist.github.com/8bb6e9c2a81f348a06218420e3b6094a.git", - "git_push_url": "https://gist.github.com/8bb6e9c2a81f348a06218420e3b6094a.git", - "html_url": "https://gist.github.com/8bb6e9c2a81f348a06218420e3b6094a", - "files": { - "function.go": { - "filename": "function.go", - "type": "text/plain", - "language": "Go", - "raw_url": "https://gist.githubusercontent.com/didil/8bb6e9c2a81f348a06218420e3b6094a/raw/05571402da43c6574f83e7199604707babc6e6f0/function.go", - "size": 2355 - } - }, - "public": true, - "created_at": "2019-01-18T10:48:29Z", - "updated_at": "2019-01-18T10:48:29Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/8bb6e9c2a81f348a06218420e3b6094a/comments", - "owner": { - "login": "didil", - "id": 1284255, - "node_id": "MDQ6VXNlcjEyODQyNTU=", - "avatar_url": "https://avatars2.githubusercontent.com/u/1284255?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/didil", - "html_url": "https://github.com/didil", - "followers_url": "https://api.github.com/users/didil/followers", - "following_url": "https://api.github.com/users/didil/following{/other_user}", - "gists_url": "https://api.github.com/users/didil/gists{/gist_id}", - "starred_url": "https://api.github.com/users/didil/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/didil/subscriptions", - "organizations_url": "https://api.github.com/users/didil/orgs", - "repos_url": "https://api.github.com/users/didil/repos", - "events_url": "https://api.github.com/users/didil/events{/privacy}", - "received_events_url": "https://api.github.com/users/didil/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/e100a0303abae200089ff4fde19b8a31", - "forks_url": "https://api.github.com/gists/e100a0303abae200089ff4fde19b8a31/forks", - "commits_url": "https://api.github.com/gists/e100a0303abae200089ff4fde19b8a31/commits", - "id": "e100a0303abae200089ff4fde19b8a31", - "node_id": "MDQ6R2lzdGUxMDBhMDMwM2FiYWUyMDAwODlmZjRmZGUxOWI4YTMx", - "git_pull_url": "https://gist.github.com/e100a0303abae200089ff4fde19b8a31.git", - "git_push_url": "https://gist.github.com/e100a0303abae200089ff4fde19b8a31.git", - "html_url": "https://gist.github.com/e100a0303abae200089ff4fde19b8a31", - "files": { - "README.md": { - "filename": "README.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/Nathan2-D/e100a0303abae200089ff4fde19b8a31/raw/745a320116da084be7b5f1ae3fc429ad03d14396/README.md", - "size": 169 - }, - "css.css": { - "filename": "css.css", - "type": "text/css", - "language": "CSS", - "raw_url": "https://gist.githubusercontent.com/Nathan2-D/e100a0303abae200089ff4fde19b8a31/raw/3b1a123200728b0d7301e3af7eb2048981c09584/css.css", - "size": 1419 - }, - "function.js": { - "filename": "function.js", - "type": "application/javascript", - "language": "JavaScript", - "raw_url": "https://gist.githubusercontent.com/Nathan2-D/e100a0303abae200089ff4fde19b8a31/raw/1e280bf1bdc543a4087ff2b9ba5ac574dd8c1912/function.js", - "size": 2274 - }, - "html.html": { - "filename": "html.html", - "type": "text/html", - "language": "HTML", - "raw_url": "https://gist.githubusercontent.com/Nathan2-D/e100a0303abae200089ff4fde19b8a31/raw/c110e747fa1ec417d6f169210a1001a6e84931d4/html.html", - "size": 237 - } - }, - "public": true, - "created_at": "2019-01-18T10:48:09Z", - "updated_at": "2019-01-18T10:49:23Z", - "description": "SNEK.js - scrolll based animation snippet", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/e100a0303abae200089ff4fde19b8a31/comments", - "owner": { - "login": "Nathan2-D", - "id": 13834324, - "node_id": "MDQ6VXNlcjEzODM0MzI0", - "avatar_url": "https://avatars3.githubusercontent.com/u/13834324?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/Nathan2-D", - "html_url": "https://github.com/Nathan2-D", - "followers_url": "https://api.github.com/users/Nathan2-D/followers", - "following_url": "https://api.github.com/users/Nathan2-D/following{/other_user}", - "gists_url": "https://api.github.com/users/Nathan2-D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/Nathan2-D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/Nathan2-D/subscriptions", - "organizations_url": "https://api.github.com/users/Nathan2-D/orgs", - "repos_url": "https://api.github.com/users/Nathan2-D/repos", - "events_url": "https://api.github.com/users/Nathan2-D/events{/privacy}", - "received_events_url": "https://api.github.com/users/Nathan2-D/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/1bd5ad023f283f91735b7d200e338ea4", - "forks_url": "https://api.github.com/gists/1bd5ad023f283f91735b7d200e338ea4/forks", - "commits_url": "https://api.github.com/gists/1bd5ad023f283f91735b7d200e338ea4/commits", - "id": "1bd5ad023f283f91735b7d200e338ea4", - "node_id": "MDQ6R2lzdDFiZDVhZDAyM2YyODNmOTE3MzViN2QyMDBlMzM4ZWE0", - "git_pull_url": "https://gist.github.com/1bd5ad023f283f91735b7d200e338ea4.git", - "git_push_url": "https://gist.github.com/1bd5ad023f283f91735b7d200e338ea4.git", - "html_url": "https://gist.github.com/1bd5ad023f283f91735b7d200e338ea4", - "files": { - "latest_pr.sh": { - "filename": "latest_pr.sh", - "type": "application/x-sh", - "language": "Shell", - "raw_url": "https://gist.githubusercontent.com/rootux/1bd5ad023f283f91735b7d200e338ea4/raw/3d06f207d3f9a39ceca82f2777a6f5a297eb0ba7/latest_pr.sh", - "size": 496 - } - }, - "public": true, - "created_at": "2019-01-18T10:48:08Z", - "updated_at": "2019-01-18T10:48:08Z", - "description": "Getting latest closed pr commit messages", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/1bd5ad023f283f91735b7d200e338ea4/comments", - "owner": { - "login": "rootux", - "id": 1032526, - "node_id": "MDQ6VXNlcjEwMzI1MjY=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1032526?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/rootux", - "html_url": "https://github.com/rootux", - "followers_url": "https://api.github.com/users/rootux/followers", - "following_url": "https://api.github.com/users/rootux/following{/other_user}", - "gists_url": "https://api.github.com/users/rootux/gists{/gist_id}", - "starred_url": "https://api.github.com/users/rootux/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/rootux/subscriptions", - "organizations_url": "https://api.github.com/users/rootux/orgs", - "repos_url": "https://api.github.com/users/rootux/repos", - "events_url": "https://api.github.com/users/rootux/events{/privacy}", - "received_events_url": "https://api.github.com/users/rootux/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/de7f3717934fb8c34e921fd16d8fa4d6", - "forks_url": "https://api.github.com/gists/de7f3717934fb8c34e921fd16d8fa4d6/forks", - "commits_url": "https://api.github.com/gists/de7f3717934fb8c34e921fd16d8fa4d6/commits", - "id": "de7f3717934fb8c34e921fd16d8fa4d6", - "node_id": "MDQ6R2lzdGRlN2YzNzE3OTM0ZmI4YzM0ZTkyMWZkMTZkOGZhNGQ2", - "git_pull_url": "https://gist.github.com/de7f3717934fb8c34e921fd16d8fa4d6.git", - "git_push_url": "https://gist.github.com/de7f3717934fb8c34e921fd16d8fa4d6.git", - "html_url": "https://gist.github.com/de7f3717934fb8c34e921fd16d8fa4d6", - "files": { - "lambda.tf": { - "filename": "lambda.tf", - "type": "text/plain", - "language": "HCL", - "raw_url": "https://gist.githubusercontent.com/KotMeow/de7f3717934fb8c34e921fd16d8fa4d6/raw/53afec7cd75a850f1605d6123a572a784d210f4b/lambda.tf", - "size": 743 - } - }, - "public": true, - "created_at": "2019-01-18T10:47:39Z", - "updated_at": "2019-01-18T10:47:39Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/de7f3717934fb8c34e921fd16d8fa4d6/comments", - "owner": { - "login": "KotMeow", - "id": 10243131, - "node_id": "MDQ6VXNlcjEwMjQzMTMx", - "avatar_url": "https://avatars3.githubusercontent.com/u/10243131?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/KotMeow", - "html_url": "https://github.com/KotMeow", - "followers_url": "https://api.github.com/users/KotMeow/followers", - "following_url": "https://api.github.com/users/KotMeow/following{/other_user}", - "gists_url": "https://api.github.com/users/KotMeow/gists{/gist_id}", - "starred_url": "https://api.github.com/users/KotMeow/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/KotMeow/subscriptions", - "organizations_url": "https://api.github.com/users/KotMeow/orgs", - "repos_url": "https://api.github.com/users/KotMeow/repos", - "events_url": "https://api.github.com/users/KotMeow/events{/privacy}", - "received_events_url": "https://api.github.com/users/KotMeow/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/4a5d6cf4fc1aa78961a861c96773444c", - "forks_url": "https://api.github.com/gists/4a5d6cf4fc1aa78961a861c96773444c/forks", - "commits_url": "https://api.github.com/gists/4a5d6cf4fc1aa78961a861c96773444c/commits", - "id": "4a5d6cf4fc1aa78961a861c96773444c", - "node_id": "MDQ6R2lzdDRhNWQ2Y2Y0ZmMxYWE3ODk2MWE4NjFjOTY3NzM0NDRj", - "git_pull_url": "https://gist.github.com/4a5d6cf4fc1aa78961a861c96773444c.git", - "git_push_url": "https://gist.github.com/4a5d6cf4fc1aa78961a861c96773444c.git", - "html_url": "https://gist.github.com/4a5d6cf4fc1aa78961a861c96773444c", - "files": { - "FilesSnapshot.xml": { - "filename": "FilesSnapshot.xml", - "type": "application/xml", - "language": "XML", - "raw_url": "https://gist.githubusercontent.com/choco-bot/4a5d6cf4fc1aa78961a861c96773444c/raw/e4baa82e99c9e9022f1ad68ebb95dc779a18e060/FilesSnapshot.xml", - "size": 101697 - }, - "Install.txt": { - "filename": "Install.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/4a5d6cf4fc1aa78961a861c96773444c/raw/82e4accd306be8601e8013cc36abe9eabcff8c7a/Install.txt", - "size": 223672 - }, - "Uninstall.txt": { - "filename": "Uninstall.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/4a5d6cf4fc1aa78961a861c96773444c/raw/287311b44fd2f1d3bd014c995d5bc02dd85b5982/Uninstall.txt", - "size": 532820 - }, - "_Summary.md": { - "filename": "_Summary.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/choco-bot/4a5d6cf4fc1aa78961a861c96773444c/raw/08a238632a6bade0f827c9904e2757ea65e684be/_Summary.md", - "size": 449 - } - }, - "public": true, - "created_at": "2019-01-18T10:47:11Z", - "updated_at": "2019-01-18T10:47:11Z", - "description": "antlrworks2 v2.1.0 - Passed - Package Tests Results", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/4a5d6cf4fc1aa78961a861c96773444c/comments", - "owner": { - "login": "choco-bot", - "id": 6270979, - "node_id": "MDQ6VXNlcjYyNzA5Nzk=", - "avatar_url": "https://avatars2.githubusercontent.com/u/6270979?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/choco-bot", - "html_url": "https://github.com/choco-bot", - "followers_url": "https://api.github.com/users/choco-bot/followers", - "following_url": "https://api.github.com/users/choco-bot/following{/other_user}", - "gists_url": "https://api.github.com/users/choco-bot/gists{/gist_id}", - "starred_url": "https://api.github.com/users/choco-bot/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/choco-bot/subscriptions", - "organizations_url": "https://api.github.com/users/choco-bot/orgs", - "repos_url": "https://api.github.com/users/choco-bot/repos", - "events_url": "https://api.github.com/users/choco-bot/events{/privacy}", - "received_events_url": "https://api.github.com/users/choco-bot/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/41645dcb832947ff4cf52ffe69d67b47", - "forks_url": "https://api.github.com/gists/41645dcb832947ff4cf52ffe69d67b47/forks", - "commits_url": "https://api.github.com/gists/41645dcb832947ff4cf52ffe69d67b47/commits", - "id": "41645dcb832947ff4cf52ffe69d67b47", - "node_id": "MDQ6R2lzdDQxNjQ1ZGNiODMyOTQ3ZmY0Y2Y1MmZmZTY5ZDY3YjQ3", - "git_pull_url": "https://gist.github.com/41645dcb832947ff4cf52ffe69d67b47.git", - "git_push_url": "https://gist.github.com/41645dcb832947ff4cf52ffe69d67b47.git", - "html_url": "https://gist.github.com/41645dcb832947ff4cf52ffe69d67b47", - "files": { - "bitmapCutAndFill.java": { - "filename": "bitmapCutAndFill.java", - "type": "text/plain", - "language": "Java", - "raw_url": "https://gist.githubusercontent.com/luoyesiqiu/41645dcb832947ff4cf52ffe69d67b47/raw/c37bb5702542e4798c36905768a5ae736ee34100/bitmapCutAndFill.java", - "size": 1774 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:52Z", - "updated_at": "2019-01-18T10:47:57Z", - "description": "Android图片裁剪和填充", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/41645dcb832947ff4cf52ffe69d67b47/comments", - "owner": { - "login": "luoyesiqiu", - "id": 9801756, - "node_id": "MDQ6VXNlcjk4MDE3NTY=", - "avatar_url": "https://avatars1.githubusercontent.com/u/9801756?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/luoyesiqiu", - "html_url": "https://github.com/luoyesiqiu", - "followers_url": "https://api.github.com/users/luoyesiqiu/followers", - "following_url": "https://api.github.com/users/luoyesiqiu/following{/other_user}", - "gists_url": "https://api.github.com/users/luoyesiqiu/gists{/gist_id}", - "starred_url": "https://api.github.com/users/luoyesiqiu/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/luoyesiqiu/subscriptions", - "organizations_url": "https://api.github.com/users/luoyesiqiu/orgs", - "repos_url": "https://api.github.com/users/luoyesiqiu/repos", - "events_url": "https://api.github.com/users/luoyesiqiu/events{/privacy}", - "received_events_url": "https://api.github.com/users/luoyesiqiu/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/09bb259b5cb8df91335b64f3fecb0aec", - "forks_url": "https://api.github.com/gists/09bb259b5cb8df91335b64f3fecb0aec/forks", - "commits_url": "https://api.github.com/gists/09bb259b5cb8df91335b64f3fecb0aec/commits", - "id": "09bb259b5cb8df91335b64f3fecb0aec", - "node_id": "MDQ6R2lzdDA5YmIyNTliNWNiOGRmOTEzMzViNjRmM2ZlY2IwYWVj", - "git_pull_url": "https://gist.github.com/09bb259b5cb8df91335b64f3fecb0aec.git", - "git_push_url": "https://gist.github.com/09bb259b5cb8df91335b64f3fecb0aec.git", - "html_url": "https://gist.github.com/09bb259b5cb8df91335b64f3fecb0aec", - "files": { - "PowerShell Customization.md": { - "filename": "PowerShell Customization.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/alexanek/09bb259b5cb8df91335b64f3fecb0aec/raw/da4bf4f28663ae28cfba0590e6ea08059f6ef97f/PowerShell%20Customization.md", - "size": 16557 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:43Z", - "updated_at": "2019-01-18T10:46:43Z", - "description": "PowerShell, Cmder / ConEmu, Posh-Git, Oh-My-Posh, Powerline Customization", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/09bb259b5cb8df91335b64f3fecb0aec/comments", - "owner": { - "login": "alexanek", - "id": 389707, - "node_id": "MDQ6VXNlcjM4OTcwNw==", - "avatar_url": "https://avatars1.githubusercontent.com/u/389707?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/alexanek", - "html_url": "https://github.com/alexanek", - "followers_url": "https://api.github.com/users/alexanek/followers", - "following_url": "https://api.github.com/users/alexanek/following{/other_user}", - "gists_url": "https://api.github.com/users/alexanek/gists{/gist_id}", - "starred_url": "https://api.github.com/users/alexanek/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/alexanek/subscriptions", - "organizations_url": "https://api.github.com/users/alexanek/orgs", - "repos_url": "https://api.github.com/users/alexanek/repos", - "events_url": "https://api.github.com/users/alexanek/events{/privacy}", - "received_events_url": "https://api.github.com/users/alexanek/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/2f060add6b805ad1e0e1a252d37865a2", - "forks_url": "https://api.github.com/gists/2f060add6b805ad1e0e1a252d37865a2/forks", - "commits_url": "https://api.github.com/gists/2f060add6b805ad1e0e1a252d37865a2/commits", - "id": "2f060add6b805ad1e0e1a252d37865a2", - "node_id": "MDQ6R2lzdDJmMDYwYWRkNmI4MDVhZDFlMGUxYTI1MmQzNzg2NWEy", - "git_pull_url": "https://gist.github.com/2f060add6b805ad1e0e1a252d37865a2.git", - "git_push_url": "https://gist.github.com/2f060add6b805ad1e0e1a252d37865a2.git", - "html_url": "https://gist.github.com/2f060add6b805ad1e0e1a252d37865a2", - "files": { - "ApplicationViewModelFactory.kt": { - "filename": "ApplicationViewModelFactory.kt", - "type": "text/plain", - "language": "Kotlin", - "raw_url": "https://gist.githubusercontent.com/ashdavies/2f060add6b805ad1e0e1a252d37865a2/raw/41aa8f51bbdcbaef9227a305ebe8a03702aa935f/ApplicationViewModelFactory.kt", - "size": 540 - }, - "ViewModelKey.kt": { - "filename": "ViewModelKey.kt", - "type": "text/plain", - "language": "Kotlin", - "raw_url": "https://gist.githubusercontent.com/ashdavies/2f060add6b805ad1e0e1a252d37865a2/raw/03b9511521c2f8d9dcd4fc5eabde3a646f5e9838/ViewModelKey.kt", - "size": 91 - }, - "ViewModelModule.kt": { - "filename": "ViewModelModule.kt", - "type": "text/plain", - "language": "Kotlin", - "raw_url": "https://gist.githubusercontent.com/ashdavies/2f060add6b805ad1e0e1a252d37865a2/raw/1f96ca1736edb6f0ae183877f9fc873bb54f3ce7/ViewModelModule.kt", - "size": 122 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:41Z", - "updated_at": "2019-01-18T10:46:42Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/2f060add6b805ad1e0e1a252d37865a2/comments", - "owner": { - "login": "ashdavies", - "id": 1892070, - "node_id": "MDQ6VXNlcjE4OTIwNzA=", - "avatar_url": "https://avatars1.githubusercontent.com/u/1892070?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/ashdavies", - "html_url": "https://github.com/ashdavies", - "followers_url": "https://api.github.com/users/ashdavies/followers", - "following_url": "https://api.github.com/users/ashdavies/following{/other_user}", - "gists_url": "https://api.github.com/users/ashdavies/gists{/gist_id}", - "starred_url": "https://api.github.com/users/ashdavies/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/ashdavies/subscriptions", - "organizations_url": "https://api.github.com/users/ashdavies/orgs", - "repos_url": "https://api.github.com/users/ashdavies/repos", - "events_url": "https://api.github.com/users/ashdavies/events{/privacy}", - "received_events_url": "https://api.github.com/users/ashdavies/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/d5f93c438661656084bb686863ba576a", - "forks_url": "https://api.github.com/gists/d5f93c438661656084bb686863ba576a/forks", - "commits_url": "https://api.github.com/gists/d5f93c438661656084bb686863ba576a/commits", - "id": "d5f93c438661656084bb686863ba576a", - "node_id": "MDQ6R2lzdGQ1ZjkzYzQzODY2MTY1NjA4NGJiNjg2ODYzYmE1NzZh", - "git_pull_url": "https://gist.github.com/d5f93c438661656084bb686863ba576a.git", - "git_push_url": "https://gist.github.com/d5f93c438661656084bb686863ba576a.git", - "html_url": "https://gist.github.com/d5f93c438661656084bb686863ba576a", - "files": { - "gistfile1.txt": { - "filename": "gistfile1.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/phisad/d5f93c438661656084bb686863ba576a/raw/004354c8480f19fd073f2f12898b04a30d2df96c/gistfile1.txt", - "size": 103 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:39Z", - "updated_at": "2019-01-18T10:46:40Z", - "description": "Tensorflow disable the warning AVX/FMA not enabled (because the standard version is supposed to support as many CPU as possible)", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/d5f93c438661656084bb686863ba576a/comments", - "owner": { - "login": "phisad", - "id": 6343036, - "node_id": "MDQ6VXNlcjYzNDMwMzY=", - "avatar_url": "https://avatars2.githubusercontent.com/u/6343036?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/phisad", - "html_url": "https://github.com/phisad", - "followers_url": "https://api.github.com/users/phisad/followers", - "following_url": "https://api.github.com/users/phisad/following{/other_user}", - "gists_url": "https://api.github.com/users/phisad/gists{/gist_id}", - "starred_url": "https://api.github.com/users/phisad/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/phisad/subscriptions", - "organizations_url": "https://api.github.com/users/phisad/orgs", - "repos_url": "https://api.github.com/users/phisad/repos", - "events_url": "https://api.github.com/users/phisad/events{/privacy}", - "received_events_url": "https://api.github.com/users/phisad/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/ed4b9bf78d80b792918df483d8a83216", - "forks_url": "https://api.github.com/gists/ed4b9bf78d80b792918df483d8a83216/forks", - "commits_url": "https://api.github.com/gists/ed4b9bf78d80b792918df483d8a83216/commits", - "id": "ed4b9bf78d80b792918df483d8a83216", - "node_id": "MDQ6R2lzdGVkNGI5YmY3OGQ4MGI3OTI5MThkZjQ4M2Q4YTgzMjE2", - "git_pull_url": "https://gist.github.com/ed4b9bf78d80b792918df483d8a83216.git", - "git_push_url": "https://gist.github.com/ed4b9bf78d80b792918df483d8a83216.git", - "html_url": "https://gist.github.com/ed4b9bf78d80b792918df483d8a83216", - "files": { - "article-1e1-epilogue": { - "filename": "article-1e1-epilogue", - "type": "text/plain", - "language": null, - "raw_url": "https://gist.githubusercontent.com/v-kolesov/ed4b9bf78d80b792918df483d8a83216/raw/df7daf38820a87616f2d830e824b6ba65af14b6d/article-1e1-epilogue", - "size": 86 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:31Z", - "updated_at": "2019-01-18T10:46:31Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/ed4b9bf78d80b792918df483d8a83216/comments", - "owner": { - "login": "v-kolesov", - "id": 1316359, - "node_id": "MDQ6VXNlcjEzMTYzNTk=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1316359?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/v-kolesov", - "html_url": "https://github.com/v-kolesov", - "followers_url": "https://api.github.com/users/v-kolesov/followers", - "following_url": "https://api.github.com/users/v-kolesov/following{/other_user}", - "gists_url": "https://api.github.com/users/v-kolesov/gists{/gist_id}", - "starred_url": "https://api.github.com/users/v-kolesov/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/v-kolesov/subscriptions", - "organizations_url": "https://api.github.com/users/v-kolesov/orgs", - "repos_url": "https://api.github.com/users/v-kolesov/repos", - "events_url": "https://api.github.com/users/v-kolesov/events{/privacy}", - "received_events_url": "https://api.github.com/users/v-kolesov/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/02a1b692a390d5124959f38104ee3254", - "forks_url": "https://api.github.com/gists/02a1b692a390d5124959f38104ee3254/forks", - "commits_url": "https://api.github.com/gists/02a1b692a390d5124959f38104ee3254/commits", - "id": "02a1b692a390d5124959f38104ee3254", - "node_id": "MDQ6R2lzdDAyYTFiNjkyYTM5MGQ1MTI0OTU5ZjM4MTA0ZWUzMjU0", - "git_pull_url": "https://gist.github.com/02a1b692a390d5124959f38104ee3254.git", - "git_push_url": "https://gist.github.com/02a1b692a390d5124959f38104ee3254.git", - "html_url": "https://gist.github.com/02a1b692a390d5124959f38104ee3254", - "files": { - "gistfile1.txt": { - "filename": "gistfile1.txt", - "type": "text/plain", - "language": null, - "raw_url": "https://gist.githubusercontent.com/ozgurtavtay/02a1b692a390d5124959f38104ee3254/raw/e69de29bb2d1d6434b8b29ae775ad8c2e48c5391/gistfile1.txt", - "size": 0 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:30Z", - "updated_at": "2019-01-18T10:49:19Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/02a1b692a390d5124959f38104ee3254/comments", - "owner": { - "login": "ozgurtavtay", - "id": 46104634, - "node_id": "MDQ6VXNlcjQ2MTA0NjM0", - "avatar_url": "https://avatars0.githubusercontent.com/u/46104634?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/ozgurtavtay", - "html_url": "https://github.com/ozgurtavtay", - "followers_url": "https://api.github.com/users/ozgurtavtay/followers", - "following_url": "https://api.github.com/users/ozgurtavtay/following{/other_user}", - "gists_url": "https://api.github.com/users/ozgurtavtay/gists{/gist_id}", - "starred_url": "https://api.github.com/users/ozgurtavtay/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/ozgurtavtay/subscriptions", - "organizations_url": "https://api.github.com/users/ozgurtavtay/orgs", - "repos_url": "https://api.github.com/users/ozgurtavtay/repos", - "events_url": "https://api.github.com/users/ozgurtavtay/events{/privacy}", - "received_events_url": "https://api.github.com/users/ozgurtavtay/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/33f55d7b9b205ac9395d1ea9b090cea0", - "forks_url": "https://api.github.com/gists/33f55d7b9b205ac9395d1ea9b090cea0/forks", - "commits_url": "https://api.github.com/gists/33f55d7b9b205ac9395d1ea9b090cea0/commits", - "id": "33f55d7b9b205ac9395d1ea9b090cea0", - "node_id": "MDQ6R2lzdDMzZjU1ZDdiOWIyMDVhYzkzOTVkMWVhOWIwOTBjZWEw", - "git_pull_url": "https://gist.github.com/33f55d7b9b205ac9395d1ea9b090cea0.git", - "git_push_url": "https://gist.github.com/33f55d7b9b205ac9395d1ea9b090cea0.git", - "html_url": "https://gist.github.com/33f55d7b9b205ac9395d1ea9b090cea0", - "files": { - "frontend-developer-jds.html": { - "filename": "frontend-developer-jds.html", - "type": "text/html", - "language": "HTML", - "raw_url": "https://gist.githubusercontent.com/dhanyn10/33f55d7b9b205ac9395d1ea9b090cea0/raw/076305b0f24bb50a1353f164e31bc207f5180b5d/frontend-developer-jds.html", - "size": 880 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:17Z", - "updated_at": "2019-01-18T10:46:17Z", - "description": "test frontend developer jds css 2", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/33f55d7b9b205ac9395d1ea9b090cea0/comments", - "owner": { - "login": "dhanyn10", - "id": 11478316, - "node_id": "MDQ6VXNlcjExNDc4MzE2", - "avatar_url": "https://avatars1.githubusercontent.com/u/11478316?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/dhanyn10", - "html_url": "https://github.com/dhanyn10", - "followers_url": "https://api.github.com/users/dhanyn10/followers", - "following_url": "https://api.github.com/users/dhanyn10/following{/other_user}", - "gists_url": "https://api.github.com/users/dhanyn10/gists{/gist_id}", - "starred_url": "https://api.github.com/users/dhanyn10/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/dhanyn10/subscriptions", - "organizations_url": "https://api.github.com/users/dhanyn10/orgs", - "repos_url": "https://api.github.com/users/dhanyn10/repos", - "events_url": "https://api.github.com/users/dhanyn10/events{/privacy}", - "received_events_url": "https://api.github.com/users/dhanyn10/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/ed224019d4fd6f6480492777f8f72480", - "forks_url": "https://api.github.com/gists/ed224019d4fd6f6480492777f8f72480/forks", - "commits_url": "https://api.github.com/gists/ed224019d4fd6f6480492777f8f72480/commits", - "id": "ed224019d4fd6f6480492777f8f72480", - "node_id": "MDQ6R2lzdGVkMjI0MDE5ZDRmZDZmNjQ4MDQ5Mjc3N2Y4ZjcyNDgw", - "git_pull_url": "https://gist.github.com/ed224019d4fd6f6480492777f8f72480.git", - "git_push_url": "https://gist.github.com/ed224019d4fd6f6480492777f8f72480.git", - "html_url": "https://gist.github.com/ed224019d4fd6f6480492777f8f72480", - "files": { - "ONVAULT.sh": { - "filename": "ONVAULT.sh", - "type": "application/x-sh", - "language": "Shell", - "raw_url": "https://gist.githubusercontent.com/kaiix/ed224019d4fd6f6480492777f8f72480/raw/d9ebe67fabd2588b4edf1b6427778d0877e94389/ONVAULT.sh", - "size": 376 - } - }, - "public": true, - "created_at": "2019-01-18T10:46:02Z", - "updated_at": "2019-01-18T10:46:02Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/ed224019d4fd6f6480492777f8f72480/comments", - "owner": { - "login": "kaiix", - "id": 172202, - "node_id": "MDQ6VXNlcjE3MjIwMg==", - "avatar_url": "https://avatars0.githubusercontent.com/u/172202?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kaiix", - "html_url": "https://github.com/kaiix", - "followers_url": "https://api.github.com/users/kaiix/followers", - "following_url": "https://api.github.com/users/kaiix/following{/other_user}", - "gists_url": "https://api.github.com/users/kaiix/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kaiix/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kaiix/subscriptions", - "organizations_url": "https://api.github.com/users/kaiix/orgs", - "repos_url": "https://api.github.com/users/kaiix/repos", - "events_url": "https://api.github.com/users/kaiix/events{/privacy}", - "received_events_url": "https://api.github.com/users/kaiix/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/b605e74286b7f8ca016b163f7ec10f67", - "forks_url": "https://api.github.com/gists/b605e74286b7f8ca016b163f7ec10f67/forks", - "commits_url": "https://api.github.com/gists/b605e74286b7f8ca016b163f7ec10f67/commits", - "id": "b605e74286b7f8ca016b163f7ec10f67", - "node_id": "MDQ6R2lzdGI2MDVlNzQyODZiN2Y4Y2EwMTZiMTYzZjdlYzEwZjY3", - "git_pull_url": "https://gist.github.com/b605e74286b7f8ca016b163f7ec10f67.git", - "git_push_url": "https://gist.github.com/b605e74286b7f8ca016b163f7ec10f67.git", - "html_url": "https://gist.github.com/b605e74286b7f8ca016b163f7ec10f67", - "files": { - "1.js": { - "filename": "1.js", - "type": "application/javascript", - "language": "JavaScript", - "raw_url": "https://gist.githubusercontent.com/mihalskiy/b605e74286b7f8ca016b163f7ec10f67/raw/12a4aca39a15b1e35469bbc63889c1fdf1b3e12a/1.js", - "size": 1255 - } - }, - "public": true, - "created_at": "2019-01-18T10:45:32Z", - "updated_at": "2019-01-18T10:48:40Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/b605e74286b7f8ca016b163f7ec10f67/comments", - "owner": { - "login": "mihalskiy", - "id": 29286972, - "node_id": "MDQ6VXNlcjI5Mjg2OTcy", - "avatar_url": "https://avatars3.githubusercontent.com/u/29286972?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/mihalskiy", - "html_url": "https://github.com/mihalskiy", - "followers_url": "https://api.github.com/users/mihalskiy/followers", - "following_url": "https://api.github.com/users/mihalskiy/following{/other_user}", - "gists_url": "https://api.github.com/users/mihalskiy/gists{/gist_id}", - "starred_url": "https://api.github.com/users/mihalskiy/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/mihalskiy/subscriptions", - "organizations_url": "https://api.github.com/users/mihalskiy/orgs", - "repos_url": "https://api.github.com/users/mihalskiy/repos", - "events_url": "https://api.github.com/users/mihalskiy/events{/privacy}", - "received_events_url": "https://api.github.com/users/mihalskiy/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/03bf022427c288129db77d9c295f458c", - "forks_url": "https://api.github.com/gists/03bf022427c288129db77d9c295f458c/forks", - "commits_url": "https://api.github.com/gists/03bf022427c288129db77d9c295f458c/commits", - "id": "03bf022427c288129db77d9c295f458c", - "node_id": "MDQ6R2lzdDAzYmYwMjI0MjdjMjg4MTI5ZGI3N2Q5YzI5NWY0NThj", - "git_pull_url": "https://gist.github.com/03bf022427c288129db77d9c295f458c.git", - "git_push_url": "https://gist.github.com/03bf022427c288129db77d9c295f458c.git", - "html_url": "https://gist.github.com/03bf022427c288129db77d9c295f458c", - "files": { - "git-mig.sh": { - "filename": "git-mig.sh", - "type": "application/x-sh", - "language": "Shell", - "raw_url": "https://gist.githubusercontent.com/fabiojose/03bf022427c288129db77d9c295f458c/raw/6a08e52be4c84bac902f1cc95dd3462d3030f6bd/git-mig.sh", - "size": 155 - } - }, - "public": true, - "created_at": "2019-01-18T10:45:31Z", - "updated_at": "2019-01-18T10:45:31Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/03bf022427c288129db77d9c295f458c/comments", - "owner": { - "login": "fabiojose", - "id": 1252022, - "node_id": "MDQ6VXNlcjEyNTIwMjI=", - "avatar_url": "https://avatars3.githubusercontent.com/u/1252022?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/fabiojose", - "html_url": "https://github.com/fabiojose", - "followers_url": "https://api.github.com/users/fabiojose/followers", - "following_url": "https://api.github.com/users/fabiojose/following{/other_user}", - "gists_url": "https://api.github.com/users/fabiojose/gists{/gist_id}", - "starred_url": "https://api.github.com/users/fabiojose/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/fabiojose/subscriptions", - "organizations_url": "https://api.github.com/users/fabiojose/orgs", - "repos_url": "https://api.github.com/users/fabiojose/repos", - "events_url": "https://api.github.com/users/fabiojose/events{/privacy}", - "received_events_url": "https://api.github.com/users/fabiojose/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/24219b1985d18833c59f00d0727b911f", - "forks_url": "https://api.github.com/gists/24219b1985d18833c59f00d0727b911f/forks", - "commits_url": "https://api.github.com/gists/24219b1985d18833c59f00d0727b911f/commits", - "id": "24219b1985d18833c59f00d0727b911f", - "node_id": "MDQ6R2lzdDI0MjE5YjE5ODVkMTg4MzNjNTlmMDBkMDcyN2I5MTFm", - "git_pull_url": "https://gist.github.com/24219b1985d18833c59f00d0727b911f.git", - "git_push_url": "https://gist.github.com/24219b1985d18833c59f00d0727b911f.git", - "html_url": "https://gist.github.com/24219b1985d18833c59f00d0727b911f", - "files": { - "UPEntryBuilder.java": { - "filename": "UPEntryBuilder.java", - "type": "text/plain", - "language": "Java", - "raw_url": "https://gist.githubusercontent.com/eddturner/24219b1985d18833c59f00d0727b911f/raw/7f0c55ae001b441b0a0a8a9e9ed40db61cf2d1cb/UPEntryBuilder.java", - "size": 2996 - } - }, - "public": true, - "created_at": "2019-01-18T10:45:27Z", - "updated_at": "2019-01-18T10:45:27Z", - "description": "Step Builder without need for static method to create initial builder", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/24219b1985d18833c59f00d0727b911f/comments", - "owner": { - "login": "eddturner", - "id": 7251381, - "node_id": "MDQ6VXNlcjcyNTEzODE=", - "avatar_url": "https://avatars0.githubusercontent.com/u/7251381?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/eddturner", - "html_url": "https://github.com/eddturner", - "followers_url": "https://api.github.com/users/eddturner/followers", - "following_url": "https://api.github.com/users/eddturner/following{/other_user}", - "gists_url": "https://api.github.com/users/eddturner/gists{/gist_id}", - "starred_url": "https://api.github.com/users/eddturner/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/eddturner/subscriptions", - "organizations_url": "https://api.github.com/users/eddturner/orgs", - "repos_url": "https://api.github.com/users/eddturner/repos", - "events_url": "https://api.github.com/users/eddturner/events{/privacy}", - "received_events_url": "https://api.github.com/users/eddturner/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/f1361f1e9264c7aa08bea76597960007", - "forks_url": "https://api.github.com/gists/f1361f1e9264c7aa08bea76597960007/forks", - "commits_url": "https://api.github.com/gists/f1361f1e9264c7aa08bea76597960007/commits", - "id": "f1361f1e9264c7aa08bea76597960007", - "node_id": "MDQ6R2lzdGYxMzYxZjFlOTI2NGM3YWEwOGJlYTc2NTk3OTYwMDA3", - "git_pull_url": "https://gist.github.com/f1361f1e9264c7aa08bea76597960007.git", - "git_push_url": "https://gist.github.com/f1361f1e9264c7aa08bea76597960007.git", - "html_url": "https://gist.github.com/f1361f1e9264c7aa08bea76597960007", - "files": { - "deploy.rb": { - "filename": "deploy.rb", - "type": "application/x-ruby", - "language": "Ruby", - "raw_url": "https://gist.githubusercontent.com/puncoz/f1361f1e9264c7aa08bea76597960007/raw/01cd618d963cfb1377b7ffe74471b6e3291d0718/deploy.rb", - "size": 1274 - } - }, - "public": true, - "created_at": "2019-01-18T10:44:49Z", - "updated_at": "2019-01-18T10:44:49Z", - "description": "Capistrano task for creating a change log file", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/f1361f1e9264c7aa08bea76597960007/comments", - "owner": { - "login": "puncoz", - "id": 7767424, - "node_id": "MDQ6VXNlcjc3Njc0MjQ=", - "avatar_url": "https://avatars2.githubusercontent.com/u/7767424?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/puncoz", - "html_url": "https://github.com/puncoz", - "followers_url": "https://api.github.com/users/puncoz/followers", - "following_url": "https://api.github.com/users/puncoz/following{/other_user}", - "gists_url": "https://api.github.com/users/puncoz/gists{/gist_id}", - "starred_url": "https://api.github.com/users/puncoz/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/puncoz/subscriptions", - "organizations_url": "https://api.github.com/users/puncoz/orgs", - "repos_url": "https://api.github.com/users/puncoz/repos", - "events_url": "https://api.github.com/users/puncoz/events{/privacy}", - "received_events_url": "https://api.github.com/users/puncoz/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/0eab4b071cbd8ea01b5020e6d4186e5d", - "forks_url": "https://api.github.com/gists/0eab4b071cbd8ea01b5020e6d4186e5d/forks", - "commits_url": "https://api.github.com/gists/0eab4b071cbd8ea01b5020e6d4186e5d/commits", - "id": "0eab4b071cbd8ea01b5020e6d4186e5d", - "node_id": "MDQ6R2lzdDBlYWI0YjA3MWNiZDhlYTAxYjUwMjBlNmQ0MTg2ZTVk", - "git_pull_url": "https://gist.github.com/0eab4b071cbd8ea01b5020e6d4186e5d.git", - "git_push_url": "https://gist.github.com/0eab4b071cbd8ea01b5020e6d4186e5d.git", - "html_url": "https://gist.github.com/0eab4b071cbd8ea01b5020e6d4186e5d", - "files": { - ".tmux.conf": { - "filename": ".tmux.conf", - "type": "text/plain", - "language": null, - "raw_url": "https://gist.githubusercontent.com/sean1188/0eab4b071cbd8ea01b5020e6d4186e5d/raw/a2f5c22a4180b3c028e921812eaa4bacfe65c056/.tmux.conf", - "size": 659 - } - }, - "public": true, - "created_at": "2019-01-18T10:44:36Z", - "updated_at": "2019-01-18T10:44:36Z", - "description": "tmux config", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/0eab4b071cbd8ea01b5020e6d4186e5d/comments", - "owner": { - "login": "sean1188", - "id": 8543107, - "node_id": "MDQ6VXNlcjg1NDMxMDc=", - "avatar_url": "https://avatars1.githubusercontent.com/u/8543107?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/sean1188", - "html_url": "https://github.com/sean1188", - "followers_url": "https://api.github.com/users/sean1188/followers", - "following_url": "https://api.github.com/users/sean1188/following{/other_user}", - "gists_url": "https://api.github.com/users/sean1188/gists{/gist_id}", - "starred_url": "https://api.github.com/users/sean1188/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/sean1188/subscriptions", - "organizations_url": "https://api.github.com/users/sean1188/orgs", - "repos_url": "https://api.github.com/users/sean1188/repos", - "events_url": "https://api.github.com/users/sean1188/events{/privacy}", - "received_events_url": "https://api.github.com/users/sean1188/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/b19e4d8916a29759988b24fa74435a17", - "forks_url": "https://api.github.com/gists/b19e4d8916a29759988b24fa74435a17/forks", - "commits_url": "https://api.github.com/gists/b19e4d8916a29759988b24fa74435a17/commits", - "id": "b19e4d8916a29759988b24fa74435a17", - "node_id": "MDQ6R2lzdGIxOWU0ZDg5MTZhMjk3NTk5ODhiMjRmYTc0NDM1YTE3", - "git_pull_url": "https://gist.github.com/b19e4d8916a29759988b24fa74435a17.git", - "git_push_url": "https://gist.github.com/b19e4d8916a29759988b24fa74435a17.git", - "html_url": "https://gist.github.com/b19e4d8916a29759988b24fa74435a17", - "files": { - "1.RegistrySnapshot.xml": { - "filename": "1.RegistrySnapshot.xml", - "type": "application/xml", - "language": "XML", - "raw_url": "https://gist.githubusercontent.com/choco-bot/b19e4d8916a29759988b24fa74435a17/raw/609b0f6d7a5bd98aa3974f60d88324f64cc85ba1/1.RegistrySnapshot.xml", - "size": 1491 - }, - "FilesSnapshot.xml": { - "filename": "FilesSnapshot.xml", - "type": "application/xml", - "language": "XML", - "raw_url": "https://gist.githubusercontent.com/choco-bot/b19e4d8916a29759988b24fa74435a17/raw/d234b1db04ea91a737a543ff09d024c848d06299/FilesSnapshot.xml", - "size": 542 - }, - "Install.txt": { - "filename": "Install.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/b19e4d8916a29759988b24fa74435a17/raw/2fa375d8148ab9dc6332152267afc4c60d98f520/Install.txt", - "size": 34806 - }, - "Uninstall.txt": { - "filename": "Uninstall.txt", - "type": "text/plain", - "language": "Text", - "raw_url": "https://gist.githubusercontent.com/choco-bot/b19e4d8916a29759988b24fa74435a17/raw/751ded1a5a1715ab054ad2a4f30c58e09caeb84a/Uninstall.txt", - "size": 12344 - }, - "_Summary.md": { - "filename": "_Summary.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/choco-bot/b19e4d8916a29759988b24fa74435a17/raw/5534b8d9869e9beacc82df04c56e3a22df6edd2f/_Summary.md", - "size": 434 - } - }, - "public": true, - "created_at": "2019-01-18T10:44:23Z", - "updated_at": "2019-01-18T10:44:23Z", - "description": "jwcad v8.03.1 - Passed - Package Tests Results", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/b19e4d8916a29759988b24fa74435a17/comments", - "owner": { - "login": "choco-bot", - "id": 6270979, - "node_id": "MDQ6VXNlcjYyNzA5Nzk=", - "avatar_url": "https://avatars2.githubusercontent.com/u/6270979?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/choco-bot", - "html_url": "https://github.com/choco-bot", - "followers_url": "https://api.github.com/users/choco-bot/followers", - "following_url": "https://api.github.com/users/choco-bot/following{/other_user}", - "gists_url": "https://api.github.com/users/choco-bot/gists{/gist_id}", - "starred_url": "https://api.github.com/users/choco-bot/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/choco-bot/subscriptions", - "organizations_url": "https://api.github.com/users/choco-bot/orgs", - "repos_url": "https://api.github.com/users/choco-bot/repos", - "events_url": "https://api.github.com/users/choco-bot/events{/privacy}", - "received_events_url": "https://api.github.com/users/choco-bot/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/3fc2388e512ebe216a747564ca3764d1", - "forks_url": "https://api.github.com/gists/3fc2388e512ebe216a747564ca3764d1/forks", - "commits_url": "https://api.github.com/gists/3fc2388e512ebe216a747564ca3764d1/commits", - "id": "3fc2388e512ebe216a747564ca3764d1", - "node_id": "MDQ6R2lzdDNmYzIzODhlNTEyZWJlMjE2YTc0NzU2NGNhMzc2NGQx", - "git_pull_url": "https://gist.github.com/3fc2388e512ebe216a747564ca3764d1.git", - "git_push_url": "https://gist.github.com/3fc2388e512ebe216a747564ca3764d1.git", - "html_url": "https://gist.github.com/3fc2388e512ebe216a747564ca3764d1", - "files": { - "PY0101EN-2-3-Sets.ipynb": { - "filename": "PY0101EN-2-3-Sets.ipynb", - "type": "text/plain", - "language": "Jupyter Notebook", - "raw_url": "https://gist.githubusercontent.com/davente/3fc2388e512ebe216a747564ca3764d1/raw/7c46c1c913d5c4fc455eca7079fa15fb7d4bf080/PY0101EN-2-3-Sets.ipynb", - "size": 23281 - } - }, - "public": true, - "created_at": "2019-01-18T10:44:13Z", - "updated_at": "2019-01-18T10:44:13Z", - "description": "Created on Cognitive Class Labs", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/3fc2388e512ebe216a747564ca3764d1/comments", - "owner": { - "login": "davente", - "id": 23741489, - "node_id": "MDQ6VXNlcjIzNzQxNDg5", - "avatar_url": "https://avatars2.githubusercontent.com/u/23741489?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/davente", - "html_url": "https://github.com/davente", - "followers_url": "https://api.github.com/users/davente/followers", - "following_url": "https://api.github.com/users/davente/following{/other_user}", - "gists_url": "https://api.github.com/users/davente/gists{/gist_id}", - "starred_url": "https://api.github.com/users/davente/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/davente/subscriptions", - "organizations_url": "https://api.github.com/users/davente/orgs", - "repos_url": "https://api.github.com/users/davente/repos", - "events_url": "https://api.github.com/users/davente/events{/privacy}", - "received_events_url": "https://api.github.com/users/davente/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/abb449f7e57fe60b424cf01ba705e863", - "forks_url": "https://api.github.com/gists/abb449f7e57fe60b424cf01ba705e863/forks", - "commits_url": "https://api.github.com/gists/abb449f7e57fe60b424cf01ba705e863/commits", - "id": "abb449f7e57fe60b424cf01ba705e863", - "node_id": "MDQ6R2lzdGFiYjQ0OWY3ZTU3ZmU2MGI0MjRjZjAxYmE3MDVlODYz", - "git_pull_url": "https://gist.github.com/abb449f7e57fe60b424cf01ba705e863.git", - "git_push_url": "https://gist.github.com/abb449f7e57fe60b424cf01ba705e863.git", - "html_url": "https://gist.github.com/abb449f7e57fe60b424cf01ba705e863", - "files": { - "main.c": { - "filename": "main.c", - "type": "text/plain", - "language": "C", - "raw_url": "https://gist.githubusercontent.com/tvallois/abb449f7e57fe60b424cf01ba705e863/raw/54eb73afd5d5430e6d83eb3584eb939622ce66b0/main.c", - "size": 2293 - } - }, - "public": true, - "created_at": "2019-01-18T10:44:05Z", - "updated_at": "2019-01-18T10:44:06Z", - "description": "my_level_in_c", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/abb449f7e57fe60b424cf01ba705e863/comments", - "owner": { - "login": "tvallois", - "id": 22823477, - "node_id": "MDQ6VXNlcjIyODIzNDc3", - "avatar_url": "https://avatars0.githubusercontent.com/u/22823477?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/tvallois", - "html_url": "https://github.com/tvallois", - "followers_url": "https://api.github.com/users/tvallois/followers", - "following_url": "https://api.github.com/users/tvallois/following{/other_user}", - "gists_url": "https://api.github.com/users/tvallois/gists{/gist_id}", - "starred_url": "https://api.github.com/users/tvallois/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/tvallois/subscriptions", - "organizations_url": "https://api.github.com/users/tvallois/orgs", - "repos_url": "https://api.github.com/users/tvallois/repos", - "events_url": "https://api.github.com/users/tvallois/events{/privacy}", - "received_events_url": "https://api.github.com/users/tvallois/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/4eb525f37bde5e923ecc39bb95309792", - "forks_url": "https://api.github.com/gists/4eb525f37bde5e923ecc39bb95309792/forks", - "commits_url": "https://api.github.com/gists/4eb525f37bde5e923ecc39bb95309792/commits", - "id": "4eb525f37bde5e923ecc39bb95309792", - "node_id": "MDQ6R2lzdDRlYjUyNWYzN2JkZTVlOTIzZWNjMzliYjk1MzA5Nzky", - "git_pull_url": "https://gist.github.com/4eb525f37bde5e923ecc39bb95309792.git", - "git_push_url": "https://gist.github.com/4eb525f37bde5e923ecc39bb95309792.git", - "html_url": "https://gist.github.com/4eb525f37bde5e923ecc39bb95309792", - "files": { - "tomcat.md": { - "filename": "tomcat.md", - "type": "text/plain", - "language": "Markdown", - "raw_url": "https://gist.githubusercontent.com/jackblack369/4eb525f37bde5e923ecc39bb95309792/raw/7734080a88c3e12e98cab1341735bfca4ea9f182/tomcat.md", - "size": 160 - } - }, - "public": true, - "created_at": "2019-01-18T10:42:54Z", - "updated_at": "2019-01-18T10:42:54Z", - "description": "[A&Q] #tomcat", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/4eb525f37bde5e923ecc39bb95309792/comments", - "owner": { - "login": "jackblack369", - "id": 12108942, - "node_id": "MDQ6VXNlcjEyMTA4OTQy", - "avatar_url": "https://avatars0.githubusercontent.com/u/12108942?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/jackblack369", - "html_url": "https://github.com/jackblack369", - "followers_url": "https://api.github.com/users/jackblack369/followers", - "following_url": "https://api.github.com/users/jackblack369/following{/other_user}", - "gists_url": "https://api.github.com/users/jackblack369/gists{/gist_id}", - "starred_url": "https://api.github.com/users/jackblack369/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/jackblack369/subscriptions", - "organizations_url": "https://api.github.com/users/jackblack369/orgs", - "repos_url": "https://api.github.com/users/jackblack369/repos", - "events_url": "https://api.github.com/users/jackblack369/events{/privacy}", - "received_events_url": "https://api.github.com/users/jackblack369/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - }, - { - "url": "https://api.github.com/gists/454473e53fecca466947d672a61a02ea", - "forks_url": "https://api.github.com/gists/454473e53fecca466947d672a61a02ea/forks", - "commits_url": "https://api.github.com/gists/454473e53fecca466947d672a61a02ea/commits", - "id": "454473e53fecca466947d672a61a02ea", - "node_id": "MDQ6R2lzdDQ1NDQ3M2U1M2ZlY2NhNDY2OTQ3ZDY3MmE2MWEwMmVh", - "git_pull_url": "https://gist.github.com/454473e53fecca466947d672a61a02ea.git", - "git_push_url": "https://gist.github.com/454473e53fecca466947d672a61a02ea.git", - "html_url": "https://gist.github.com/454473e53fecca466947d672a61a02ea", - "files": { - "BulletController.cs": { - "filename": "BulletController.cs", - "type": "text/plain", - "language": "C#", - "raw_url": "https://gist.githubusercontent.com/classicCokie/454473e53fecca466947d672a61a02ea/raw/3e7b0e659abe2282c6aec233e673a92d55db14ff/BulletController.cs", - "size": 646 - } - }, - "public": true, - "created_at": "2019-01-18T10:42:29Z", - "updated_at": "2019-01-18T10:42:30Z", - "description": "", - "comments": 0, - "user": null, - "comments_url": "https://api.github.com/gists/454473e53fecca466947d672a61a02ea/comments", - "owner": { - "login": "classicCokie", - "id": 10669108, - "node_id": "MDQ6VXNlcjEwNjY5MTA4", - "avatar_url": "https://avatars0.githubusercontent.com/u/10669108?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/classicCokie", - "html_url": "https://github.com/classicCokie", - "followers_url": "https://api.github.com/users/classicCokie/followers", - "following_url": "https://api.github.com/users/classicCokie/following{/other_user}", - "gists_url": "https://api.github.com/users/classicCokie/gists{/gist_id}", - "starred_url": "https://api.github.com/users/classicCokie/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/classicCokie/subscriptions", - "organizations_url": "https://api.github.com/users/classicCokie/orgs", - "repos_url": "https://api.github.com/users/classicCokie/repos", - "events_url": "https://api.github.com/users/classicCokie/events{/privacy}", - "received_events_url": "https://api.github.com/users/classicCokie/received_events", - "type": "User", - "site_admin": false - }, - "truncated": false - } -] diff --git a/plutus-playground-server/usecases/Crowdfunding.hs b/plutus-playground-server/usecases/Crowdfunding.hs deleted file mode 100644 index 16e54fd38c..0000000000 --- a/plutus-playground-server/usecases/Crowdfunding.hs +++ /dev/null @@ -1,250 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-} -module Crowdfunding where --- TRIM TO HERE --- Crowdfunding contract implemented using the [[Plutus]] interface. --- This is the fully parallel version that collects all contributions --- in a single transaction. --- --- Note [Transactions in the crowdfunding campaign] explains the structure of --- this contract on the blockchain. - -import Control.Applicative (Applicative (pure)) -import Control.Monad (void) -import Data.Default (Default (def)) -import Data.Text (Text) -import Ledger (POSIXTime, POSIXTimeRange, PaymentPubKeyHash (unPaymentPubKeyHash), ScriptContext (..), TxInfo (..), - getCardanoTxId) -import Ledger qualified -import Ledger.Interval qualified as Interval -import Ledger.TimeSlot qualified as TimeSlot -import Ledger.Typed.Scripts qualified as Scripts hiding (validatorHash) -import Ledger.Value (Value) -import Playground.Contract -import Plutus.Contract -import Plutus.Contract.Constraints qualified as Constraints -import Plutus.Script.Utils.V1.Scripts qualified as PV1 -import Plutus.V1.Ledger.Contexts qualified as PV1 -import PlutusTx qualified -import PlutusTx.Prelude hiding (Applicative (..), Semigroup (..)) -import Prelude (Semigroup (..)) -import Prelude qualified as Haskell -import Wallet.Emulator qualified as Emulator - --- | A crowdfunding campaign. -data Campaign = Campaign - { campaignDeadline :: POSIXTime - -- ^ The date by which the campaign funds can be contributed. - , campaignCollectionDeadline :: POSIXTime - -- ^ The date by which the campaign owner has to collect the funds - , campaignOwner :: PaymentPubKeyHash - -- ^ Public key of the campaign owner. This key is entitled to retrieve the - -- funds if the campaign is successful. - } deriving (Generic, ToJSON, FromJSON, ToSchema) - -PlutusTx.makeLift ''Campaign - --- | Action that can be taken by the participants in this contract. A value of --- `CampaignAction` is provided as the redeemer. The validator script then --- checks if the conditions for performing this action are met. --- -data CampaignAction = Collect | Refund - -PlutusTx.unstableMakeIsData ''CampaignAction -PlutusTx.makeLift ''CampaignAction - -type CrowdfundingSchema = - Endpoint "schedule collection" () - .\/ Endpoint "contribute" Contribution - -newtype Contribution = Contribution - { contribValue :: Value - -- ^ how much to contribute - } deriving stock (Haskell.Eq, Show, Generic) - deriving anyclass (ToJSON, FromJSON, ToSchema, ToArgument) - --- | Construct a 'Campaign' value from the campaign parameters, --- using the wallet's public key. -mkCampaign :: POSIXTime -> POSIXTime -> Wallet -> Campaign -mkCampaign ddl collectionDdl ownerWallet = - Campaign - { campaignDeadline = ddl - , campaignCollectionDeadline = collectionDdl - , campaignOwner = Emulator.mockWalletPaymentPubKeyHash ownerWallet - } - --- | The 'POSIXTimeRange' during which the funds can be collected -collectionRange :: Campaign -> POSIXTimeRange -collectionRange cmp = - -- We have to subtract '2', see Note [Validity Interval's upper bound] - Interval.interval (campaignDeadline cmp) (campaignCollectionDeadline cmp - 2) - --- | The 'POSIXTimeRange' during which a refund may be claimed -refundRange :: Campaign -> POSIXTimeRange -refundRange cmp = - Interval.from (campaignCollectionDeadline cmp) - -data Crowdfunding -instance Scripts.ValidatorTypes Crowdfunding where - type instance RedeemerType Crowdfunding = CampaignAction - type instance DatumType Crowdfunding = PaymentPubKeyHash - -typedValidator :: Campaign -> Scripts.TypedValidator Crowdfunding -typedValidator = Scripts.mkTypedValidatorParam @Crowdfunding - $$(PlutusTx.compile [|| mkValidator ||]) - $$(PlutusTx.compile [|| wrap ||]) - where - wrap = Scripts.mkUntypedValidator - -{-# INLINABLE validRefund #-} -validRefund :: Campaign -> PaymentPubKeyHash -> TxInfo -> Bool -validRefund campaign contributor txinfo = - -- Check that the transaction falls in the refund range of the campaign - (refundRange campaign `Interval.contains` txInfoValidRange txinfo) - -- Check that the transaction is signed by the contributor - && (txinfo `PV1.txSignedBy` unPaymentPubKeyHash contributor) - -validCollection :: Campaign -> TxInfo -> Bool -validCollection campaign txinfo = - -- Check that the transaction falls in the collection range of the campaign - (collectionRange campaign `Interval.contains` txInfoValidRange txinfo) - -- Check that the transaction is signed by the campaign owner - && (txinfo `PV1.txSignedBy` unPaymentPubKeyHash (campaignOwner campaign)) - --- | The validator script is of type 'CrowdfundingValidator', and is --- additionally parameterized by a 'Campaign' definition. This argument is --- provided by the Plutus client, using 'PlutusTx.applyCode'. --- As a result, the 'Campaign' definition is part of the script address, --- and different campaigns have different addresses. -mkValidator :: Campaign -> PaymentPubKeyHash -> CampaignAction -> ScriptContext -> Bool -mkValidator c con act p = case act of - -- the "refund" branch - Refund -> validRefund c con (scriptContextTxInfo p) - -- the "collection" branch - Collect -> validCollection c (scriptContextTxInfo p) - --- | The validator script that determines whether the campaign owner can --- retrieve the funds or the contributors can claim a refund. --- -contributionScript :: Campaign -> PV1.Validator -contributionScript = Scripts.validatorScript . typedValidator - --- | The address of a [[Campaign]] -campaignAddress :: Campaign -> Ledger.ValidatorHash -campaignAddress = PV1.validatorHash . contributionScript - --- | The crowdfunding contract for the 'Campaign'. -crowdfunding :: AsContractError e => Campaign -> Contract () CrowdfundingSchema e () -crowdfunding c = selectList [contribute c, scheduleCollection c] - --- | A sample campaign -theCampaign :: POSIXTime -> Campaign -theCampaign startTime = Campaign - { campaignDeadline = startTime + 40000 - , campaignCollectionDeadline = startTime + 60000 - , campaignOwner = Emulator.mockWalletPaymentPubKeyHash (Emulator.knownWallet 1) - } - --- | The "contribute" branch of the contract for a specific 'Campaign'. Exposes --- an endpoint that allows the user to enter their public key and the --- contribution. Then waits until the campaign is over, and collects the --- refund if the funding was not collected. -contribute :: AsContractError e => Campaign -> Promise () CrowdfundingSchema e () -contribute cmp = endpoint @"contribute" $ \Contribution{contribValue} -> do - contributor <- ownFirstPaymentPubKeyHash - let inst = typedValidator cmp - tx = Constraints.mustPayToTheScriptWithDatumInTx contributor contribValue - <> Constraints.mustValidateIn (Interval.to (campaignDeadline cmp)) - txid <- fmap getCardanoTxId $ mkTxConstraints (Constraints.typedValidatorLookups inst) tx - >>= adjustUnbalancedTx >>= submitUnbalancedTx - - utxo <- watchAddressUntilTime (Scripts.validatorAddress inst) (campaignCollectionDeadline cmp) - - -- 'utxo' is the set of unspent outputs at the campaign address at the - -- collection deadline. If 'utxo' still contains our own contribution - -- then we can claim a refund. - - let flt Ledger.TxOutRef{txOutRefId} _ = txid Haskell.== txOutRefId - tx' = Constraints.collectFromTheScriptFilter flt utxo Refund - <> Constraints.mustValidateIn (refundRange cmp) - <> Constraints.mustBeSignedBy contributor - if Constraints.modifiesUtxoSet tx' - then do - logInfo @Text "Claiming refund" - void $ mkTxConstraints (Constraints.typedValidatorLookups inst - <> Constraints.unspentOutputs utxo) tx' - >>= adjustUnbalancedTx >>= submitUnbalancedTx - else pure () - --- | The campaign owner's branch of the contract for a given 'Campaign'. It --- watches the campaign address for contributions and collects them if --- the funding goal was reached in time. -scheduleCollection :: AsContractError e => Campaign -> Promise () CrowdfundingSchema e () -scheduleCollection cmp = - -- Expose an endpoint that lets the user fire the starting gun on the - -- campaign. (This endpoint isn't technically necessary, we could just - -- run the 'trg' action right away) - endpoint @"schedule collection" $ \() -> do - let inst = typedValidator cmp - - _ <- awaitTime $ campaignDeadline cmp - unspentOutputs <- utxosAt (Scripts.validatorAddress inst) - - let tx = Constraints.collectFromTheScript unspentOutputs Collect - <> Constraints.mustBeSignedBy (campaignOwner cmp) - <> Constraints.mustValidateIn (collectionRange cmp) - void $ submitTxConstraintsSpending inst unspentOutputs tx - -{- note [Transactions in the crowdfunding campaign] - -Assume there is a campaign `c :: Campaign` with two contributors -(identified by public key `pc_1` and `pc_2`) and one campaign owner (pco). -Each contributor creates a transaction, `t_1` and `t_2`, whose outputs are -locked by the scripts `contributionScript c pc_1` and `contributionScript -c pc_1` respectively. - -There are two outcomes for the campaign. - -1. Campaign owner collects the funds from both contributors. In this case - the owner creates a single transaction with two inputs, referring to - `t_1` and `t_2`. Each input contains the script `contributionScript c` - specialised to a contributor. The redeemer script of this transaction - contains the value `Collect`, prompting the validator script to check the - branch for `Collect`. - -2. Refund. In this case each contributor creates a transaction with a - single input claiming back their part of the funds. This case is - covered by the `Refund` branch, and its redeemer script is the - `Refund` action. - -In both cases, the validator script is run twice. In the first case -there is a single transaction consuming both inputs. In the second case there -are two different transactions that may happen at different times. - --} - -{- note [PendingTx] - -This part of the API (the PendingTx argument) is experimental and subject -to change. - --} - -endpoints :: AsContractError e => Contract () CrowdfundingSchema e () -endpoints = crowdfunding (theCampaign $ TimeSlot.scSlotZeroTime def) - -mkSchemaDefinitions ''CrowdfundingSchema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/CrowdfundingSimulations.hs b/plutus-playground-server/usecases/CrowdfundingSimulations.hs deleted file mode 100644 index 53998b0fd8..0000000000 --- a/plutus-playground-server/usecases/CrowdfundingSimulations.hs +++ /dev/null @@ -1,46 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} - -module CrowdfundingSimulations where - -import Crowdfunding (Contribution (Contribution), contribValue, registeredKnownCurrencies) -import Ledger.Ada qualified as Ada -import Playground.Types (ContractCall (AddBlocksUntil), Simulation (Simulation), SimulatorAction, simulationActions, - simulationId, simulationName, simulationWallets) -import SimulationUtils (callEndpoint, simulatorWallet) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [basicCrowdfunding] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - wallet3 = WalletNumber 3 - wallet4 = WalletNumber 4 - simulationWallets = - simulatorWallet registeredKnownCurrencies 100_000_000 <$> - [wallet1, wallet2, wallet3, wallet4] - basicCrowdfunding = - Simulation - { simulationName = "Basic Campaign" - , simulationId = 1 - , simulationWallets - , simulationActions = - [ scheduleCollection wallet1 - , contribute wallet2 11_000_000 - , contribute wallet3 10_000_000 - , contribute wallet4 90_000_000 - , AddBlocksUntil 41 - ] - } - -scheduleCollection :: WalletNumber -> SimulatorAction -scheduleCollection caller = callEndpoint caller "schedule collection" () - -contribute :: WalletNumber -> Integer -> SimulatorAction -contribute caller lovelace = - callEndpoint - caller - "contribute" - Contribution {contribValue = Ada.lovelaceValueOf lovelace} diff --git a/plutus-playground-server/usecases/ErrorHandling.hs b/plutus-playground-server/usecases/ErrorHandling.hs deleted file mode 100644 index 04b5be7342..0000000000 --- a/plutus-playground-server/usecases/ErrorHandling.hs +++ /dev/null @@ -1,98 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE MonoLocalBinds #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeOperators #-} - -module ErrorHandling where - --- TRIM TO HERE -import Control.Lens (makeClassyPrisms, prism', review) -import Control.Monad (void) -import Control.Monad.Error.Lens (catching, throwing, throwing_) -import Data.Text (Text) -import Data.Text qualified as T - -import Data.Default (Default (def)) -import Ledger.TimeSlot (SlotConfig) -import Ledger.TimeSlot qualified as TimeSlot -import Playground.Contract -import Plutus.Contract (AsContractError (_ContractError), ContractError, awaitTime, logInfo, mapError, selectList) -import Prelude (Maybe (..), const, show, ($), (+), (.), (<>)) - --- Demonstrates how to deal with errors in Plutus contracts. We define a custom --- error type 'MyError' with three constructors and use --- 'Control.Lens.makeClassyPrisms' to generate the 'AsMyError' class. We can --- then use 'MyError' in our contracts with the combinators from --- 'Control.Monad.Error.Lens'. The unit tests in 'Spec.ErrorHandling' show how --- to write tests for error conditions. - -type Schema = - Endpoint "throwError" Text - .\/ Endpoint "catchError" Text - .\/ Endpoint "catchContractError" () - --- | 'MyError' has a constructor for each type of error that our contract - -- can throw. The 'AContractError' constructor wraps a 'ContractError'. -data MyError = - Error1 Text - | Error2 - | AContractError ContractError - deriving Show - -makeClassyPrisms ''MyError - -instance AsContractError MyError where - -- 'ContractError' is another error type. It is defined in - -- 'Plutus.Contract.Request'. By making 'MyError' an - -- instance of 'AsContractError' we can handle 'ContractError's - -- thrown by other contracts in our code (see 'catchContractError') - _ContractError = _AContractError - -instance AsMyError Text where - _MyError = prism' (T.pack . show) (const Nothing) - --- | Throw an 'Error1', using 'Control.Monad.Error.Lens.throwing' and the --- prism generated by 'makeClassyPrisms' -throw :: AsMyError e => Text -> Contract () s e () -throw e = do - logInfo @Text $ "throwError: " <> e - throwing _Error1 e - --- | Handle the error from 'throw' using 'Control.Monad.Error.Lens.catching' -throwAndCatch :: AsMyError e => Text -> Contract () s e () -throwAndCatch e = - let handleError1 :: Text -> Contract () s e () - handleError1 t = logInfo $ "handleError: " <> t - in catching _Error1 (throw e) handleError1 - --- | Handle an error from 'awaitTime by wrapping it in the 'AContractError' --- constructor -catchContractError :: (AsMyError e) => SlotConfig -> Contract () s e () -catchContractError slotCfg = - catching _AContractError - (void $ mapError (review _AContractError) $ - awaitTime $ TimeSlot.scSlotZeroTime slotCfg + 10000) - (\_ -> throwing_ _Error2) - -contract - :: ( AsMyError e - , AsContractError e - ) - => SlotConfig - -> Contract () Schema e () -contract slotCfg = selectList - [ endpoint @"throwError" throw - , endpoint @"catchError" throwAndCatch - , endpoint @"catchContractError" $ const (catchContractError slotCfg) - ] - -endpoints :: (AsMyError e, AsContractError e) => Contract () Schema e () -endpoints = contract def - -mkSchemaDefinitions ''Schema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/ErrorHandlingSimulations.hs b/plutus-playground-server/usecases/ErrorHandlingSimulations.hs deleted file mode 100644 index 43235d0890..0000000000 --- a/plutus-playground-server/usecases/ErrorHandlingSimulations.hs +++ /dev/null @@ -1,34 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE TypeApplications #-} - -module ErrorHandlingSimulations where - -import Data.Text (Text) -import ErrorHandling (registeredKnownCurrencies) -import Playground.Types (Simulation (Simulation), SimulatorAction, simulationActions, simulationId, simulationName, - simulationWallets) -import SimulationUtils (callEndpoint, simulatorWallet) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [throwCatch] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - simulationWallets = - simulatorWallet registeredKnownCurrencies 100_000_000 <$> [wallet1, wallet2] - throwCatch = - Simulation - { simulationName = "Throw/Catch" - , simulationId = 1 - , simulationWallets - , simulationActions = [throwError wallet1, catchError wallet2] - } - -throwError :: WalletNumber -> SimulatorAction -throwError caller = callEndpoint @Text caller "throwError" "Hello" - -catchError :: WalletNumber -> SimulatorAction -catchError caller = callEndpoint @Text caller "catchError" "World" diff --git a/plutus-playground-server/usecases/Game.hs b/plutus-playground-server/usecases/Game.hs deleted file mode 100644 index 93b5a07d9f..0000000000 --- a/plutus-playground-server/usecases/Game.hs +++ /dev/null @@ -1,187 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TupleSections #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-} - -module Game where - --- TRIM TO HERE --- A game with two players. Player 1 thinks of a secret word --- and uses its hash, and the game validator script, to lock --- some funds (the prize) in a pay-to-script transaction output. --- Player 2 guesses the word by attempting to spend the transaction --- output. If the guess is correct, the validator script releases the funds. --- If it isn't, the funds stay locked. -import Control.Lens (_2, (^?)) -import Control.Monad (void) -import Data.ByteString.Char8 qualified as C -import Data.Map (Map) -import Data.Map qualified as Map -import Data.Maybe (catMaybes) -import Ledger.Ada qualified as Ada -import Ledger.Constraints qualified as Constraints -import Ledger.Tx (DecoratedTxOut (..), datumInDatumFromQuery, decoratedTxOutDatum) -import Ledger.Typed.Scripts qualified as Scripts -import Playground.Contract -import Plutus.Contract -import Plutus.Script.Utils.V1.Address (mkValidatorAddress) -import Plutus.V1.Ledger.Api (Address, Datum (Datum), ScriptContext, Validator, Value) -import PlutusTx qualified -import PlutusTx.Prelude hiding (pure, (<$>)) -import Prelude qualified as Haskell - ------------------------------------------------------------- - -newtype HashedString = HashedString BuiltinByteString deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) - -PlutusTx.makeLift ''HashedString - -newtype ClearString = ClearString BuiltinByteString deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) - -PlutusTx.makeLift ''ClearString - -type GameSchema = - Endpoint "lock" LockParams - .\/ Endpoint "guess" GuessParams - -data Game -instance Scripts.ValidatorTypes Game where - type instance RedeemerType Game = ClearString - type instance DatumType Game = HashedString - -gameInstance :: Scripts.TypedValidator Game -gameInstance = Scripts.mkTypedValidator @Game - $$(PlutusTx.compile [|| validateGuess ||]) - $$(PlutusTx.compile [|| wrap ||]) where - wrap = Scripts.mkUntypedValidator @HashedString @ClearString - --- create a data script for the guessing game by hashing the string --- and lifting the hash to its on-chain representation -hashString :: Haskell.String -> HashedString -hashString = HashedString . sha2_256 . toBuiltin . C.pack - --- create a redeemer script for the guessing game by lifting the --- string to its on-chain representation -clearString :: Haskell.String -> ClearString -clearString = ClearString . toBuiltin . C.pack - --- | The validation function (Datum -> Redeemer -> ScriptContext -> Bool) -validateGuess :: HashedString -> ClearString -> ScriptContext -> Bool -validateGuess hs cs _ = isGoodGuess hs cs - -isGoodGuess :: HashedString -> ClearString -> Bool -isGoodGuess (HashedString actual) (ClearString guess') = actual == sha2_256 guess' - --- | The validator script of the game. -gameValidator :: Validator -gameValidator = Scripts.validatorScript gameInstance - --- | The address of the game (the hash of its validator script) -gameAddress :: Address -gameAddress = mkValidatorAddress gameValidator - --- | Parameters for the "lock" endpoint -data LockParams = LockParams - { secretWord :: Haskell.String - , amount :: Value - } - deriving stock (Haskell.Eq, Haskell.Show, Generic) - deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument) - --- | Parameters for the "guess" endpoint -newtype GuessParams = GuessParams - { guessWord :: Haskell.String - } - deriving stock (Haskell.Eq, Haskell.Show, Generic) - deriving anyclass (FromJSON, ToJSON, ToSchema, ToArgument) - --- | The "lock" contract endpoint. See note [Contract endpoints] -lock :: AsContractError e => Promise () GameSchema e () -lock = endpoint @"lock" @LockParams $ \(LockParams secret amt) -> do - logInfo @Haskell.String $ "Pay " <> Haskell.show amt <> " to the script" - let tx = Constraints.mustPayToTheScriptWithDatumInTx (hashString secret) amt - void (submitTxConstraints gameInstance tx) - --- | The "guess" contract endpoint. See note [Contract endpoints] -guess :: AsContractError e => Promise () GameSchema e () -guess = endpoint @"guess" @GuessParams $ \(GuessParams theGuess) -> do - -- Wait for script to have a UTxO of a least 1 lovelace - logInfo @Haskell.String "Waiting for script to have a UTxO of at least 1 lovelace" - utxos <- fundsAtAddressGeq gameAddress (Ada.lovelaceValueOf 1) - - let redeemer = clearString theGuess - tx = Constraints.collectFromTheScript utxos redeemer - - -- Log a message saying if the secret word was correctly guessed - let hashedSecretWord = findSecretWordValue utxos - isCorrectSecretWord = fmap (`isGoodGuess` redeemer) hashedSecretWord == Just True - if isCorrectSecretWord - then logWarn @Haskell.String "Correct secret word! Submitting the transaction" - else logWarn @Haskell.String "Incorrect secret word, but still submiting the transaction" - - -- This is only for test purposes to have a possible failing transaction. - -- In a real use-case, we would not submit the transaction if the guess is - -- wrong. - logInfo @Haskell.String "Submitting transaction to guess the secret word" - void (submitTxConstraintsSpending gameInstance utxos tx) - --- | Find the secret word in the Datum of the UTxOs -findSecretWordValue :: Map TxOutRef DecoratedTxOut -> Maybe HashedString -findSecretWordValue = - listToMaybe . catMaybes . Map.elems . Map.map secretWordValue - --- | Extract the secret word in the Datum of a given transaction output is possible -secretWordValue :: DecoratedTxOut -> Maybe HashedString -secretWordValue o = do - Datum d <- o ^? decoratedTxOutDatum . _2 . datumInDatumFromQuery - PlutusTx.fromBuiltinData d - -game :: AsContractError e => Contract () GameSchema e () -game = do - logInfo @Haskell.String "Waiting for guess or lock endpoint..." - selectList [lock, guess] - -{- Note [Contract endpoints] - -A contract endpoint is a function that uses the wallet API to interact with the -blockchain. We can look at contract endpoints from two different points of view. - -1. Contract users - -Contract endpoints are the visible interface of the contract. They provide a -UI (HTML form) for entering the parameters of the actions we may take as part -of the contract. - -2. Contract authors - -As contract authors we define endpoints as functions that return a value of -type 'MockWallet ()'. This type indicates that the function uses the wallet API -to produce and spend transaction outputs on the blockchain. - -Endpoints can have any number of parameters: 'lock' has two -parameters, 'guess' has one and 'startGame' has none. For each endpoint we -include a call to 'mkFunction' at the end of the contract definition. This -causes the Haskell compiler to generate a schema for the endpoint. The Plutus -Playground then uses this schema to present an HTML form to the user where the -parameters can be entered. - --} - -endpoints :: AsContractError e => Contract () GameSchema e () -endpoints = game - -mkSchemaDefinitions ''GameSchema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/GameSimulations.hs b/plutus-playground-server/usecases/GameSimulations.hs deleted file mode 100644 index ee5dc35925..0000000000 --- a/plutus-playground-server/usecases/GameSimulations.hs +++ /dev/null @@ -1,56 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} - -module GameSimulations where - -import Game (GuessParams (GuessParams), LockParams (LockParams), amount, guessWord, registeredKnownCurrencies, - secretWord) -import Ledger.Ada qualified as Ada -import Playground.Types (ContractCall (AddBlocks), Simulation (Simulation), SimulatorAction, simulationActions, - simulationId, simulationName, simulationWallets) -import SimulationUtils (callEndpoint, simulatorWallet) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [basicGame, badGuess] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - wallet3 = WalletNumber 3 - basicGame = - Simulation - { simulationName = "Basic Game" - , simulationId = 1 - , simulationWallets = simulatorWallet registeredKnownCurrencies 100_000_000 <$> [wallet1, wallet2] - , simulationActions = - [ lock wallet1 "Plutus" 50_000_000 - , AddBlocks 1 - , guess wallet2 "Plutus" - , AddBlocks 1 - ] - } - badGuess = - Simulation - { simulationName = "One Bad Guess" - , simulationId = 2 - , simulationWallets = simulatorWallet registeredKnownCurrencies 100_000_000 <$> [wallet1, wallet2, wallet3] - , simulationActions = - [ lock wallet1 "Plutus" 50_000_000 - , AddBlocks 1 - , guess wallet2 "Marlowe" - , AddBlocks 1 - , guess wallet3 "Plutus" - , AddBlocks 1 - ] - } - -lock :: WalletNumber -> String -> Integer -> SimulatorAction -lock caller secretWord balance = - callEndpoint - caller - "lock" - LockParams {secretWord, amount = Ada.lovelaceValueOf balance} - -guess :: WalletNumber -> String -> SimulatorAction -guess caller guessWord = callEndpoint caller "guess" (GuessParams {guessWord}) diff --git a/plutus-playground-server/usecases/HelloWorld.hs b/plutus-playground-server/usecases/HelloWorld.hs deleted file mode 100644 index d3fff6e034..0000000000 --- a/plutus-playground-server/usecases/HelloWorld.hs +++ /dev/null @@ -1,35 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# options_ghc -fno-warn-unused-imports #-} - -module HelloWorld where - --- TRIM TO HERE -import Data.Text qualified as T -import Playground.Contract -import Plutus.Contract -import PlutusTx.Prelude -import Prelude qualified as Haskell - --- | A 'Contract' that logs a message. -hello :: Contract () EmptySchema T.Text () -hello = logInfo @Haskell.String "Hello, world" - -endpoints :: Contract () EmptySchema T.Text () -endpoints = hello - --- 'mkSchemaDefinitions' doesn't work with 'EmptySchema' --- (that is, with 0 endpoints) so we define a --- dummy schema type with 1 endpoint to make it compile. --- TODO: Repair 'mkSchemaDefinitions' -type DummySchema = Endpoint "dummy" () - -mkSchemaDefinitions ''DummySchema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/HelloWorldSimulations.hs b/plutus-playground-server/usecases/HelloWorldSimulations.hs deleted file mode 100644 index 394b018ff4..0000000000 --- a/plutus-playground-server/usecases/HelloWorldSimulations.hs +++ /dev/null @@ -1,27 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} - -module HelloWorldSimulations where - -import HelloWorld (registeredKnownCurrencies) -import Playground.Types (ContractCall (AddBlocks), Simulation (Simulation), simulationActions, simulationId, - simulationName, simulationWallets) -import SimulationUtils (simulatorWallet) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [helloWorld] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - simulationWallets = - simulatorWallet registeredKnownCurrencies 100_000_000 <$> - [wallet1, wallet2] - helloWorld = - Simulation - { simulationName = "Hello, world" - , simulationId = 1 - , simulationWallets - , simulationActions = [ AddBlocks 1 ] - } diff --git a/plutus-playground-server/usecases/SimulationUtils.hs b/plutus-playground-server/usecases/SimulationUtils.hs deleted file mode 100644 index 017b5c13c6..0000000000 --- a/plutus-playground-server/usecases/SimulationUtils.hs +++ /dev/null @@ -1,39 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} - -module SimulationUtils where - -import Ledger.Scripts (ValidatorHash (ValidatorHash)) -import Ledger.Value (CurrencySymbol (CurrencySymbol), TokenName, Value) -import Ledger.Value qualified as Value -import Playground.Types (ContractCall (CallEndpoint), FunctionSchema (FunctionSchema), KnownCurrency (KnownCurrency), - SimulatorAction, SimulatorWallet (SimulatorWallet), argument, argumentValues, caller, - endpointDescription, hash, knownTokens, simulatorWalletBalance, simulatorWalletWallet) -import Schema (ToArgument, toArgument) -import Wallet.Emulator.Types (WalletNumber) -import Wallet.Types (EndpointDescription) - -callEndpoint :: ToArgument a => WalletNumber -> EndpointDescription -> a -> SimulatorAction -callEndpoint caller endpointDescription param = - CallEndpoint - { caller - , argumentValues = - FunctionSchema {endpointDescription, argument = toArgument param} - } - -initialBalance :: [KnownCurrency] -> Integer -> Value -initialBalance currencies balance = foldMap withCurrencies currencies - where - withCurrencies :: KnownCurrency -> Value - withCurrencies KnownCurrency {hash = ValidatorHash hash, knownTokens} = - foldMap withTokens knownTokens - where - currencySymbol = CurrencySymbol hash - withTokens :: TokenName -> Value - withTokens tokenName = Value.singleton currencySymbol tokenName balance - -simulatorWallet :: [KnownCurrency] -> Integer -> WalletNumber -> SimulatorWallet -simulatorWallet currencies balance wallet = - SimulatorWallet - { simulatorWalletWallet = wallet - , simulatorWalletBalance = initialBalance currencies balance - } diff --git a/plutus-playground-server/usecases/Starter.hs b/plutus-playground-server/usecases/Starter.hs deleted file mode 100644 index 9e04bf658a..0000000000 --- a/plutus-playground-server/usecases/Starter.hs +++ /dev/null @@ -1,96 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-} -module Starter where --- TRIM TO HERE --- This is a starter contract, based on the Game contract, --- containing the bare minimum required scaffolding. --- --- What you should change to something more suitable for --- your use case: --- * The MyDatum type --- * The MyRedeemer type --- --- And add function implementations (and rename them to --- something suitable) for the endpoints: --- * publish --- * redeem - -import Control.Monad (void) -import Ledger (Address) -import Ledger.Constraints qualified as Constraints -import Ledger.Typed.Scripts qualified as Scripts -import Ledger.Value (Value) -import Playground.Contract -import Plutus.Contract -import Plutus.V1.Ledger.Contexts (ScriptContext) -import PlutusTx qualified -import PlutusTx.Prelude hiding (Applicative (..)) - --- | These are the data script and redeemer types. We are using an integer --- value for both, but you should define your own types. -newtype MyDatum = MyDatum Integer deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) -PlutusTx.makeLift ''MyDatum - -newtype MyRedeemer = MyRedeemer Integer deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) -PlutusTx.makeLift ''MyRedeemer - --- | This method is the spending validator (which gets lifted to --- its on-chain representation). -validateSpend :: MyDatum -> MyRedeemer -> ScriptContext -> Bool -validateSpend _myDataValue _myRedeemerValue _ = error () -- Please provide an implementation. - --- | The address of the contract (the hash of its validator script). -contractAddress :: Address -contractAddress = Scripts.validatorAddress starterInstance - -data Starter -instance Scripts.ValidatorTypes Starter where - type instance RedeemerType Starter = MyRedeemer - type instance DatumType Starter = MyDatum - --- | The script instance is the compiled validator (ready to go onto the chain) -starterInstance :: Scripts.TypedValidator Starter -starterInstance = Scripts.mkTypedValidator @Starter - $$(PlutusTx.compile [|| validateSpend ||]) - $$(PlutusTx.compile [|| wrap ||]) where - wrap = Scripts.mkUntypedValidator @MyDatum @MyRedeemer - --- | The schema of the contract, with two endpoints. -type Schema = - Endpoint "publish" (Integer, Value) - .\/ Endpoint "redeem" Integer - -contract :: AsContractError e => Contract () Schema e () -contract = selectList [publish, redeem] - --- | The "publish" contract endpoint. -publish :: AsContractError e => Promise () Schema e () -publish = endpoint @"publish" $ \(i, lockedFunds) -> do - let tx = Constraints.mustPayToTheScriptWithDatumInTx (MyDatum i) lockedFunds - void $ submitTxConstraints starterInstance tx - --- | The "redeem" contract endpoint. -redeem :: AsContractError e => Promise () Schema e () -redeem = endpoint @"redeem" $ \myRedeemerValue -> do - unspentOutputs <- utxosAt contractAddress - let redeemer = MyRedeemer myRedeemerValue - tx = Constraints.collectFromTheScript unspentOutputs redeemer - void $ submitTxConstraintsSpending starterInstance unspentOutputs tx - -endpoints :: AsContractError e => Contract () Schema e () -endpoints = contract - -mkSchemaDefinitions ''Schema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/StarterSimulations.hs b/plutus-playground-server/usecases/StarterSimulations.hs deleted file mode 100644 index 4134f8f267..0000000000 --- a/plutus-playground-server/usecases/StarterSimulations.hs +++ /dev/null @@ -1,53 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} - -module StarterSimulations where - -import Ledger.Ada (lovelaceValueOf) -import Ledger.Value (Value) -import Playground.Types (ContractCall (AddBlocks, PayToWallet), Simulation (Simulation), SimulatorAction, amount, - recipient, sender, simulationActions, simulationId, simulationName, simulationWallets) -import SimulationUtils (callEndpoint, simulatorWallet) -import Starter (registeredKnownCurrencies) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [publishRedeem, payToWallet] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - simulationWallets = - simulatorWallet registeredKnownCurrencies 100_000_000 <$> [wallet1, wallet2] - publishRedeem = - Simulation - { simulationName = "Publish/Redeem" - , simulationId = 1 - , simulationWallets - , simulationActions = - [ publish wallet1 (12345, lovelaceValueOf 20_000_000) - , AddBlocks 1 - , redeem wallet2 12345 - , AddBlocks 1 - ] - } - payToWallet = - Simulation - { simulationName = "Pay To Wallet" - , simulationId = 2 - , simulationWallets - , simulationActions = - [ PayToWallet - { sender = wallet1 - , recipient = wallet2 - , amount = lovelaceValueOf 20_000_000 - } - , AddBlocks 1 - ] - } - -publish :: WalletNumber -> (Integer, Value) -> SimulatorAction -publish caller = callEndpoint caller "publish" - -redeem :: WalletNumber -> Integer -> SimulatorAction -redeem caller = callEndpoint caller "redeem" diff --git a/plutus-playground-server/usecases/Vesting.hs b/plutus-playground-server/usecases/Vesting.hs deleted file mode 100644 index 2d3e943022..0000000000 --- a/plutus-playground-server/usecases/Vesting.hs +++ /dev/null @@ -1,230 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NoImplicitPrelude #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeApplications #-} -{-# LANGUAGE TypeFamilies #-} -{-# LANGUAGE TypeOperators #-} -module Vesting where --- TRIM TO HERE --- Vesting scheme as a PLC contract -import Control.Lens (view) -import Control.Monad (void, when) -import Data.Default (Default (def)) -import Data.Map qualified as Map -import Data.Text qualified as T - -import Ledger (PaymentPubKeyHash (unPaymentPubKeyHash)) -import Ledger.Ada qualified as Ada -import Ledger.Constraints (TxConstraints, mustBeSignedBy, mustPayToTheScriptWithDatumInTx, mustValidateIn) -import Ledger.Constraints qualified as Constraints -import Ledger.Interval qualified as Interval -import Ledger.TimeSlot qualified as TimeSlot -import Ledger.Tx qualified as Tx -import Ledger.Typed.Scripts qualified as Scripts -import Ledger.Value (Value) -import Ledger.Value qualified as Value -import Playground.Contract -import Plutus.Contract -import Plutus.Contract.Test -import Plutus.V1.Ledger.Api (Address, POSIXTime, POSIXTimeRange, Validator) -import Plutus.V1.Ledger.Contexts (ScriptContext (..), TxInfo (..)) -import Plutus.V1.Ledger.Contexts qualified as Validation -import PlutusTx qualified -import PlutusTx.Prelude hiding (Semigroup (..), fold) -import Prelude as Haskell (Semigroup (..), show) - -{- | - A simple vesting scheme. Money is locked by a contract and may only be - retrieved after some time has passed. - - This is our first example of a contract that covers multiple transactions, - with a contract state that changes over time. - - In our vesting scheme the money will be released in two _tranches_ (parts): - A smaller part will be available after an initial number of time has - passed, and the entire amount will be released at the end. The owner of the - vesting scheme does not have to take out all the money at once: They can - take out any amount up to the total that has been released so far. The - remaining funds stay locked and can be retrieved later. - - Let's start with the data types. - --} - -type VestingSchema = - Endpoint "vest funds" () - .\/ Endpoint "retrieve funds" Value - --- | Tranche of a vesting scheme. -data VestingTranche = VestingTranche { - vestingTrancheDate :: POSIXTime, - vestingTrancheAmount :: Value - } deriving Generic - -PlutusTx.makeLift ''VestingTranche - --- | A vesting scheme consisting of two tranches. Each tranche defines a date --- (POSIX time) after which an additional amount can be spent. -data VestingParams = VestingParams { - vestingTranche1 :: VestingTranche, - vestingTranche2 :: VestingTranche, - vestingOwner :: PaymentPubKeyHash - } deriving Generic - -PlutusTx.makeLift ''VestingParams - -{-# INLINABLE totalAmount #-} --- | The total amount vested -totalAmount :: VestingParams -> Value -totalAmount VestingParams{vestingTranche1,vestingTranche2} = - vestingTrancheAmount vestingTranche1 + vestingTrancheAmount vestingTranche2 - -{-# INLINABLE availableFrom #-} --- | The amount guaranteed to be available from a given tranche in a given time range. -availableFrom :: VestingTranche -> POSIXTimeRange -> Value -availableFrom (VestingTranche d v) range = - -- The valid range is an open-ended range starting from the tranche vesting date - let validRange = Interval.from d - -- If the valid range completely contains the argument range (meaning in particular - -- that the start time of the argument range is after the tranche vesting date), then - -- the money in the tranche is available, otherwise nothing is available. - in if validRange `Interval.contains` range then v else zero - -availableAt :: VestingParams -> POSIXTime -> Value -availableAt VestingParams{vestingTranche1, vestingTranche2} sl = - let f VestingTranche{vestingTrancheDate, vestingTrancheAmount} = - if sl >= vestingTrancheDate then vestingTrancheAmount else mempty - in foldMap f [vestingTranche1, vestingTranche2] - -{-# INLINABLE remainingFrom #-} --- | The amount that has not been released from this tranche yet -remainingFrom :: VestingTranche -> POSIXTimeRange -> Value -remainingFrom t@VestingTranche{vestingTrancheAmount} range = - vestingTrancheAmount - availableFrom t range - -{-# INLINABLE validate #-} -validate :: VestingParams -> () -> () -> ScriptContext -> Bool -validate VestingParams{vestingTranche1, vestingTranche2, vestingOwner} () () ctx@ScriptContext{scriptContextTxInfo=txInfo@TxInfo{txInfoValidRange}} = - let - remainingActual = Validation.valueLockedBy txInfo (Validation.ownHash ctx) - - remainingExpected = - remainingFrom vestingTranche1 txInfoValidRange - + remainingFrom vestingTranche2 txInfoValidRange - - in remainingActual `Value.geq` remainingExpected - -- The policy encoded in this contract - -- is "vestingOwner can do with the funds what they want" (as opposed - -- to "the funds must be paid to vestingOwner"). This is enforcey by - -- the following condition: - && Validation.txSignedBy txInfo (unPaymentPubKeyHash vestingOwner) - -- That way the recipient of the funds can pay them to whatever address they - -- please, potentially saving one transaction. - -data Vesting -instance Scripts.ValidatorTypes Vesting where - type instance RedeemerType Vesting = () - type instance DatumType Vesting = () - -vestingScript :: VestingParams -> Validator -vestingScript = Scripts.validatorScript . typedValidator - -typedValidator :: VestingParams -> Scripts.TypedValidator Vesting -typedValidator = Scripts.mkTypedValidatorParam @Vesting - $$(PlutusTx.compile [|| validate ||]) - $$(PlutusTx.compile [|| wrap ||]) - where - wrap = Scripts.mkUntypedValidator - -contractAddress :: VestingParams -> Address -contractAddress = Scripts.validatorAddress . typedValidator - -vestingContract :: VestingParams -> Contract () VestingSchema T.Text () -vestingContract vesting = selectList [vest, retrieve] - where - vest = endpoint @"vest funds" $ \_ -> vestFundsC vesting - retrieve = endpoint @"retrieve funds" $ \payment -> do - liveness <- retrieveFundsC vesting payment - case liveness of - Alive -> awaitPromise retrieve - Dead -> pure () - -payIntoContract :: Value -> TxConstraints () () -payIntoContract = mustPayToTheScriptWithDatumInTx () - -vestFundsC - :: VestingParams - -> Contract () s T.Text () -vestFundsC vesting = do - let txn = payIntoContract (totalAmount vesting) - mkTxConstraints (Constraints.typedValidatorLookups $ typedValidator vesting) txn - >>= adjustUnbalancedTx >>= void . submitUnbalancedTx - -data Liveness = Alive | Dead - -retrieveFundsC - :: VestingParams - -> Value - -> Contract () s T.Text Liveness -retrieveFundsC vesting payment = do - let inst = typedValidator vesting - addr = Scripts.validatorAddress inst - now <- fst <$> currentNodeClientTimeRange - unspentOutputs <- utxosAt addr - let - currentlyLocked = foldMap (view Tx.decoratedTxOutValue) (Map.elems unspentOutputs) - remainingValue = currentlyLocked - payment - mustRemainLocked = totalAmount vesting - availableAt vesting now - maxPayment = currentlyLocked - mustRemainLocked - - when (remainingValue `Value.lt` mustRemainLocked) - $ throwError - $ T.unwords - [ "Cannot take out" - , T.pack (show payment) `T.append` "." - , "The maximum is" - , T.pack (show maxPayment) `T.append` "." - , "At least" - , T.pack (show mustRemainLocked) - , "must remain locked by the script." - ] - - let liveness = if remainingValue `Value.gt` mempty then Alive else Dead - remainingOutputs = case liveness of - Alive -> payIntoContract remainingValue - Dead -> mempty - txn = Constraints.collectFromTheScript unspentOutputs () - <> remainingOutputs - <> mustValidateIn (Interval.from now) - <> mustBeSignedBy (vestingOwner vesting) - -- we don't need to add a pubkey output for 'vestingOwner' here - -- because this will be done by the wallet when it balances the - -- transaction. - mkTxConstraints (Constraints.typedValidatorLookups inst - <> Constraints.unspentOutputs unspentOutputs) txn - >>= adjustUnbalancedTx >>= void . submitUnbalancedTx - return liveness - -endpoints :: Contract () VestingSchema T.Text () -endpoints = vestingContract vestingParams - where - vestingOwner = mockWalletPaymentPubKeyHash w1 - vestingParams = - VestingParams {vestingTranche1, vestingTranche2, vestingOwner} - vestingTranche1 = - VestingTranche - {vestingTrancheDate = TimeSlot.scSlotZeroTime def + 20000, vestingTrancheAmount = Ada.lovelaceValueOf 50_000_000} - vestingTranche2 = - VestingTranche - {vestingTrancheDate = TimeSlot.scSlotZeroTime def + 40000, vestingTrancheAmount = Ada.lovelaceValueOf 30_000_000} - -mkSchemaDefinitions ''VestingSchema - -$(mkKnownCurrencies []) diff --git a/plutus-playground-server/usecases/VestingSimulations.hs b/plutus-playground-server/usecases/VestingSimulations.hs deleted file mode 100644 index a846364417..0000000000 --- a/plutus-playground-server/usecases/VestingSimulations.hs +++ /dev/null @@ -1,41 +0,0 @@ -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE NumericUnderscores #-} -{-# LANGUAGE OverloadedStrings #-} - -module VestingSimulations where - -import Ledger.Ada (lovelaceValueOf) -import Ledger.Value (Value) -import Playground.Types (ContractCall (AddBlocks), Simulation (Simulation), SimulatorAction, simulationActions, - simulationId, simulationName, simulationWallets) -import SimulationUtils (callEndpoint, simulatorWallet) -import Vesting (registeredKnownCurrencies) -import Wallet.Emulator.Types (WalletNumber (..)) - -simulations :: [Simulation] -simulations = [vestRetrieve] - where - wallet1 = WalletNumber 1 - wallet2 = WalletNumber 2 - simulationWallets = - simulatorWallet registeredKnownCurrencies 100_000_000 <$> [wallet1, wallet2] - vestRetrieve = - Simulation - { simulationName = "Vest/Retrieve" - , simulationId = 1 - , simulationWallets - , simulationActions = - [ vestFunds wallet2 - , AddBlocks 20 - , retrieveFunds wallet1 (lovelaceValueOf 40_000_000) - , AddBlocks 40 - , retrieveFunds wallet1 (lovelaceValueOf 40_000_000) - , AddBlocks 1 - ] - } - -vestFunds :: WalletNumber -> SimulatorAction -vestFunds caller = callEndpoint caller "vest funds" () - -retrieveFunds :: WalletNumber -> Value -> SimulatorAction -retrieveFunds caller = callEndpoint caller "retrieve funds" diff --git a/shell.nix b/shell.nix index 8248d918ff..30f824f552 100644 --- a/shell.nix +++ b/shell.nix @@ -5,7 +5,7 @@ , packages ? import ./. { inherit system enableHaskellProfiling sources sourcesOverride; } }: let - inherit (packages) pkgs plutus-apps plutus-playground pab-nami-demo docs webCommon; + inherit (packages) pkgs plutus-apps pab-nami-demo docs webCommon; inherit (pkgs) stdenv lib utillinux python3 nixpkgs-fmt glibcLocales; inherit (plutus-apps) haskell stylish-haskell sphinxcontrib-haddock sphinx-markdown-tables sphinxemoji scriv nix-pre-commit-hooks cabal-fmt; @@ -130,7 +130,6 @@ let hie-bios hlint pab-nami-demo.start-backend - plutus-playground.start-backend psa purescript-language-server purs-0_14_3 diff --git a/stack.yaml b/stack.yaml index 6268d1b509..f27bd8a9db 100644 --- a/stack.yaml +++ b/stack.yaml @@ -13,10 +13,8 @@ packages: - plutus-contract - plutus-ledger - plutus-pab -- plutus-playground-server - plutus-use-cases - quickcheck-dynamic -- web-ghc extra-deps: - OddWord-1.0.2.0@sha256:5d848ff5db2c0457ce37ccc8898ce2b6b880a1c6a78e5b16841328a7404ff5ee,1888 diff --git a/web-ghc/.gitignore b/web-ghc/.gitignore deleted file mode 100644 index 2fb2b8e0b9..0000000000 --- a/web-ghc/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.stack-work/ -*~ -/playground.yaml diff --git a/web-ghc/LICENSE b/web-ghc/LICENSE deleted file mode 100644 index 0c8a80022e..0000000000 --- a/web-ghc/LICENSE +++ /dev/null @@ -1,53 +0,0 @@ -Apache License - -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. - -"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of this License; and -You must cause any modified files to carry prominent notices stating that You changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. -5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS diff --git a/web-ghc/NOTICE b/web-ghc/NOTICE deleted file mode 100644 index 63df78b657..0000000000 --- a/web-ghc/NOTICE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2022 Input Output Global, Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/web-ghc/README.md b/web-ghc/README.md deleted file mode 100644 index 4200198e0a..0000000000 --- a/web-ghc/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Building - -## Server - -### stack - -```sh -stack build -stack exec web-ghc-server -- webserver -``` - -### nix - -```sh -nix build -f default.nix web-ghc -./result/bin/web-ghc-server webserver -``` \ No newline at end of file diff --git a/web-ghc/app/Main.hs b/web-ghc/app/Main.hs deleted file mode 100644 index 68102f10ff..0000000000 --- a/web-ghc/app/Main.hs +++ /dev/null @@ -1,73 +0,0 @@ -{-# LANGUAGE ApplicativeDo #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module Main - ( main, - ) -where - -import Control.Monad.IO.Class (MonadIO) -import Control.Monad.Logger (MonadLogger, logInfoN, runStderrLoggingT) -import Data.Text qualified as Text -import Data.Time.Units (Second, fromMicroseconds) -import Network.Wai.Handler.Warp (HostPreference, defaultSettings, setHost, setPort) -import Options.Applicative (CommandFields, Mod, Parser, auto, command, customExecParser, disambiguate, fullDesc, help, - helper, idm, info, long, option, prefs, short, showDefault, showHelpOnEmpty, - showHelpOnError, strOption, subparser, value) -import Webserver qualified - -data Command = Webserver - { _host :: !HostPreference, - _port :: !Int, - _timeoutSec :: !Second - } - deriving (Show, Eq) - - -commandParser :: Parser Command -commandParser = subparser webserverCommandParser - -webserverCommandParser :: Mod CommandFields Command -webserverCommandParser = - command "webserver" - $ flip info fullDesc - $ do - _host <- - strOption - ( short 'b' <> long "bind" <> help "Webserver bind address" - <> showDefault - <> value "127.0.0.1" - ) - _port <- - option - auto - ( short 'p' <> long "port" <> help "Webserver port number" - <> showDefault - <> value 8080 - ) - _timeoutSec <- - fromMicroseconds . (*1000000) <$> option - auto - ( short 't' <> long "timeout" <> help "timeout in seconds for interpretation" - <> showDefault - <> value 80 - ) - - pure Webserver {..} - -runCommand :: (MonadIO m, MonadLogger m) => Command -> m () -runCommand Webserver {..} = Webserver.run settings _timeoutSec - where - settings = setHost _host . setPort _port $ defaultSettings - -main :: IO () -main = do - options <- - customExecParser - (prefs $ disambiguate <> showHelpOnEmpty <> showHelpOnError) - (info (helper <*> commandParser) idm) - runStderrLoggingT $ do - logInfoN $ "Running: " <> Text.pack (show options) - runCommand options diff --git a/web-ghc/app/Webserver.hs b/web-ghc/app/Webserver.hs deleted file mode 100644 index 1161741aaa..0000000000 --- a/web-ghc/app/Webserver.hs +++ /dev/null @@ -1,49 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} -{-# OPTIONS_GHC -Wno-orphans #-} - -module Webserver - ( run, - ) -where - -import Control.Concurrent (forkIO) -import Control.Monad (void) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Control.Monad.Logger (MonadLogger, logInfoN) -import Data.Default.Class (def) -import Data.Proxy (Proxy (Proxy)) -import Data.Time.Units (Second, TimeUnit, convertUnit) -import Network.Wai (Application) -import Network.Wai.Handler.Warp (Settings, runSettings) -import Network.Wai.Middleware.Cors (cors, corsRequestHeaders, simpleCorsResourcePolicy) -import Network.Wai.Middleware.Gzip (gzip) -import Network.Wai.Middleware.RequestLogger (logStdout) -import Servant (serve) -import Servant.Prometheus (monitorEndpoints) -import System.Metrics.Prometheus.Concurrent.RegistryT (runRegistryT) -import System.Metrics.Prometheus.Http.Scrape (serveMetricsT) -import Webghc.Server (API, server) - - -app :: Second -> Application -app timeOutSecs = - gzip def . logStdout . cors (const $ Just policy) . serve (Proxy @API) $ server timeOutSecs - where - policy = - simpleCorsResourcePolicy - { corsRequestHeaders = ["content-type", "set-cookie"] - } - -run :: (MonadLogger m, TimeUnit t, MonadIO m) => Settings -> t -> m () -run settings timeOutSecs = runRegistryT $ do - appMonitor <- monitorEndpoints (Proxy @API) - logInfoN "Starting webserver." - void . liftIO . forkIO . runSettings settings . appMonitor $ app (convertUnit timeOutSecs) - serveMetricsT 9091 ["metrics"] diff --git a/web-ghc/src/Interpreter.hs b/web-ghc/src/Interpreter.hs deleted file mode 100644 index 6f0fe02013..0000000000 --- a/web-ghc/src/Interpreter.hs +++ /dev/null @@ -1,81 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} - -module Interpreter where - -import Control.Monad.Catch (MonadMask) -import Control.Monad.Error.Class (MonadError) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Control.Newtype.Generics qualified as Newtype -import Data.Text (Text) -import Data.Text.IO qualified as Text -import Data.Time.Units (TimeUnit) -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult, SourceCode, avoidUnsafe, runghc) -import System.FilePath (()) -import System.IO (Handle, IOMode (ReadWriteMode), hFlush) -import System.IO.Extras (withFile) -import System.IO.Temp (withSystemTempDirectory) - -runscript :: - ( Show t, - TimeUnit t, - MonadMask m, - MonadIO m, - MonadError InterpreterError m - ) => - Handle -> - FilePath -> - t -> - Bool -> - Text -> - m (InterpreterResult String) -runscript handle file timeout implicitPrelude script = do - liftIO $ Text.hPutStr handle script - liftIO $ hFlush handle - runghc timeout (runghcOpts implicitPrelude) file - -compile :: - ( Show t, - TimeUnit t, - MonadMask m, - MonadIO m, - MonadError InterpreterError m - ) => - t -> - Bool -> - SourceCode -> - m (InterpreterResult String) -compile timeout implicitPrelude source = - do - avoidUnsafe source - withSystemTempDirectory "web-ghc-work" $ \dir -> do - let file = dir "Main.hs" - withFile file ReadWriteMode $ \handle -> runscript handle file timeout implicitPrelude . Newtype.unpack $ source - -runghcOpts :: Bool -> [String] -runghcOpts implicitPrelude = - [ "-XDataKinds", - "-XDeriveAnyClass", - "-XDeriveGeneric", - "-XDerivingStrategies", - "-XExplicitNamespaces", - "-XFlexibleContexts", - "-XGeneralizedNewtypeDeriving", - "-XImportQualifiedPost", - "-XMultiParamTypeClasses", - "-XNamedFieldPuns", - "-XNumericUnderscores", - "-XOverloadedStrings", - "-XRecordWildCards", - "-XScopedTypeVariables", - "-XTemplateHaskell", - "-XTypeApplications", - "-XTypeFamilies", - "-XTypeOperators", - -- See Plutus Tx readme - -- runghc is interpreting our code - "-fno-ignore-interface-pragmas", - "-fobject-code" - ] - <> ["-XNoImplicitPrelude" | not implicitPrelude] diff --git a/web-ghc/src/Webghc/Client.hs b/web-ghc/src/Webghc/Client.hs deleted file mode 100644 index eeef6ed68d..0000000000 --- a/web-ghc/src/Webghc/Client.hs +++ /dev/null @@ -1,30 +0,0 @@ -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE TypeApplications #-} -module Webghc.Client where - -import Control.Monad.Error.Class (MonadError, throwError) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Data.Proxy (Proxy (Proxy)) -import Data.Text qualified as Text -import Language.Haskell.Interpreter (CompilationError (RawError), InterpreterError (CompilationErrors), - InterpreterResult) -import Servant.Client (ClientEnv, ClientM, client, runClientM) -import Webghc.Server (CompileRequest, FrontendAPI) - -runghc :: CompileRequest -> ClientM (Either InterpreterError (InterpreterResult String)) -runghc = client (Proxy @FrontendAPI) - --- | Run a script using a webghc backend specified in the client environment -runscript :: - ( MonadIO m, - MonadError InterpreterError m - ) => - ClientEnv -> - CompileRequest -> - m (InterpreterResult String) -runscript clientEnv code = do - res <- liftIO $ flip runClientM clientEnv $ runghc $ code - case res of - Left e -> throwError (CompilationErrors [RawError (Text.pack (show e))]) - Right (Left e) -> throwError e - Right (Right r) -> pure r diff --git a/web-ghc/src/Webghc/Server.hs b/web-ghc/src/Webghc/Server.hs deleted file mode 100644 index 37bd03b41d..0000000000 --- a/web-ghc/src/Webghc/Server.hs +++ /dev/null @@ -1,46 +0,0 @@ -{-# LANGUAGE DataKinds #-} -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DerivingStrategies #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE TypeOperators #-} -module Webghc.Server where - -import Control.Monad.Catch (MonadMask) -import Control.Monad.Except (runExceptT) -import Control.Monad.IO.Class (MonadIO, liftIO) -import Data.Aeson (FromJSON, ToJSON) -import Data.Text (Text) -import Data.Time.Units (Second) -import GHC.Generics (Generic) -import Interpreter (compile) -import Language.Haskell.Interpreter (InterpreterError, InterpreterResult, SourceCode (SourceCode)) -import Servant (Get, JSON, Post, ReqBody, (:<|>) ((:<|>)), (:>)) -import Servant.Server (Server) - -type FrontendAPI = "runghc" :> ReqBody '[JSON] CompileRequest :> Post '[JSON] (Either InterpreterError (InterpreterResult String)) - -type API = - "health" :> Get '[JSON] () - :<|> FrontendAPI - -data CompileRequest = CompileRequest { code :: Text, implicitPrelude :: Bool } - deriving stock (Generic) - deriving anyclass (FromJSON, ToJSON) - -server :: Second -> Server API -server timeoutSecs = - health :<|> runghc timeoutSecs - -health :: Applicative m => m () -health = pure () - -runghc :: - MonadMask m => - MonadIO m => - Second -> - CompileRequest -> - m (Either InterpreterError (InterpreterResult String)) -runghc timeoutSecs CompileRequest {..} = do - liftIO $ print code - runExceptT $ compile timeoutSecs implicitPrelude $ SourceCode code diff --git a/web-ghc/test/Spec.hs b/web-ghc/test/Spec.hs deleted file mode 100644 index 3c79c6fcef..0000000000 --- a/web-ghc/test/Spec.hs +++ /dev/null @@ -1,13 +0,0 @@ -module Main - ( main, - ) -where - -import Test.Tasty (defaultMain, testGroup) - -main :: IO () -main = - defaultMain $ - testGroup - "all tests" - [] diff --git a/web-ghc/web-ghc.cabal b/web-ghc/web-ghc.cabal deleted file mode 100644 index bc54178dac..0000000000 --- a/web-ghc/web-ghc.cabal +++ /dev/null @@ -1,117 +0,0 @@ -cabal-version: 2.0 -name: web-ghc -version: 1.0.0.0 -license: Apache-2.0 -license-files: - LICENSE - NOTICE - -maintainer: david.smith@tweag.io -author: David Smith -homepage: https://github.com/input-output-hk/plutus-apps#readme -bug-reports: https://github.com/input-output-hk/plutus-apps/issues -description: - Please see the README on GitHub at - -build-type: Simple -data-files: - -source-repository head - type: git - location: https://github.com/input-output-hk/plutus-apps - -flag defer-plugin-errors - description: - Defer errors from the plugin, useful for things like Haddock that can't handle it. - - default: False - manual: True - -library - exposed-modules: - Interpreter - Webghc.Client - Webghc.Server - - hs-source-dirs: src - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - ghc-options: - -Wall -Wcompat -Wunused-packages -Wincomplete-uni-patterns - -Wincomplete-record-updates -Wno-missing-import-lists - -Wredundant-constraints - - -------------------- - -- Local components - -------------------- - build-depends: playground-common >=1.0.0 - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - aeson - , base >=4.7 && <5 - , exceptions - , filepath - , mtl - , newtype-generics - , servant-client - , servant-server - , temporary - , text - , time-units - -executable web-ghc-server - main-is: Main.hs - hs-source-dirs: app - other-modules: Webserver - default-language: Haskell2010 - default-extensions: ImportQualifiedPost - ghc-options: - -threaded -rtsopts -with-rtsopts=-N -Wall -Wcompat - -Wincomplete-uni-patterns -Wincomplete-record-updates - -Wno-missing-import-lists -Wredundant-constraints -O0 - -Wunused-packages - - -------------------- - -- Local components - -------------------- - build-depends: playground-common >=1.0.0 - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - base >=4.7 && <5 - , data-default-class - , monad-logger - , optparse-applicative - , prometheus - , servant-server - , text - , time-units - , wai - , wai-cors - , wai-extra - , warp - , web-ghc - -test-suite web-ghc-test - type: exitcode-stdio-1.0 - main-is: Spec.hs - hs-source-dirs: test - other-modules: - default-language: Haskell2010 - ghc-options: - -threaded -rtsopts -with-rtsopts=-N -Wall -Wcompat - -Wincomplete-uni-patterns -Wincomplete-record-updates - -Wno-missing-import-lists -Wredundant-constraints - -fprint-potential-instances -Wunused-packages - - ------------------------ - -- Non-IOG dependencies - ------------------------ - build-depends: - base >=4.7 && <5 - , tasty