Skip to content

Commit 6a856f4

Browse files
authored
Merge pull request #1521 from Plutonomicon/dshuiski/purs-0.15-migration
Migrate to PureScript 0.15
2 parents 406c2c0 + 485cf79 commit 6a856f4

File tree

230 files changed

+10679
-10494
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

230 files changed

+10679
-10494
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ test-data/keys
2727
tmp
2828
node_modules
2929
plutip-server/dist-newstyle/
30+
plutip-server/dist/
3031
plutip-server/.stack-work/
31-

CHANGELOG.md

Lines changed: 90 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,47 +12,52 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
1212
- [Changed](#changed)
1313
- [Fixed](#fixed)
1414
- [Removed](#removed)
15-
- [[v6.0.0]](#v600)
15+
- [[v7.0.0]](#v700)
1616
- [Added](#added-1)
1717
- [Changed](#changed-1)
1818
- [Fixed](#fixed-1)
1919
- [Removed](#removed-1)
20-
- [[v5.0.0]](#v500)
20+
- [[v6.0.0]](#v600)
2121
- [Added](#added-2)
2222
- [Changed](#changed-2)
23-
- [Removed](#removed-2)
2423
- [Fixed](#fixed-2)
25-
- [Runtime Dependencies](#runtime-dependencies)
26-
- [[v4.0.2] - 2023-01-17](#v402---2023-01-17)
27-
- [Fixed](#fixed-3)
28-
- [[v4.0.1] - 2022-12-20](#v401---2022-12-20)
24+
- [Removed](#removed-2)
25+
- [[v5.0.0]](#v500)
2926
- [Added](#added-3)
30-
- [[v4.0.0] - 2022-12-15](#v400---2022-12-15)
31-
- [Added](#added-4)
3227
- [Changed](#changed-3)
3328
- [Removed](#removed-3)
29+
- [Fixed](#fixed-3)
30+
- [Runtime Dependencies](#runtime-dependencies)
31+
- [[v4.0.2] - 2023-01-17](#v402---2023-01-17)
3432
- [Fixed](#fixed-4)
35-
- [Runtime Dependencies](#runtime-dependencies-1)
36-
- [[3.0.0] - 2022-11-21](#300---2022-11-21)
33+
- [[v4.0.1] - 2022-12-20](#v401---2022-12-20)
34+
- [Added](#added-4)
35+
- [[v4.0.0] - 2022-12-15](#v400---2022-12-15)
3736
- [Added](#added-5)
3837
- [Changed](#changed-4)
3938
- [Removed](#removed-4)
4039
- [Fixed](#fixed-5)
41-
- [Runtime Dependencies](#runtime-dependencies-2)
42-
- [[2.0.0] - 2022-09-12](#200---2022-09-12)
40+
- [Runtime Dependencies](#runtime-dependencies-1)
41+
- [[3.0.0] - 2022-11-21](#300---2022-11-21)
4342
- [Added](#added-6)
4443
- [Changed](#changed-5)
4544
- [Removed](#removed-5)
4645
- [Fixed](#fixed-6)
47-
- [[2.0.0-alpha] - 2022-07-05](#200-alpha---2022-07-05)
46+
- [Runtime Dependencies](#runtime-dependencies-2)
47+
- [[2.0.0] - 2022-09-12](#200---2022-09-12)
4848
- [Added](#added-7)
49-
- [Removed](#removed-6)
5049
- [Changed](#changed-6)
50+
- [Removed](#removed-6)
5151
- [Fixed](#fixed-7)
52-
- [[1.1.0] - 2022-06-30](#110---2022-06-30)
52+
- [[2.0.0-alpha] - 2022-07-05](#200-alpha---2022-07-05)
53+
- [Added](#added-8)
54+
- [Removed](#removed-7)
55+
- [Changed](#changed-7)
5356
- [Fixed](#fixed-8)
54-
- [[1.0.1] - 2022-06-17](#101---2022-06-17)
57+
- [[1.1.0] - 2022-06-30](#110---2022-06-30)
5558
- [Fixed](#fixed-9)
59+
- [[1.0.1] - 2022-06-17](#101---2022-06-17)
60+
- [Fixed](#fixed-10)
5661
- [[1.0.0] - 2022-06-10](#100---2022-06-10)
5762

5863
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -67,6 +72,74 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6772

6873
### Removed
6974

75+
## [v7.0.0]
76+
77+
### Added
78+
79+
- [esbuild](https://esbuild.github.io/) bundler support.
80+
- To update your package to use esbuild, add new `devDependencies` to your `package.json`:
81+
82+
```diff
83+
+ "esbuild": "0.18.11",
84+
+ "esbuild-plugin-polyfill-node": "^0.3.0",
85+
+ "esbuild-plugin-wasm": "^1.1.0",
86+
```
87+
88+
Then consult with [the template's build scripts](./templates/ctl-scaffold/esbuild/) - also see the new [Makefile](./templates/ctl-scaffold/Makefile) setup and [NPM scripts](./templates/ctl-scaffold/package.json).
89+
90+
### Changed
91+
92+
- PureScript compiler version has been updated to v0.15.8. ([#1521](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1521))
93+
- PureScript v0.15.x outputs and expects ES modules (instead of CommonJS), which means that FFI code in dependent projects should be updated to use [ES module-style imports and exports](https://nodejs.org/api/esm.html), and consumers of CTL-based bundles should expect ES modules as well.
94+
- Due to limitations of ES modules (inability to patch at runtime), CTL now uses vendored versions of CSL for node and the browser:
95+
96+
```diff
97+
- "@emurgo/cardano-serialization-lib-browser": "11.2.1",
98+
- "@emurgo/cardano-serialization-lib-nodejs": "11.2.1",
99+
+ "@mlabs-haskell/cardano-serialization-lib-gc-browser": "^1.0.6",
100+
+ "@mlabs-haskell/cardano-serialization-lib-gc-nodejs": "^1.0.6",
101+
```
102+
103+
- Our vendored version of `json-bigint` should be updated:
104+
105+
```diff
106+
- "@mlabs-haskell/json-bigint": "1.0.0",
107+
+ "@mlabs-haskell/json-bigint": "2.0.0",
108+
```
109+
110+
- `utf-8-validate` NPM package has been added (used during bundling):
111+
112+
```diff
113+
+ "utf-8-validate": "^5.0.10",
114+
```
115+
116+
- WebPack bundling machinery updates:
117+
118+
```diff
119+
- "webpack": "5.67.0",
120+
- "webpack-cli": "4.10",
121+
- "webpack-dev-server": "4.7.4"
122+
+ "webpack": "5.88.1",
123+
+ "webpack-cli": "5.1.4",
124+
+ "webpack-dev-server": "4.15.1"
125+
```
126+
127+
- Nix machinery refactorings ([#1521](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1521)):
128+
- `buildPursDependencies` is a new function that allows to build everything except the source files of a project itself. It allows to skip rebuilding all the dependencies when using Nix every time. `buildPursProject` calls `buildPursDependencies` automatically.
129+
- `censorCodes` and `strictComp` arguments have been removed from `purescriptProject` and added to `buildPursDependencies` and `buildPursProject` for more granular control.
130+
- `runPursTest`: new `psEntryPoint` argument, for PureScript-level entry point function ("main" by default).
131+
- `runE2ETest`: new `runnerMain` and `runnerPsEntryPoint` arguments to control which module should be the runner.
132+
- `runE2ETest`: new arguments for configuring the E2E test suite: `envFile`, `emptySettingsFile` and `testTimeout`.
133+
- `bundlePursProjectEsbuild` is a bundling function that uses newly introduced `esbuild`.
134+
- `bundlePursProject` is renamed to `bundlePursProjectWebpack`
135+
- `Data.BigInt` (`purescript-bigints`) dependency was replaced with `JS.BigInt` (`purescript-js-bigints`), that uses native JavaScript BigInt instead of `BigInteger.js` library. You can remove `big-integer` NPM dependency from your project, if you don't use it elsewhere. ([#1551](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1551))
136+
137+
### Fixed
138+
139+
### Removed
140+
141+
- Temporarily removed `buildSearchablePursDocs` and `launchSearchablePursDocs` from nix machinery - see [#1578](https://github.com/Plutonomicon/cardano-transaction-lib/issues/1578) for context. Use `buildPursDocs` for now. ([#1521](https://github.com/Plutonomicon/cardano-transaction-lib/pull/1521))
142+
70143
## [v6.0.0]
71144

72145
### Added

Makefile

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,61 @@
11
SHELL := bash
22
.ONESHELL:
3-
.PHONY: run-dev run-build check-format format query-testnet-tip clean check-explicit-exports
3+
.PHONY: esbuild-bundle esbuild-serve webpack-bundle webpack-serve check-format format query-testnet-tip clean check-explicit-exports spago-build create-bundle-entrypoint create-html-entrypoint delete-bundle-entrypoint
44
.SHELLFLAGS := -eu -o pipefail -c
55

66
ps-sources := $(shell fd --no-ignore-parent -epurs)
77
nix-sources := $(shell fd --no-ignore-parent -enix --exclude='spago*')
8-
js-sources := $(shell fd --no-ignore-parent -ejs)
9-
ps-entrypoint := Ctl.Examples.ByUrl # points to one of the example PureScript modules in examples/
10-
ps-bundle = spago bundle-module -m ${ps-entrypoint} --to output.js
8+
js-sources := $(shell fd --no-ignore-parent -ejs -ecjs)
9+
10+
### Bundler setup
11+
12+
# The main Purescript module
13+
ps-entrypoint := Ctl.Examples.ByUrl
14+
# The entry point function in the main PureScript module
15+
ps-entrypoint-function := main
16+
# Whether to bundle for the browser
17+
browser-runtime := 1 # Use "1" for true and "" for false
18+
1119
preview-node-ipc = $(shell docker volume inspect store_node-preview-ipc | jq -r '.[0].Mountpoint')
1220
preprod-node-ipc = $(shell docker volume inspect store_node-preprod-ipc | jq -r '.[0].Mountpoint')
21+
serve-port := 4008
22+
23+
spago-build:
24+
@spago build
25+
26+
create-bundle-entrypoint:
27+
@mkdir -p dist/
28+
@echo 'import("../output/${ps-entrypoint}/index.js").then(m => m.${ps-entrypoint-function}());' > ./dist/entrypoint.js
1329

14-
run-dev:
15-
@${ps-bundle} && BROWSER_RUNTIME=1 webpack-dev-server --progress
30+
delete-bundle-entrypoint:
31+
@rm -f ./dist/entrypoint.js
1632

17-
run-build:
18-
@${ps-bundle} && BROWSER_RUNTIME=1 webpack --mode=production
33+
create-html-entrypoint:
34+
@mkdir -p dist/
35+
@cat << EOF > dist/index.html
36+
<!DOCTYPE html>
37+
<html>
38+
<body><script type="module" src="./index.js"></script></body>
39+
</html>
40+
EOF
41+
42+
esbuild-bundle: spago-build create-bundle-entrypoint
43+
@mkdir -p dist/
44+
BROWSER_RUNTIME=${browser-runtime} node esbuild/bundle.js ./dist/entrypoint.js dist/index.js
45+
@make delete-bundle-entrypoint
46+
47+
esbuild-serve: spago-build create-bundle-entrypoint create-html-entrypoint
48+
BROWSER_RUNTIME=1 node esbuild/serve.js ./dist/entrypoint.js dist/index.js dist/ ${serve-port}
49+
50+
webpack-bundle: spago-build create-bundle-entrypoint
51+
BROWSER_RUNTIME=${browser-runtime} webpack --mode=production \
52+
-o dist/ --env entry=./dist/entrypoint.js
53+
@make delete-bundle-entrypoint
54+
55+
webpack-serve: spago-build create-bundle-entrypoint create-html-entrypoint
56+
BROWSER_RUNTIME=1 webpack-dev-server --progress \
57+
--port ${serve-port} \
58+
-o dist/ --env entry=./dist/entrypoint.js
1959

2060
.ONESHELL:
2161
check-explicit-exports:
@@ -35,8 +75,8 @@ check-whitespace:
3575
check-format: check-explicit-exports check-examples-imports check-whitespace
3676
@purs-tidy check ${ps-sources}
3777
@nixpkgs-fmt --check ${nix-sources}
38-
@prettier --log-level warn -c ${js-sources}
39-
@eslint --quiet ${js-sources}
78+
@prettier --loglevel warn -c ${js-sources}
79+
@eslint --quiet ${js-sources} --parser-options 'sourceType: module'
4080

4181
format:
4282
@purs-tidy format-in-place ${ps-sources}
@@ -66,7 +106,6 @@ run-ci-actions:
66106
nix build -L .#checks.x86_64-linux.ctl-staking-test
67107
nix build -L .#checks.x86_64-linux.examples-imports-check
68108

69-
70109
clean:
71110
@ rm -r .psc-ide-port || true
72111
@ rm -rf .psci_modules || true
@@ -75,3 +114,4 @@ clean:
75114
@ rm -rf .spago2nix || true
76115
@ rm -rf node_modules || true
77116
@ rm -rf output || true
117+
@ rm -rf dist || true

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ You can find help, more information and ongoing discusion about the project here
118118

119119
## Funding acknowledgements
120120

121-
CTL is being developed by MLabs. The following companies/funds have contributed significan resources to development:
121+
CTL is being developed by MLabs. The following companies/funds have contributed significant resources to development:
122122

123123
- [IOHK](https://iohk.io/en/about/)
124124
- [Catalyst Fund8](https://cardano.ideascale.com/c/idea/396607)

doc/babbage-features.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ This document is a reference/explainer for the new CTL APIs introduced for Babba
1414
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
1515
## Reference Inputs
1616

17-
[Reference inputs](https://cips.cardano.org/cip/CIP-0031/#reference-inputs) allow looking at an output without spending it in Plutus scripts.
17+
[Reference inputs](https://cips.cardano.org/cip/CIP-0031#reference-inputs) allow looking at an output without spending it in Plutus scripts.
1818

1919
There are two ways to use an input as a reference in the constraints API:
2020

@@ -28,7 +28,7 @@ There are two ways to use an input as a reference in the constraints API:
2828

2929
## Reference Scripts
3030

31-
[Reference Scripts](https://developers.cardano.org/docs/governance/cardano-improvement-proposals/cip-0033/) allows the use of scripts without attaching them to the transaction (and using a reference instead).
31+
[Reference Scripts](https://cips.cardano.org/cip/CIP-0033) allows the use of scripts without attaching them to the transaction (and using a reference instead).
3232

3333
Reference scripts can be utilized in CTL by first creating a reference point for the script to be used later via `mustPayToScriptWithScriptRef` (or its variants).
3434

@@ -40,7 +40,7 @@ Then, `mustSpendScriptOutputUsingScriptRef` (or its variants) can be used to use
4040

4141
## Inline Data
4242

43-
[CIP-32](https://developers.cardano.org/docs/governance/cardano-improvement-proposals/cip-0032/) introduces the inline data feature that allows storing datum values directly in transaction outputs, instead of just the hashes.
43+
[CIP-32](https://cips.cardano.org/cip/CIP-0032) introduces the inline data feature that allows storing datum values directly in transaction outputs, instead of just the hashes.
4444

4545
In CTL, alternating between datum storage options can be achieved by specifying a `DatumPresence` value with constraints that accept it, like `mustPayToPubKeyWithDatum`.
4646

doc/ctl-as-dependency.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ The following caveats alway applies when using CTL from your project:
2424

2525
CTL exposes two `overlay`s from its flake. You can use these in the Nix setup of your own project to use the same setup as we do, e.g. the same packages and PS builders:
2626

27-
- `overlays.purescript` contains Purescript builders to compile Purescript sources, build bundles with Webpack (`bundlePursProject`), run unit tests using NodeJS (`runPursTest`), run CTL contracts on a private testnet using Plutip (`runPlutipTest`), or build Pursuit documentation (`buildSearchablePursDocs` and `launchSearchablePursDocs`)
27+
- `overlays.purescript` contains Purescript builders to compile Purescript sources, build bundles with Webpack (`bundlePursProject`), run unit tests using NodeJS (`runPursTest`), and run CTL contracts on a private testnet using Plutip (`runPlutipTest`).
2828
- `overlays.runtime` contains various packages and other tools used in CTL's runtime, including `ogmios`, `kupo`, and `plutip-server`. It also defines `buildCtlRuntime` and `launchCtlRuntime` to help you quickly launch all runtime services (see the [runtime docs](./runtime.md))
2929

3030
We've split the overlays into two components to allow users to more easily choose which parts of CTL's Nix infrastructure they would like to directly consume. For example, some users do not require a pre-packaged runtime and would prefer to build it themselves with more control over its components (e.g. by directly using `ogmios` from their own `inputs`). Such users might still like to use our `purescript` overlay -- splitting the `overlays` allows us to support this. `overlays.runtime` also contains several haskell.nix packages which may cause issues with `hackage.nix` versions in your own project.

doc/development.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ To **build** the project **without bundling and for a NodeJS environment**:
7777
- `npm run staking-test` to run [Plutip](./plutip-testing.md)-powered tests for ADA staking functionality - [entry point](../test/Plutip/Staking.purs)
7878
- `npm run blockfrost-test` for [Blockfrost-powered tests](./blockfrost.md) (does not require a runtime, but needs [some setup](./blockfrost.md#setting-up-a-blockfrost-powered-test-suite)) - [entry point](../test/Blockfrost/Contract.purs)
7979
- `npm run blockfrost-local-test` for self-hosted [Blockfrost-powered tests](./blockfrost.md) (requires a [local Blockfrost runtime](./blockfrost.md#running-blockfrost-locally)) - [entry point](../test/Blockfrost/Contract.purs)
80-
- `npm run e2e-test` for [tests with a headless browser](./e2e-testing.md) (requires a runtime and the tests served via HTTP)
80+
- `npm run e2e-test` for [tests with a headless browser](./e2e-testing.md) (requires a runtime and the tests served via HTTP: `npm run start-runtime` and `npm run webpack-serve` or `esbuild-serve`)
8181

8282
#### With Nix
8383

@@ -100,16 +100,16 @@ Here and below, `<SYSTEM>` should be replaced with [one of the supported systems
100100

101101
To run or build/bundle the project for the browser:
102102

103-
- `npm run e2e-serve` will start a Webpack development server at `localhost:4008`, which is required for [E2E tests](./e2e-testing.md)
104-
- `npm run build` will output a Webpack-bundled example module to `dist` (or `nix build -L .#ctl-example-bundle-web` to build an example module using Nix into `./result/`)
103+
- `npm run webpack-serve` will start a Webpack development server at `localhost:4008`, which is required for [E2E tests](./e2e-testing.md)
104+
- `npm run {webpack|esbuild}-bundle` will output a bundled example module to `dist` (or `nix build -L .#ctl-example-bundle-web-{webpack|esbuild}` to build an example module using Nix into `./result/`)
105105

106106
By default, Webpack will build a [Purescript module](../examples/ByUrl.purs) that serves multiple example `Contract`s depending on URL (see [here](./e2e-testing.md#serving-the-contract-to-be-tested)). You can point Webpack to another Purescript entrypoint by changing the `ps-bundle` variable in the Makefile or in the `main` argument in the flake's `packages.ctl-examples-bundle-web`.
107107

108-
You will also need a light wallet extension pre-configured.
108+
You will also need a light wallet extension pre-configured to run a `Contract`.
109109

110-
**Note**: The `BROWSER_RUNTIME` environment variable must be set to `1` in order to build/bundle the project properly for the browser (e.g. `BROWSER_RUNTIME=1 webpack ...`). For Node environments, leave this variable unset or set it to `0`.
110+
**Note**: The `BROWSER_RUNTIME` environment variable must be set to `1` in order to build/bundle the project properly for the browser (e.g. `BROWSER_RUNTIME=1 webpack ...`). For Node environments, leave this variable unset.
111111

112-
**Note**: The `KUPO_HOST` environment variable must be set the base URL of the Kupo service in order to successfully run the project for the browser (e.g. `KUPO_HOST=http://localhost:1442`), otherwise all requests to Kupo will fail.
112+
**Note**: The `KUPO_HOST` environment variable must be set to the base URL of the Kupo service in order to successfully serve the project for the browser (by default, `KUPO_HOST=http://localhost:1442`).
113113

114114
## Generating PS documentation
115115

doc/e2e-testing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ Note that the test closes successfully after the first successful `Contract` exe
214214

215215
CTL offers a function to serve the `Contract`s to be tested with a router, that dispatches contracts and configuration parameters based on query part of the URL.
216216

217-
It also builds a page with a table consisting of links to all possible examples with all possible environments, that looks like this:
217+
It also builds a page with drop-downs, allowing to select an example and an environments, that looks like this:
218218

219219
![Headless browser test suite - served examples](./images/e2e.png)
220220

doc/images/e2e.png

-5.21 KB
Loading

doc/importing-scripts.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
55
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
66

7-
- [Exporting scripts from Plutus](#exporting-scripts-from-plutus)
7+
- [Exporting scripts from Plutus or Plutarch](#exporting-scripts-from-plutus-or-plutarch)
8+
- [Using Plutonomy](#using-plutonomy)
89
- [Importing serialized scripts](#importing-serialized-scripts)
910
- [Serializing Plutus scripts](#serializing-plutus-scripts)
1011
- [PlutusTx](#plutustx)
@@ -13,9 +14,35 @@
1314

1415
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
1516

16-
## Exporting scripts from Plutus
17+
## Exporting scripts from Plutus or Plutarch
1718

18-
See [the-plutus-scaffold](https://github.com/mlabs-haskell/the-plutus-scaffold)'s [exporter](https://github.com/mlabs-haskell/the-plutus-scaffold/tree/main/onchain/exporter) for a pipeline example.
19+
Usually projects use a Haskell binary called *exporter* that outputs a pre-compiler UPLC bundle into a file.
20+
21+
The output file should be a Cardano envelope:
22+
23+
```json
24+
{
25+
"cborHex": "4e4d01000033222220051200120011",
26+
"description": "always-succeeds",
27+
"type": "PlutusScriptV2"
28+
}
29+
```
30+
31+
- An example of a Plutus exporter can be found [here](https://github.com/Mr-Andersen/ctl-multisign-mre/blob/main/onchain/exporter/Main.hs).
32+
- For Plutarch, see [the-plutus-scaffold](https://github.com/mlabs-haskell/the-plutus-scaffold)'s [exporter](https://github.com/mlabs-haskell/the-plutus-scaffold/tree/main/onchain/exporter).
33+
34+
35+
### Using Plutonomy
36+
37+
It makes sense to use [Plutonomy](https://github.com/well-typed/plutonomy) (an optimizer for UPLC) in the exporter:
38+
39+
```haskell
40+
import Plutonomy (aggressiveOptimizerOptions, optimizeUPLCWith)
41+
42+
script :: Script
43+
script = fromCompiledCode $
44+
optimizeUPLCWith aggressiveOptimizerOptions $$(PlutusTx.compile [||policy||])
45+
```
1946

2047
## Importing serialized scripts
2148

0 commit comments

Comments
 (0)