diff --git a/README.md b/README.md index 2f1de7f7..137fb1cb 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,22 @@ # Squiggle [![Packages check](https://github.com/quantified-uncertainty/squiggle/actions/workflows/ci.yml/badge.svg)](https://github.com/quantified-uncertainty/squiggle/actions/workflows/ci.yml) -[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) -[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) +[![npm version - lang](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) +[![npm version - components](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) [![codecov](https://codecov.io/gh/quantified-uncertainty/squiggle/branch/develop/graph/badge.svg?token=QRLBL5CQ7C)](https://codecov.io/gh/quantified-uncertainty/squiggle) -This is an experimental DSL/language for making probabilistic estimates. The full story can be found [here](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3). +_An estimation language_. + +## Get started + +- [Gallery](https://www.squiggle-language.com/docs/Discussions/Gallery) +- [Squiggle playground](https://squiggle-language.com/playground) +- [Language basics](https://www.squiggle-language.com/docs/Features/Language) +- [Squiggle functions source of truth](https://www.squiggle-language.com/docs/Features/Functions) +- [Known bugs](https://www.squiggle-language.com/docs/Discussions/Bugs) +- [Original lesswrong sequence](https://www.lesswrong.com/s/rDe8QE5NvXcZYzgZ3) +- [Author your squiggle models as Observable notebooks](https://observablehq.com/@hazelfire/squiggle) ## Our deployments @@ -27,7 +37,7 @@ the packages can be found in `packages`. - `@quri/squiggle-components` in `packages/components` contains React components that can be passed squiggle strings as props, and return a presentation of the result of the calculation. -- `@quri/squiggle-website` in `packages/website` The main descriptive website for squiggle, +- `packages/website` is the main descriptive website for squiggle, it is hosted at `squiggle-language.com`. The playground depends on the components library which then depends on the language. This means that if you wish to work on the components library, you will need to build (no need to bundle) the language, and as of this writing playground doesn't really work. diff --git a/packages/components/README.md b/packages/components/README.md index 282230d9..03eb5750 100644 --- a/packages/components/README.md +++ b/packages/components/README.md @@ -1,8 +1,29 @@ -# Squiggle Components +[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-components.svg)](https://www.npmjs.com/package/@quri/squiggle-components) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) -This package contains all the components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/). +# Squiggle components -# Build for development +This package contains the react components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/). + +# Usage in a `react` project + +For example, in a fresh `create-react-app` project + +```sh +yarn add @quri/squiggle-components +``` + +Add to `App.js`: + +```jsx +import { SquiggleEditor } from "@quri/squiggle-components"; +; +``` + +# Build storybook for development We assume that you had run `yarn` at monorepo level, installing dependencies. @@ -20,10 +41,3 @@ Run a development server ```sh yarn start ``` - -And build artefacts for production, - -```sh -yarn bundle # builds components library -yarn build # builds storybook app -``` diff --git a/packages/components/package.json b/packages/components/package.json index d895d545..b7841dda 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,13 +1,20 @@ { "name": "@quri/squiggle-components", - "version": "0.2.9", - "licence": "MIT", + "version": "0.2.19", + "license": "MIT", "dependencies": { - "antd": "^4.20.1", - "react-ace": "10.1.0", - "react-dom": "^18.1.0", + "@quri/squiggle-lang": "^0.2.8", "@react-hook/size": "^2.1.2", - "styled-components": "^5.3.5" + "lodash": "^4.17.21", + "react": "^18.1.0", + "react-ace": "^10.1.0", + "react-dom": "^18.1.0", + "react-use": "^17.3.2", + "react-vega": "^7.5.0", + "styled-components": "^5.3.5", + "vega": "^5.22.1", + "vega-embed": "^6.20.6", + "vega-lite": "^5.2.0" }, "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.16.7", @@ -19,34 +26,26 @@ "@storybook/node-logger": "^6.4.22", "@storybook/preset-create-react-app": "^4.1.0", "@storybook/react": "^6.4.22", - "@types/styled-components": "^5.1.24", - "@types/webpack": "^5.28.0", - "style-loader": "^3.3.1", - "ts-loader": "^9.2.9", - "webpack": "^5.72.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.8.1", - "@quri/squiggle-lang": "0.2.5", "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.1.1", + "@testing-library/react": "^13.2.0", "@testing-library/user-event": "^14.1.1", - "@types/jest": "^27.4.0", + "@types/jest": "^27.5.0", "@types/lodash": "^4.14.182", - "@types/node": "^17.0.29", + "@types/node": "^17.0.31", "@types/react": "^18.0.3", "@types/react-dom": "^18.0.2", + "@types/styled-components": "^5.1.24", + "@types/webpack": "^5.28.0", "cross-env": "^7.0.3", - "lodash": "^4.17.21", - "react": "^18.1.0", - "react-scripts": "5.0.1", - "react-vega": "^7.5.0", + "react-scripts": "^5.0.1", + "style-loader": "^3.3.1", + "ts-loader": "^9.3.0", "tsconfig-paths-webpack-plugin": "^3.5.2", "typescript": "^4.6.3", - "vega": "^5.22.1", - "vega-embed": "^6.20.6", - "vega-lite": "^5.2.0", "web-vitals": "^2.1.4", - "webpack-cli": "^4.9.2" + "webpack": "^5.72.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.8.1" }, "scripts": { "start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public", @@ -54,7 +53,8 @@ "bundle": "webpack", "all": "yarn bundle && yarn build", "lint": "prettier --check .", - "format": "prettier --write ." + "format": "prettier --write .", + "prepack": "yarn bundle && tsc -b" }, "eslintConfig": { "extends": [ @@ -88,6 +88,6 @@ "@types/react": "17.0.43" }, "source": "./src/index.ts", - "main": "dist/bundle.js", - "types": "dist/src/index.d.ts" + "main": "./dist/src/index.js", + "types": "./dist/src/index.d.ts" } diff --git a/packages/components/src/SquiggleChart.js.map b/packages/components/src/SquiggleChart.js.map deleted file mode 100644 index b344b505..00000000 --- a/packages/components/src/SquiggleChart.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"SquiggleChart.js","sourceRoot":"","sources":["SquiggleChart.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,6BAAgC;AAChC,sCAAyC;AACzC,0BAA4B;AAC5B,wBAAsB;AAEtB,yDAA8C;AAE9C,yCAAiD;AACjD,8DAA+D;AAC/D,yDAA0D;AAE1D,IAAI,iBAAiB,GAAG,IAAA,gCAAmB,EAAC,EAAC,MAAM,EAAE,kBAA0B,EAAC,CAAC,CAAC;AAElF,IAAI,wBAAwB,GAAG,IAAA,gCAAmB,EAAC,EAAC,MAAM,EAAE,eAAuB,EAAC,CAAC,CAAC;AAK/E,IAAM,aAAa,GAAG,UAAC,EAA6C;QAA3C,cAAc,oBAAA;IAE5C,IAAI,MAAM,GAAG,IAAA,mBAAG,EAAC,cAAc,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE;QACvB,IAAI,aAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClC,IAAG,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,EAAC;YACjC,OAAO,oBAAC,gBAAgB,IAAC,SAAS,EAAE,CAAC,EAAE,MAAM,EAAE,aAAW,CAAC,KAAK,CAAC,GAAI,CAAC;SACvE;aACI,IAAG,aAAW,CAAC,MAAM,CAAC,KAAK,UAAU,EAAC;YACzC,IAAI,KAAK,GAAG,aAAW,CAAC,GAAG,CAAC,KAAK,CAAC;YAClC,IAAG,KAAK,CAAC,GAAG,KAAK,YAAY,EAAC;gBAC5B,IAAI,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;gBAClC,IAAI,QAAM,GAAG,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;gBAChD,IAAI,OAAK,GAAG,CAAC,CAAC;gBACd,IAAI,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,UAAA,CAAC;oBACxB,OAAK,IAAI,CAAC,CAAC;oBACX,OAAO,OAAK,GAAG,QAAM,CAAC;gBACxB,CAAC,CAAC,CAAA;gBACF,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBAChB,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,EAAU;wBAAT,CAAC,QAAA,EAAE,CAAC,QAAA,EAAE,CAAC,QAAA;oBAAO,OAAA,CAAC,EAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAC,CAAC;gBAA/C,CAA+C,CAAC,CAAC;gBAErH,OAAO,CACL,oBAAC,iBAAiB,IAChB,IAAI,EAAE,EAAC,KAAK,EAAE,MAAM,EAAC,GACnB,CACL,CAAC;aACH;iBACI,IAAG,KAAK,CAAC,GAAG,KAAK,UAAU,EAAC;gBAC/B,IAAI,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;gBAClC,IAAI,QAAM,GAAG,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;gBAChD,IAAI,OAAK,GAAG,CAAC,CAAC;gBACd,IAAI,GAAG,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,UAAA,CAAC;oBACxB,OAAK,IAAI,CAAC,CAAC;oBACX,OAAO,OAAK,GAAG,QAAM,CAAC;gBACxB,CAAC,CAAC,CAAA;gBACF,IAAI,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,EAAQ;wBAAP,CAAC,QAAA,EAAE,CAAC,QAAA,EAAC,CAAC,QAAA;oBAAM,OAAA,CAAC,EAAC,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAC,CAAC;gBAA/C,CAA+C,CAAC,CAAC;gBAEnH,OAAO,CACL,oBAAC,iBAAiB,IAChB,IAAI,EAAE,EAAC,KAAK,EAAE,MAAM,EAAC,GACnB,CACL,CAAC;aACH;iBACI,IAAG,KAAK,CAAC,GAAG,KAAK,OAAO,EAAC;gBAC5B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;gBAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;gBACpD,IAAI,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACjD,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;gBAE7D,IAAI,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;gBAC/D,IAAI,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;gBACrD,IAAI,gBAAgB,GAAG,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;gBAMpE,CAAC;gBAEF,IAAI,eAAe,GAAoB,cAAc,CAAC,GAAG,CAAC,UAAC,EAAK;wBAAJ,CAAC,QAAA,EAAC,CAAC,QAAA;oBAAM,OAAA,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC;gBAAhC,CAAgC,CAAC,CAAA;gBACtG,IAAI,eAAe,GAAoB,gBAAgB,CAAC,GAAG,CAAC,UAAC,EAAK;wBAAJ,CAAC,QAAA,EAAC,CAAC,QAAA;oBAAM,OAAA,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAC,CAAC;gBAAlC,CAAkC,CAAC,CAAA;gBAE1G,IAAI,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,CAAA;gBAEzE,IAAI,iBAAe,GAAG,CAAC,GAAG,aAAa,CAAC;gBACxC,IAAI,QAAM,GAAG,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAQ,EAAE,CAAQ,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;gBAEtE,IAAI,OAAK,GAAG,CAAC,CAAC;gBACd,IAAI,GAAG,GAAG,YAAY,CAAC,GAAG,CAAC,UAAC,KAAmB;oBAC7C,IAAG,KAAK,CAAC,IAAI,IAAI,UAAU,EAAE;wBAC3B,OAAK,IAAI,KAAK,CAAC,CAAC,CAAC;wBACjB,OAAO,OAAK,CAAC;qBACd;yBACI,IAAI,KAAK,CAAC,IAAI,IAAI,YAAY,EAAE;wBACnC,OAAK,IAAI,KAAK,CAAC,CAAC,GAAG,QAAM,GAAG,iBAAe,CAAC;wBAC5C,OAAO,OAAK,CAAC;qBACd;gBACH,CAAC,CAAC,CAAC;gBAQH,IAAI,eAAe,GAAuB,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,YAAY,EAAE,UAAC,CAAS,EAAE,KAAmB,IAAK,OAAA,uBAAK,KAAK,KAAE,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,IAAE,EAA7C,CAA6C,CAAC,CAAA;gBACzJ,IAAI,gBAAgB,GAAG,eAAe,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,IAAI,YAAY,EAAtB,CAAsB,CAAC,CAAA;gBAC1E,IAAI,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,IAAI,IAAI,UAAU,EAApB,CAAoB,CAAC,CAAA;gBAEtE,OAAO,CACL,oBAAC,iBAAiB,IAChB,IAAI,EAAE,EAAC,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,cAAc,EAAC,GACpD,CACL,CAAC;aACD;SACJ;aACI,IAAG,aAAW,CAAC,IAAI,KAAK,UAAU,EAAC;YACtC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;YAE1B,IAAI,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,EAAE,EAAC,GAAG,CAAC,CAAC,GAAG,CAAC,UAAC,CAAC,EAAC,CAAC;gBACnC,IAAI,CAAC,GAAG,CAAC,GAAE,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,aAAW,CAAC,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;gBACxB,IAAG,aAAW,CAAC,IAAI,IAAE,UAAU,EAAC;oBAC9B,IAAI,QAAM,GAAG,aAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAChC,OAAO,CAAC,GAAG,CAAC,QAAM,CAAC,CAAC;oBACpB,IAAG,QAAM,CAAC,GAAG,IAAI,IAAI,EAAC;wBACpB,IAAI,eAAe,GAAG;4BACpB,IAAI;4BACJ,IAAI;4BACJ,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,GAAG;4BACH,IAAI;4BACJ,IAAI;yBACL,CAAA;wBAED,IAAI,WAAW,GAAG,cAAc,CAAC,eAAe,EAAE,QAAM,CAAC,KAAK,CAAC,CAAC;wBAChE,OAAO;4BACL,GAAG,EAAE,CAAC;4BACN,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;4BACpB,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC;4BACpB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;4BACrB,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;4BACtB,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;4BACtB,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;yBACvB,CAAA;qBAEA;iBAEF;gBACD,OAAO,CAAC,CAAC;YACb,CAAC,CAAC,CAAA;YACF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,OAAO,oBAAC,wBAAwB,IAAC,IAAI,EAAE,EAAC,OAAO,EAAE,IAAI,EAAC,GAAI,CAAA;SAC3D;KACJ;SACI,IAAG,MAAM,CAAC,GAAG,IAAI,OAAO,EAAE;QAE7B,OAAO,CAAC,+BAAI,0BAA0B,GAAG,MAAM,CAAC,KAAK,CAAK,CAAC,CAAA;KAE5D;IACD,OAAO,CAAC,+BAAI,kBAAkB,CAAK,CAAC,CAAA;AACtC,CAAC,CAAC;AA5JW,QAAA,aAAa,iBA4JxB;AAEF,SAAS,cAAc,CAAC,WAAoB,EAAE,CAAY;IACxD,IAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,UAAU,EAAE;QAC5B,IAAI,OAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC1C,IAAI,QAAM,GAAG,WAAW,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,MAAI,EAAJ,CAAI,CAAC,CAAC;QACvC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAC,CAAC,EAAC,CAAC;YAC9D,OAAK,IAAI,CAAC,CAAA;YACV,WAAW,CAAC,OAAO,CAAC,UAAC,CAAC,EAAE,CAAC;gBACzB,IAAG,OAAK,GAAG,CAAC,IAAI,QAAM,CAAC,CAAC,CAAC,IAAI,MAAI,EAAC;oBAClC,QAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;iBACZ;YACD,CAAC,CAAC,CAAA;QACL,CAAC,CAAC,CAAC;QACH,OAAO,QAAM,CAAC;KAChB;SACI,IAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,YAAY,EAAC;QAClC,IAAI,OAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC1C,IAAI,QAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC5C,IAAI,QAAM,GAAG,WAAW,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,MAAI,EAAJ,CAAI,CAAC,CAAC;QACvC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,UAAC,CAAC,EAAC,CAAC;YAC9D,OAAK,IAAI,CAAC,GAAG,QAAM,CAAC;YACpB,WAAW,CAAC,OAAO,CAAC,UAAC,CAAC,EAAE,CAAC;gBACzB,IAAG,OAAK,GAAG,CAAC,IAAI,QAAM,CAAC,CAAC,CAAC,IAAI,MAAI,EAAC;oBAClC,QAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;iBACZ;YACD,CAAC,CAAC,CAAA;QACL,CAAC,CAAC,CAAC;QACH,OAAO,QAAM,CAAC;KAChB;SACI,IAAG,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,OAAO,EAAC;QAC7B,IAAI,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;QACnD,IAAI,aAAa,GAAG,aAAa,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAC,EAAE,CAAC,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;QAE7D,IAAI,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QAC/D,IAAI,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC;QACvD,IAAI,gBAAgB,GAAG,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE,EAAE,eAAe,CAAC,EAAE,CAAC,CAAC;QAMpE,CAAC;QAEF,IAAI,eAAe,GAAoB,cAAc,CAAC,GAAG,CAAC,UAAC,EAAK;gBAAJ,CAAC,QAAA,EAAC,CAAC,QAAA;YAAM,OAAA,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAC,CAAC;QAAhC,CAAgC,CAAC,CAAA;QACtG,IAAI,eAAe,GAAoB,gBAAgB,CAAC,GAAG,CAAC,UAAC,EAAK;gBAAJ,CAAC,QAAA,EAAC,CAAC,QAAA;YAAM,OAAA,CAAC,EAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAC,CAAC;QAAlC,CAAkC,CAAC,CAAA;QAE1G,IAAI,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,GAAG,CAAC,CAAA;QAEzE,IAAI,iBAAe,GAAG,CAAC,GAAG,aAAa,CAAC;QACxC,IAAI,QAAM,GAAG,eAAe,CAAC,EAAE,CAAC,MAAM,CAAC,UAAC,CAAQ,EAAE,CAAQ,IAAK,OAAA,CAAC,GAAG,CAAC,EAAL,CAAK,CAAC,CAAC;QAEtE,IAAI,OAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAI,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,CAAC,CAAC,CAAC,EAAH,CAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,QAAM,GAAG,WAAW,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,MAAI,EAAJ,CAAI,CAAC,CAAC;QACxC,YAAY,CAAC,GAAG,CAAC,UAAC,KAAmB;YACnC,IAAG,KAAK,CAAC,IAAI,IAAI,UAAU,EAAE;gBAC3B,OAAK,IAAI,KAAK,CAAC,CAAC,CAAC;aAClB;iBACI,IAAI,KAAK,CAAC,IAAI,IAAI,YAAY,EAAE;gBACnC,OAAK,IAAI,KAAK,CAAC,CAAC,GAAG,QAAM,GAAG,iBAAe,CAAC;aAC7C;YACD,WAAW,CAAC,OAAO,CAAC,UAAC,CAAC,EAAC,CAAC;gBACtB,IAAG,OAAK,GAAG,CAAC,IAAI,QAAM,CAAC,CAAC,CAAC,IAAI,MAAI,EAAC;oBAChC,QAAM,CAAC,CAAC,CAAC,GAAG,OAAK,CAAC;iBACnB;YACH,CAAC,CAAC,CAAA;YACF,OAAO,OAAK,CAAC;QACf,CAAC,CAAC,CAAC;QACH,OAAO,QAAM,CAAC;KACf;AACH,CAAC;AAED,qBAAa,CAAC,SAAS,GAAG;IAIzB,cAAc,EAAG,SAAS,CAAC,MAAM;CACjC,CAAC;AAEF,qBAAa,CAAC,YAAY,GAAG;IAC7B,aAAa,EAAE,cAAc;CAE5B,CAAC;AAGF,SAAS,gBAAgB,CAAC,KAA0C;IAClE,IAAI,sBAAsB,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACvE,OAAO,CACL;QACG,sBAAsB,CAAC,KAAK;QAC5B,sBAAsB,CAAC,MAAM;QAC7B,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAC/B;gBACG,UAAU;gBACX,8BAAM,KAAK,EAAE,EAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAC,IACrD,sBAAsB,CAAC,KAAK,CACxB,CACF;YACP,CAAC,CAAC,yCAAK,CACF,CAEN,CAAC;AAEN,CAAC;AAED,IAAM,mBAAmB,GAAG,UAAC,CAAQ;IACnC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACzB,CAAC,CAAC;AAGF,IAAM,gBAAgB,GAAG,UAAC,CAAQ;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;AAC3D,CAAC,CAAC;AAEF,SAAS,YAAY,CAAC,MAAa,EAAE,OAAc;IACjD,IAAM,aAAa,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAClD,IAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACxC,OAAO,UAAG,SAAS,CAAE,CAAC;AACxB,CAAC;AAED;IAIE,sBAAY,MAAa,EAAE,SAAa;QAAb,0BAAA,EAAA,aAAa;QACtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,8BAAO,GAAP;QACE,IAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,IAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,QAAQ,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC;SACvC;QACD,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,mCAAY,GAAZ,UAAa,MAAc,EAAE,KAAa;QACxC,IAAM,SAAS,GAAG,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACtD,IAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,OAAO,UAAG,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAE,CAAC;IACjD,CAAC;IAED,+BAAQ,GAAR,UAAS,MAAc;QACrB,IAAI,MAAM,KAAK,CAAC,EAAE;YAChB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;SAC1C;QAED,IAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE;YACd,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;SAClE;aAAM,IAAI,KAAK,GAAG,CAAC,EAAE;YACpB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC;SAChD;aAAM,IAAI,KAAK,GAAG,CAAC,EAAE;YACpB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;SAC7D;aAAM,IAAI,KAAK,GAAG,CAAC,EAAE;YACpB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;SAC7D;aAAM,IAAI,KAAK,GAAG,EAAE,EAAE;YACrB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;SAC7D;aAAM,IAAI,KAAK,GAAG,EAAE,EAAE;YACrB,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;SAC9D;aAAM;YACL,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;SAClE;IACH,CAAC;IACH,mBAAC;AAAD,CAAC,AA9CD,IA8CC;AAED,SAAgB,UAAU,CAAC,MAAc,EAAE,SAAa;IAAb,0BAAA,EAAA,aAAa;IACtD,IAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC/C,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;AACtB,CAAC;AAHD,gCAGC"} \ No newline at end of file diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index a27f325a..5eafecf9 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -1,42 +1,130 @@ import * as React from "react"; import _ from "lodash"; -import type { Spec } from "vega"; import type { Distribution } from "@quri/squiggle-lang"; import { distributionErrorToString } from "@quri/squiggle-lang"; -import { createClassFromSpec } from "react-vega"; +import { Vega, VisualizationSpec } from "react-vega"; import * as chartSpecification from "../vega-specs/spec-distributions.json"; import { ErrorBox } from "./ErrorBox"; - -let SquiggleVegaChart = createClassFromSpec({ - spec: chartSpecification as Spec, -}); +import { useSize } from "react-use"; +import { + linearXScale, + logXScale, + linearYScale, + expYScale, +} from "./DistributionVegaScales"; +import styled from "styled-components"; type DistributionChartProps = { distribution: Distribution; - width: number; + width?: number; height: number; + /** Whether to show the user graph controls (scale etc) */ + showControls?: boolean; }; export const DistributionChart: React.FC = ({ distribution, - width, height, + width, + showControls = false, }: DistributionChartProps) => { + let [isLogX, setLogX] = React.useState(false); + let [isExpY, setExpY] = React.useState(false); let shape = distribution.pointSet(); - if (shape.tag === "Ok") { - return ( - - ); - } else { - return ( - - {distributionErrorToString(shape.value)} - - ); - } + const [sized, _] = useSize((size) => { + if (shape.tag === "Ok") { + let massBelow0 = + shape.value.continuous.some((x) => x.x <= 0) || + shape.value.discrete.some((x) => x.x <= 0); + let spec = buildVegaSpec(isLogX, isExpY); + let widthProp = width ? width - 20 : size.width - 10; + + // Check whether we should disable the checkbox + var logCheckbox = ( + + ); + if (massBelow0) { + logCheckbox = ( + + ); + } + + var result = ( +
+ + {showControls && ( +
+ {logCheckbox} + +
+ )} +
+ ); + } else { + var result = ( + + {distributionErrorToString(shape.value)} + + ); + } + + return result; + }); + return sized; +}; + +function buildVegaSpec(isLogX: boolean, isExpY: boolean): VisualizationSpec { + return { + ...chartSpecification, + scales: [ + isLogX ? logXScale : linearXScale, + isExpY ? expYScale : linearYScale, + ], + } as VisualizationSpec; +} + +interface CheckBoxProps { + label: string; + onChange: (x: boolean) => void; + value: boolean; + disabled?: boolean; + tooltip?: string; +} + +const Label = styled.label<{ disabled: boolean }>` + ${(props) => props.disabled && "color: #999;"} +`; + +export const CheckBox = ({ + label, + onChange, + value, + disabled = false, + tooltip, +}: CheckBoxProps) => { + return ( + + onChange(!value)} + disabled={disabled} + /> + + + ); }; diff --git a/packages/components/src/components/DistributionVegaScales.ts b/packages/components/src/components/DistributionVegaScales.ts new file mode 100644 index 00000000..f0c5c8f6 --- /dev/null +++ b/packages/components/src/components/DistributionVegaScales.ts @@ -0,0 +1,80 @@ +import type { LogScale, LinearScale, PowScale } from "vega"; +export let linearXScale: LinearScale = { + name: "xscale", + type: "linear", + range: "width", + zero: false, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "x", + }, + { + data: "dis", + field: "x", + }, + ], + }, +}; +export let linearYScale: LinearScale = { + name: "yscale", + type: "linear", + range: "height", + zero: true, + domain: { + fields: [ + { + data: "con", + field: "y", + }, + { + data: "dis", + field: "y", + }, + ], + }, +}; + +export let logXScale: LogScale = { + name: "xscale", + type: "log", + range: "width", + zero: false, + base: 10, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "x", + }, + { + data: "dis", + field: "x", + }, + ], + }, +}; + +export let expYScale: PowScale = { + name: "yscale", + type: "pow", + exponent: 0.1, + range: "height", + zero: true, + nice: false, + domain: { + fields: [ + { + data: "con", + field: "y", + }, + { + data: "dis", + field: "y", + }, + ], + }, +}; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 534d164d..9e65c130 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -5,12 +5,15 @@ import { run, errorValueToString, squiggleExpression, + bindings, + samplingParams, + jsImports, + defaultImports, + defaultBindings, } from "@quri/squiggle-lang"; -import type { samplingParams } from "@quri/squiggle-lang"; import { NumberShower } from "./NumberShower"; import { DistributionChart } from "./DistributionChart"; import { ErrorBox } from "./ErrorBox"; -import useSize from "@react-hook/size"; const variableBox = { Component: styled.div` @@ -30,44 +33,66 @@ const variableBox = { `, }; -export const VariableBox: React.FC<{ +interface VariableBoxProps { heading: string; children: React.ReactNode; -}> = ({ heading = "Error", children }) => { - return ( - - -

{heading}

-
- {children} -
- ); + showTypes?: boolean; +} + +export const VariableBox: React.FC = ({ + heading = "Error", + children, + showTypes = false, +}: VariableBoxProps) => { + if (showTypes) { + return ( + + +

{heading}

+
+ {children} +
+ ); + } else { + return <>{children}; + } }; +let RecordKeyHeader = styled.h3``; + export interface SquiggleItemProps { /** The input string for squiggle */ expression: squiggleExpression; - width: number; + width?: number; height: number; + /** Whether to show type information */ + showTypes?: boolean; + /** Whether to show users graph controls (scale etc) */ + showControls?: boolean; } const SquiggleItem: React.FC = ({ expression, width, height, + showTypes = false, + showControls = false, }: SquiggleItemProps) => { switch (expression.tag) { case "number": return ( - + ); case "distribution": { let distType = expression.value.type(); return ( - - {distType === "Symbolic" ? ( + + {distType === "Symbolic" && showTypes ? ( <>
{expression.value.toString()}
@@ -78,36 +103,77 @@ const SquiggleItem: React.FC = ({ distribution={expression.value} height={height} width={width} + showControls={showControls} />
); } case "string": return ( - {`"${expression.value}"`} + {`"${expression.value}"`} ); case "boolean": return ( - + {expression.value.toString()} ); case "symbol": - return {expression.value}; + return ( + + {expression.value} + + ); case "call": - return {expression.value}; + return ( + + {expression.value} + + ); case "array": return ( - + {expression.value.map((r) => ( - + ))} ); - default: + case "record": + return ( + + {Object.entries(expression.value).map(([key, r]) => ( + <> + {key} + + + ))} + + ); + case "arraystring": + return ( + + {expression.value.map((r) => `"${r}"`)} + + ); + case "lambda": return ( - {"We don't currently have a working viewer for record types."} + There is no viewer currently available for function types. ); } @@ -128,47 +194,68 @@ export interface SquiggleChartProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** variables declared before this expression */ - environment?: unknown; /** When the environment changes */ onChange?(expr: squiggleExpression): void; /** CSS width of the element */ width?: number; height?: number; + /** Bindings of previous variables declared */ + bindings?: bindings; + /** JS imported parameters */ + jsImports?: jsImports; + /** Whether to show type information about returns, default false */ + showTypes?: boolean; + /** Whether to show graph controls (scale etc)*/ + showControls?: boolean; } +const ChartWrapper = styled.div` + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; +`; + export const SquiggleChart: React.FC = ({ squiggleString = "", sampleCount = 1000, outputXYPoints = 1000, onChange = () => {}, height = 60, - width = NaN, + bindings = defaultBindings, + jsImports = defaultImports, + width, + showTypes = false, + showControls = false, }: SquiggleChartProps) => { - const target = React.useRef(null); - const [componentWidth] = useSize(target); - // I would have wanted to just use componentWidth, but this created infinite loops with SquiggleChart.stories. - //So you can manually add a width, as an escape hatch. - let _width = width || componentWidth; let samplingInputs: samplingParams = { sampleCount: sampleCount, xyPointLength: outputXYPoints, }; - let expressionResult = run(squiggleString, samplingInputs); + let expressionResult = run( + squiggleString, + bindings, + samplingInputs, + jsImports + ); let internal: JSX.Element; if (expressionResult.tag === "Ok") { let expression = expressionResult.value; onChange(expression); internal = ( - + ); } else { - // At this point, we came across an error. What was our error? internal = ( {errorValueToString(expressionResult.value)} ); } - return
{internal}
; + return {internal}; }; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 580db580..572dbd76 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -3,7 +3,19 @@ import * as ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import { CodeEditor } from "./CodeEditor"; import styled from "styled-components"; -import type { squiggleExpression } from "@quri/squiggle-lang"; +import type { + squiggleExpression, + samplingParams, + bindings, + jsImports, +} from "@quri/squiggle-lang"; +import { + runPartial, + errorValueToString, + defaultImports, + defaultBindings, +} from "@quri/squiggle-lang"; +import { ErrorBox } from "./ErrorBox"; export interface SquiggleEditorProps { /** The input string for squiggle */ @@ -20,12 +32,18 @@ export interface SquiggleEditorProps { diagramStop?: number; /** If the result is a function, how many points along the function it samples */ diagramCount?: number; - /** The environment, other variables that were already declared */ - environment?: unknown; /** when the environment changes. Used again for notebook magic*/ onChange?(expr: squiggleExpression): void; /** The width of the element */ - width: number; + width?: number; + /** Previous variable declarations */ + bindings?: bindings; + /** JS Imports */ + jsImports?: jsImports; + /** Whether to show detail about types of the returns, default false */ + showTypes?: boolean; + /** Whether to give users access to graph controls */ + showControls: boolean; } const Input = styled.div` @@ -36,7 +54,7 @@ const Input = styled.div` export let SquiggleEditor: React.FC = ({ initialSquiggleString = "", - width = 500, + width, sampleCount, outputXYPoints, kernelWidth, @@ -45,7 +63,10 @@ export let SquiggleEditor: React.FC = ({ diagramStop, diagramCount, onChange, - environment, + bindings = defaultBindings, + jsImports = defaultImports, + showTypes = false, + showControls = false, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -69,8 +90,11 @@ export let SquiggleEditor: React.FC = ({ diagramStart={diagramStart} diagramStop={diagramStop} diagramCount={diagramCount} - environment={environment} onChange={onChange} + bindings={bindings} + jsImports={jsImports} + showTypes={showTypes} + showControls={showControls} /> ); @@ -107,3 +131,94 @@ export function renderSquiggleEditorToDom(props: SquiggleEditorProps) { ); return parent; } + +export interface SquigglePartialProps { + /** The input string for squiggle */ + initialSquiggleString?: string; + /** If the output requires monte carlo sampling, the amount of samples */ + sampleCount?: number; + /** The amount of points returned to draw the distribution */ + outputXYPoints?: number; + kernelWidth?: number; + pointDistLength?: number; + /** If the result is a function, where the function starts */ + diagramStart?: number; + /** If the result is a function, where the function ends */ + diagramStop?: number; + /** If the result is a function, how many points along the function it samples */ + diagramCount?: number; + /** when the environment changes. Used again for notebook magic*/ + onChange?(expr: bindings): void; + /** Previously declared variables */ + bindings?: bindings; + /** Variables imported from js */ + jsImports?: jsImports; + /** Whether to give users access to graph controls */ + showControls?: boolean; +} + +export let SquigglePartial: React.FC = ({ + initialSquiggleString = "", + onChange, + bindings = defaultBindings, + sampleCount = 1000, + outputXYPoints = 1000, + jsImports = defaultImports, +}: SquigglePartialProps) => { + let samplingInputs: samplingParams = { + sampleCount: sampleCount, + xyPointLength: outputXYPoints, + }; + let [expression, setExpression] = React.useState(initialSquiggleString); + let [error, setError] = React.useState(null); + + let runSquiggleAndUpdateBindings = () => { + let squiggleResult = runPartial( + expression, + bindings, + samplingInputs, + jsImports + ); + if (squiggleResult.tag == "Ok") { + if (onChange) onChange(squiggleResult.value); + setError(null); + } else { + setError(errorValueToString(squiggleResult.value)); + } + }; + + React.useEffect(runSquiggleAndUpdateBindings, [expression]); + + return ( +
+ + + + {error !== null ? {error} : <>} +
+ ); +}; + +export function renderSquigglePartialToDom(props: SquigglePartialProps) { + let parent = document.createElement("div"); + ReactDOM.render( + { + // @ts-ignore + parent.value = bindings; + + parent.dispatchEvent(new CustomEvent("input")); + if (props.onChange) props.onChange(bindings); + }} + />, + parent + ); + return parent; +} diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 93e8e9c6..424cff8d 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -1,11 +1,9 @@ import _ from "lodash"; -import React, { FC, useState } from "react"; +import React, { FC, ReactElement, useState } from "react"; import ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import CodeEditor from "./CodeEditor"; -import { Form, Input, Row, Col } from "antd"; import styled from "styled-components"; -import "antd/dist/antd.css"; interface FieldFloatProps { label: string; @@ -14,10 +12,19 @@ interface FieldFloatProps { onChange: (value: number) => void; } +const Input = styled.input``; + +const FormItem = (props: { label: string; children: ReactElement }) => ( +
+ + {props.children} +
+); + function FieldFloat(Props: FieldFloatProps) { let [contents, setContents] = useState(Props.value + ""); return ( - + - + ); } interface Props { initialSquiggleString?: string; height?: number; + showTypes?: boolean; + showControls?: boolean; } interface Props2 { @@ -48,10 +57,6 @@ const ShowBox = styled.div` height: ${(props) => props.height}; `; -const MyComponent = styled.div` - color: ${(props) => props.theme.colors.main}; -`; - interface TitleProps { readonly maxHeight: number; } @@ -65,9 +70,17 @@ const Display = styled.div` max-height: ${(props) => props.maxHeight}px; `; +const Row = styled.div` + display: grid; + grid-template-columns: 50% 50%; +`; +const Col = styled.div``; + let SquigglePlayground: FC = ({ initialSquiggleString = "", height = 300, + showTypes = false, + showControls = false, }: Props) => { let [squiggleString, setSquiggleString] = useState(initialSquiggleString); let [sampleCount, setSampleCount] = useState(1000); @@ -79,7 +92,7 @@ let SquigglePlayground: FC = ({ return ( - + = ({ height={height - 3} /> - + = ({ diagramCount={diagramCount} pointDistLength={pointDistLength} height={150} + showTypes={showTypes} + showControls={showControls} /> diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts index 364e6dcb..ffd9c8e0 100644 --- a/packages/components/src/index.ts +++ b/packages/components/src/index.ts @@ -1,7 +1,9 @@ export { SquiggleChart } from "./components/SquiggleChart"; export { SquiggleEditor, + SquigglePartial, renderSquiggleEditorToDom, + renderSquigglePartialToDom, } from "./components/SquiggleEditor"; import SquigglePlayground, { renderSquigglePlaygroundToDom, diff --git a/packages/components/src/stories/SquigglePartial.stories.mdx b/packages/components/src/stories/SquigglePartial.stories.mdx new file mode 100644 index 00000000..b4446402 --- /dev/null +++ b/packages/components/src/stories/SquigglePartial.stories.mdx @@ -0,0 +1,51 @@ +import { SquigglePartial, SquiggleEditor } from "../components/SquiggleEditor"; +import { useState } from "react"; +import { Canvas, Meta, Story, Props } from "@storybook/addon-docs"; + + + +export const Template = (props) => ; + +# Squiggle Partial + +A Squiggle Partial is an editor that does not return a graph to the user, but +instead returns bindings that can be used by further Squiggle Editors. + + + + {Template.bind({})} + + + + + + {(props) => { + let [bindings, setBindings] = useState({}); + return ( + <> + + + + ); + }} + + diff --git a/packages/components/src/vega-specs/spec-distributions.json b/packages/components/src/vega-specs/spec-distributions.json index ef30bdf2..5ca9576f 100644 --- a/packages/components/src/vega-specs/spec-distributions.json +++ b/packages/components/src/vega-specs/spec-distributions.json @@ -12,72 +12,8 @@ "name": "dis" } ], - "signals": [ - { - "name": "xscale", - "description": "The transform of the x scale", - "value": false, - "bind": { - "input": "checkbox", - "name": "log x scale" - } - }, - { - "name": "yscale", - "description": "The transform of the y scale", - "value": false, - "bind": { - "input": "checkbox", - "name": "log y scale" - } - } - ], - "scales": [ - { - "name": "xscale", - "type": "pow", - "exponent": { - "signal": "xscale ? 0.1 : 1" - }, - "range": "width", - "zero": false, - "nice": false, - "domain": { - "fields": [ - { - "data": "con", - "field": "x" - }, - { - "data": "dis", - "field": "x" - } - ] - } - }, - { - "name": "yscale", - "type": "pow", - "exponent": { - "signal": "yscale ? 0.1 : 1" - }, - "range": "height", - "nice": true, - "zero": true, - "domain": { - "fields": [ - { - "data": "con", - "field": "y" - }, - { - "data": "dis", - "field": "y" - } - ] - } - } - ], + "signals": [], + "scales": [], "axes": [ { "orient": "bottom", @@ -87,7 +23,7 @@ "tickOpacity": 0.0, "domainColor": "#fff", "domainOpacity": 0.0, - "format": "~s", + "format": "~g", "tickCount": 10 } ], diff --git a/packages/squiggle-lang/.npmignore b/packages/squiggle-lang/.npmignore index bfbe051d..2d3f13c3 100644 --- a/packages/squiggle-lang/.npmignore +++ b/packages/squiggle-lang/.npmignore @@ -2,7 +2,6 @@ node_modules shell.nix .cache .direnv -src __tests__ lib examples diff --git a/packages/squiggle-lang/README.md b/packages/squiggle-lang/README.md index fcd0c7a2..f6735454 100644 --- a/packages/squiggle-lang/README.md +++ b/packages/squiggle-lang/README.md @@ -1,6 +1,28 @@ +[![npm version](https://badge.fury.io/js/@quri%2Fsquiggle-lang.svg)](https://www.npmjs.com/package/@quri/squiggle-lang) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/quantified-uncertainty/squiggle/blob/develop/LICENSE) + # Squiggle language -## Build for development +_An estimation language_ + +# Use the `npm` package + +For instance, in a javascript project, you can + +```sh +yarn add @quri/squiggle-lang +``` + +```js +import { run } from "@quri/squiggle-lang"; +run( + "normal(0, 1) * fromSamples([-3,-2,-1,1,2,3,3,3,4,9]" +).value.value.toSparkline().value; +``` + +**However, for most use cases you'll prefer to use our [library of react components](https://www.npmjs.com/package/@quri/squiggle-components)**, and let your app transitively depend on `@quri/squiggle-lang`. + +# Build for development We assume that you ran `yarn` at the monorepo level. @@ -15,13 +37,16 @@ Other: ```sh yarn start # listens to files and recompiles at every mutation yarn test -yarn test:watch # keeps an active session and runs all tests at every mutation # where o := open in osx and o := xdg-open in linux, -yarn coverage; o _coverage/index.html # produces coverage report and opens it in browser +yarn coverage:rescript; o _coverage/index.html # produces coverage report and opens it in browser ``` -## Information +# Distributing this package or using this package from other monorepo packages + +As it says in the other `packages/*/README.md`s, building this package is an essential step of building other packages. + +# Information Squiggle is a language for representing probability distributions, as well as functions that return probability distributions. Its original intended use is for improving epistemics around EA decisions. @@ -34,11 +59,3 @@ This package is mainly written in [ReScript](https://rescript-lang.org/), but ha ReScript has an interesting philosophy of not providing much in the way of effective build tools. Every ReScript file is compiled into `.bs.js` and `.gen.ts` files with the same name and same location, and then you can use these files in other `.js` files to create your program. To generate these files to build the package, you run `yarn build`. `.gen.ts` files are created by the [`@genType`](https://rescript-lang.org/docs/gentype/latest/getting-started) decorator, which creates typescript typings for needed parts of the codebase so that they can be easily used in typescript. These .gen.ts files reference the .bs.js files generated by rescript. - -### Errors regarding the `rationale` package - -You may notice sometimes, that there are errors about the `rationale` package. If you ever get these errors, `yarn build` should fix this issue. These errors occur because `yarn build` also needs to create build files that are in `node_modules`. So if you replace `node_modules` you may need to rebuild to get those files back. - -## Distributing this package or using this package from other monorepo packages - -As it says in the other `packages/*/README.md`s, building this package is an essential step of building other packages. diff --git a/packages/squiggle-lang/__tests__/E/splitContinuousAndDiscrete_test.res b/packages/squiggle-lang/__tests__/E/splitContinuousAndDiscrete_test.res index 449787dd..a52227ee 100644 --- a/packages/squiggle-lang/__tests__/E/splitContinuousAndDiscrete_test.res +++ b/packages/squiggle-lang/__tests__/E/splitContinuousAndDiscrete_test.res @@ -2,7 +2,7 @@ open Jest open TestHelpers let prepareInputs = (ar, minWeight) => - E.A.Sorted.Floats.splitContinuousAndDiscreteForMinWeight(ar, ~minDiscreteWeight=minWeight) |> ( + E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight(ar, ~minDiscreteWeight=minWeight) |> ( ((c, disc)) => (c, disc |> E.FloatFloatMap.toArray) ) @@ -31,14 +31,14 @@ describe("Continuous and discrete splits", () => { E.A.concatMany([sorted, sorted, sorted, sorted]) |> Belt.SortArray.stableSortBy(_, compare) } - let (_, discrete1) = E.A.Sorted.Floats.splitContinuousAndDiscreteForMinWeight( + let (_, discrete1) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( makeDuplicatedArray(10), ~minDiscreteWeight=2, ) let toArr1 = discrete1 |> E.FloatFloatMap.toArray makeTest("splitMedium at count=10", toArr1 |> Belt.Array.length, 10) - let (_c, discrete2) = E.A.Sorted.Floats.splitContinuousAndDiscreteForMinWeight( + let (_c, discrete2) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( makeDuplicatedArray(500), ~minDiscreteWeight=2, ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res new file mode 100644 index 00000000..7bbc43dd --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res @@ -0,0 +1,142 @@ +open Jest +// open Expect + +open Reducer_Expression_ExpressionBuilder +open Reducer_TestMacroHelpers +module ExpressionT = Reducer_Expression_T + +let exampleExpression = eNumber(1.) +let exampleExpressionY = eSymbol("y") +let exampleStatementY = eLetStatement("y", eNumber(1.)) +let exampleStatementX = eLetStatement("y", eSymbol("x")) +let exampleStatementZ = eLetStatement("z", eSymbol("y")) + +// If it is not a macro then it is not expanded +testMacro([], exampleExpression, "Ok(1)") + +describe("bindStatement", () => { + // A statement is bound by the bindings created by the previous statement + testMacro([], eBindStatement(eBindings([]), exampleStatementY), "Ok((:$setBindings {} :y 1))") + // Then it answers the bindings for the next statement when reduced + testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok({y: 1})") + // Now let's feed a binding to see what happens + testMacro( + [], + eBindStatement(eBindings([("x", EvNumber(2.))]), exampleStatementX), + "Ok((:$setBindings {x: 2} :y 2))", + ) + // An expression does not return a binding, thus error + testMacro([], eBindStatement(eBindings([]), exampleExpression), "Error(Assignment expected)") + // When bindings from previous statement are missing the context is injected. This must be the first statement of a block + testMacro( + [("z", EvNumber(99.))], + eBindStatementDefault(exampleStatementY), + "Ok((:$setBindings {z: 99} :y 1))", + ) +}) + +describe("bindExpression", () => { + // x is simply bound in the expression + testMacro([], eBindExpression(eBindings([("x", EvNumber(2.))]), eSymbol("x")), "Ok(2)") + // When an let statement is the end expression then bindings are returned + testMacro( + [], + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY), + "Ok((:$exportBindings (:$setBindings {x: 2} :y 1)))", + ) + // Now let's reduce that expression + testMacroEval( + [], + eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY), + "Ok({x: 2,y: 1})", + ) + // When bindings are missing the context is injected. This must be the first and last statement of a block + testMacroEval( + [("z", EvNumber(99.))], + eBindExpressionDefault(exampleStatementY), + "Ok({y: 1,z: 99})", + ) +}) + +describe("block", () => { + // Block with a single expression + testMacro([], eBlock(list{exampleExpression}), "Ok((:$$bindExpression 1))") + testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") + // Block with a single statement + testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$bindExpression (:$let :y 1)))") + testMacroEval([], eBlock(list{exampleStatementY}), "Ok({y: 1})") + // Block with a statement and an expression + testMacro( + [], + eBlock(list{exampleStatementY, exampleExpressionY}), + "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) :y))", + ) + testMacroEval([], eBlock(list{exampleStatementY, exampleExpressionY}), "Ok(1)") + // Block with a statement and another statement + testMacro( + [], + eBlock(list{exampleStatementY, exampleStatementZ}), + "Ok((:$$bindExpression (:$$bindStatement (:$let :y 1)) (:$let :z :y)))", + ) + testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok({y: 1,z: 1})") + // Block inside a block + testMacro( + [], + eBlock(list{eBlock(list{exampleExpression})}), + "Ok((:$$bindExpression (:$$block 1)))", + ) + testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)") + // Block assigned to a variable + testMacro( + [], + eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), + "Ok((:$$bindExpression (:$let :z (:$$block (:$$block :y)))))", + ) + testMacroEval( + [], + eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), + "Ok({z: :y})", + ) + // Empty block + testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error + // :$$block (:$$block (:$let :y (:add :x 1)) :y)" + testMacro( + [], + eBlock(list{ + eBlock(list{ + eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), + eSymbol("y"), + }), + }), + "Ok((:$$bindExpression (:$$block (:$let :y (:add :x 1)) :y)))", + ) + MyOnly.testMacroEval( + [("x", EvNumber(1.))], + eBlock(list{ + eBlock(list{ + eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), + eSymbol("y"), + }), + }), + "Ok(2)", + ) +}) + +describe("lambda", () => { + // assign a lambda to a variable + let lambdaExpression = eFunction("$$lambda", list{eArrayString(["y"]), exampleExpressionY}) + testMacro([], lambdaExpression, "Ok(lambda(y=>internal))") + // call a lambda + let callLambdaExpression = list{lambdaExpression, eNumber(1.)}->ExpressionT.EList + testMacro([], callLambdaExpression, "Ok(((:$$lambda [y] :y) 1))") + testMacroEval([], callLambdaExpression, "Ok(1)") + // Parameters shadow the outer scope + testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(1)") + // When not shadowed by the parameters, the outer scope variables are available + let lambdaExpression = eFunction( + "$$lambda", + list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})}, + ) + let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) + testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(667)") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res new file mode 100644 index 00000000..f20d95f7 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Expression/Reducer_Expression_test.res @@ -0,0 +1,6 @@ +open Jest +open Expect + +test("dummy", () => { + expect(true)->toBe(true) +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res index 355c69ea..6f232d0e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res @@ -1,5 +1,5 @@ open ReducerInterface.ExpressionValue -module MathJs = Reducer.MathJs +module MathJs = Reducer_MathJs module ErrorValue = Reducer.ErrorValue open Jest diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res index 6282c14d..b6c8c290 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsParse_test.res @@ -1,4 +1,4 @@ -module Parse = Reducer.MathJs.Parse +module Parse = Reducer_MathJs.Parse module Result = Belt.Result open Jest @@ -18,8 +18,14 @@ module MySkip = { Skip.test(desc, () => expectParseToBe(expr, answer)) } +module MyOnly = { + let testParse = (expr, answer) => Only.test(expr, () => expectParseToBe(expr, answer)) + let testDescriptionParse = (desc, expr, answer) => + Only.test(desc, () => expectParseToBe(expr, answer)) +} + describe("MathJs parse", () => { - describe("literals operators paranthesis", () => { + describe("literals operators parenthesis", () => { testParse("1", "1") testParse("'hello'", "'hello'") testParse("true", "true") @@ -40,15 +46,15 @@ describe("MathJs parse", () => { }) describe("functions", () => { - MySkip.testParse("identity(x) = x", "???") - MySkip.testParse("identity(x)", "???") + testParse("identity(x) = x", "identity = (x) => x") + testParse("identity(x)", "identity(x)") }) describe("arrays", () => { testDescriptionParse("empty", "[]", "[]") testDescriptionParse("define", "[0, 1, 2]", "[0, 1, 2]") testDescriptionParse("define with strings", "['hello', 'world']", "['hello', 'world']") - MySkip.testParse("range(0, 4)", "range(0, 4)") + testParse("range(0, 4)", "range(0, 4)") testDescriptionParse("index", "([0,1,2])[1]", "([0, 1, 2])[1]") }) @@ -58,11 +64,11 @@ describe("MathJs parse", () => { }) describe("comments", () => { - MySkip.testDescriptionParse("define", "# This is a comment", "???") + testDescriptionParse("define", "1 # This is a comment", "1") }) - describe("if statement", () => { - // TODO Tertiary operator instead - MySkip.testDescriptionParse("define", "if (true) { 1 } else { 0 }", "???") + describe("ternary operator", () => { + testParse("1 ? 2 : 3", "ternary(1, 2, 3)") + testParse("1 ? 2 : 3 ? 4 : 5", "ternary(1, 2, ternary(3, 4, 5))") }) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 581f6c8a..766acd43 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,40 +1,31 @@ -module Expression = Reducer.Expression +module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue +module ErrorValue = Reducer_ErrorValue open Jest open Expect +let unwrapRecord = rValue => + rValue->Belt.Result.flatMap(value => + switch value { + | ExpressionValue.EvRecord(aRecord) => Ok(aRecord) + | _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error + } + ) + let expectParseToBe = (expr: string, answer: string) => - Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer) - -let expectParseOuterToBe = (expr: string, answer: string) => - Reducer.parseOuter(expr)->Expression.toStringResult->expect->toBe(answer) - -let expectParsePartialToBe = (expr: string, answer: string) => - Reducer.parsePartial(expr)->Expression.toStringResult->expect->toBe(answer) + Reducer.parse(expr)->ExpressionT.toStringResult->expect->toBe(answer) let expectEvalToBe = (expr: string, answer: string) => Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingExternalBindings(expr, bindings) + Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~environment=None) ->ExpressionValue.toStringResult ->expect ->toBe(answer) -let expectEvalPartialBindingsToBe = ( - expr: string, - bindings: Reducer.externalBindings, - answer: string, -) => - Reducer.evaluatePartialUsingExternalBindings(expr, bindings) - ->ExpressionValue.toStringResultRecord - ->expect - ->toBe(answer) - let testParseToBe = (expr, answer) => test(expr, () => expectParseToBe(expr, answer)) -let testParseOuterToBe = (expr, answer) => test(expr, () => expectParseOuterToBe(expr, answer)) -let testParsePartialToBe = (expr, answer) => test(expr, () => expectParsePartialToBe(expr, answer)) let testDescriptionParseToBe = (desc, expr, answer) => test(desc, () => expectParseToBe(expr, answer)) @@ -42,34 +33,16 @@ let testEvalToBe = (expr, answer) => test(expr, () => expectEvalToBe(expr, answe let testDescriptionEvalToBe = (desc, expr, answer) => test(desc, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) -let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - test(expr, () => expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) module MySkip = { let testParseToBe = (expr, answer) => Skip.test(expr, () => expectParseToBe(expr, answer)) - let testParseOuterToBe = (expr, answer) => - Skip.test(expr, () => expectParseOuterToBe(expr, answer)) - let testParsePartialToBe = (expr, answer) => - Skip.test(expr, () => expectParsePartialToBe(expr, answer)) let testEvalToBe = (expr, answer) => Skip.test(expr, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => Skip.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) - let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - Skip.test(expr, () => - expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer) - ) } module MyOnly = { let testParseToBe = (expr, answer) => Only.test(expr, () => expectParseToBe(expr, answer)) - let testParseOuterToBe = (expr, answer) => - Only.test(expr, () => expectParseOuterToBe(expr, answer)) - let testParsePartialToBe = (expr, answer) => - Only.test(expr, () => expectParsePartialToBe(expr, answer)) let testEvalToBe = (expr, answer) => Only.test(expr, () => expectEvalToBe(expr, answer)) let testEvalBindingsToBe = (expr, bindingsList, answer) => Only.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) - let testEvalPartialBindingsToBe = (expr, bindingsList, answer) => - Only.test(expr, () => - expectEvalPartialBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer) - ) } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res new file mode 100644 index 00000000..330f7da0 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -0,0 +1,82 @@ +open Jest +open Expect + +module Bindings = Reducer_Expression_Bindings +module Expression = Reducer_Expression +module ExpressionValue = ReducerInterface_ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext +module Macro = Reducer_Expression_Macro +module T = Reducer_Expression_T + +let testMacro_ = ( + tester, + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedCode: string, +) => { + let bindings = Belt.Map.String.fromArray(bindArray) + tester(expr->T.toString, () => + expr + ->Macro.expandMacroCall( + bindings, + ExpressionValue.defaultEnvironment, + Expression.reduceExpression, + ) + ->ExpressionWithContext.toStringResult + ->expect + ->toEqual(expectedCode) + ) +} + +let testMacroEval_ = ( + tester, + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, +) => { + let bindings = Belt.Map.String.fromArray(bindArray) + tester(expr->T.toString, () => + expr + ->Macro.doMacroCall(bindings, ExpressionValue.defaultEnvironment, Expression.reduceExpression) + ->ExpressionValue.toStringResult + ->expect + ->toEqual(expectedValue) + ) +} + +let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, +) => testMacro_(test, bindArray, expr, expectedExpr) +let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, +) => testMacroEval_(test, bindArray, expr, expectedValue) + +module MySkip = { + let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, + ) => testMacro_(Skip.test, bindArray, expr, expectedExpr) + let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, + ) => testMacroEval_(Skip.test, bindArray, expr, expectedValue) +} + +module MyOnly = { + let testMacro = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedExpr: string, + ) => testMacro_(Only.test, bindArray, expr, expectedExpr) + let testMacroEval = ( + bindArray: array<(string, ExpressionValue.expressionValue)>, + expr: T.expression, + expectedValue: string, + ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) +} diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res new file mode 100644 index 00000000..51efdbea --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_debugging_test.res @@ -0,0 +1,15 @@ +open Jest +open Reducer_TestHelpers + +/* + You can wrap around any expression with inspect(expr) to log the value of that expression. + This is useful for debugging. inspect(expr) returns the value of expr, but also prints it out. + + There is a second version of inspect that takes a label, which will print out the label and the value. + + inspectPerformace(expr, label) will print out the value of expr, the label, and the time it took to evaluate expr. +*/ +describe("Debugging", () => { + testEvalToBe("inspect(1)", "Ok(1)") + testEvalToBe("inspect(1, \"one\")", "Ok(1)") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res index ce834ed1..3a903343 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res @@ -1,60 +1,63 @@ +// TODO: Reimplement with usual parse open Jest open Reducer_TestHelpers -describe("Parse for Bindings", () => { - testParseOuterToBe("x", "Ok((:$$bindExpression (:$$bindings) :x))") - testParseOuterToBe("x+1", "Ok((:$$bindExpression (:$$bindings) (:add :x 1)))") - testParseOuterToBe( - "y = x+1; y", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) :y))", - ) -}) +// describe("Parse for Bindings", () => { +// testParseOuterToBe("x", "Ok((:$$bindExpression (:$$bindings) :x))") +// testParseOuterToBe("x+1", "Ok((:$$bindExpression (:$$bindings) (:add :x 1)))") +// testParseOuterToBe( +// "y = x+1; y", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) :y))", +// ) +// }) -describe("Parse Partial", () => { - testParsePartialToBe( - "x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) :x) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y=x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y :x)) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y=x+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$exportVariablesExpression)))", - ) - testParsePartialToBe( - "y = x+1; z = y", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$let :z :y)) (:$exportVariablesExpression)))", - ) -}) +// describe("Parse Partial", () => { +// testParsePartialToBe( +// "x", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) :x) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y=x", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y :x)) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y=x+1", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$exportVariablesExpression)))", +// ) +// testParsePartialToBe( +// "y = x+1; z = y", +// "Ok((:$$bindExpression (:$$bindStatement (:$$bindStatement (:$$bindings) (:$let :y (:add :x 1))) (:$let :z :y)) (:$exportVariablesExpression)))", +// ) +// }) describe("Eval with Bindings", () => { testEvalBindingsToBe("x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(1)") testEvalBindingsToBe("x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(2)") + testParseToBe("y = x+1; y", "Ok((:$$block (:$$block (:$let :y (:add :x 1)) :y)))") testEvalBindingsToBe("y = x+1; y", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(2)") + testEvalBindingsToBe("y = x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1,y: 2})") }) /* Partial code is a partial code fragment that is cut out from a larger code. Therefore it does not end with an expression. */ -describe("Eval Partial", () => { - testEvalPartialBindingsToBe( - // A partial cannot end with an expression - "x", - list{("x", ExpressionValue.EvNumber(1.))}, - "Error(Assignment expected)", - ) - testEvalPartialBindingsToBe("y=x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1, y: 1})") - testEvalPartialBindingsToBe( - "y=x+1", - list{("x", ExpressionValue.EvNumber(1.))}, - "Ok({x: 1, y: 2})", - ) - testEvalPartialBindingsToBe( - "y = x+1; z = y", - list{("x", ExpressionValue.EvNumber(1.))}, - "Ok({x: 1, y: 2, z: 2})", - ) -}) +// describe("Eval Partial", () => { +// testEvalPartialBindingsToBe( +// // A partial cannot end with an expression +// "x", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Error(Assignment expected)", +// ) +// testEvalPartialBindingsToBe("y=x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1,y: 1})") +// testEvalPartialBindingsToBe( +// "y=x+1", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Ok({x: 1,y: 2})", +// ) +// testEvalPartialBindingsToBe( +// "y = x+1; z = y", +// list{("x", ExpressionValue.EvNumber(1.))}, +// "Ok({x: 1,y: 2,z: 2})", +// ) +// }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res new file mode 100644 index 00000000..bb3e2220 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -0,0 +1,12 @@ +open Jest +open Reducer_TestHelpers + +describe("Parse function assignment", () => { + testParseToBe("f(x)=x", "Ok((:$$block (:$let :f (:$$lambda [x] (:$$block :x)))))") + testParseToBe("f(x)=2*x", "Ok((:$$block (:$let :f (:$$lambda [x] (:$$block (:multiply 2 :x))))))") + //MathJs does not allow blocks in function definitions +}) + +describe("Evaluate function assignment", () => { + testEvalToBe("f(x)=x; f(1)", "Ok(1)") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res new file mode 100644 index 00000000..d9f7e7c8 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -0,0 +1,77 @@ +open Jest +open Reducer_TestHelpers + +describe("Arity check", () => { + testEvalToBe("f(x,y) = x + y; f(1,2)", "Ok(3)") + testEvalToBe( + "f(x,y) = x + y; f(1)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y) = x + y; f(1,2,3)", + "Error(2 arguments expected. Instead 3 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x+y; f(1,2,3,4)", + "Error(2 arguments expected. Instead 4 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x+y; f(1)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe( + "f(x,y)=x(y); f(f)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) + testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") + testEvalToBe( + "f(x,y)=x(y); f(z)", + "Error(2 arguments expected. Instead 1 argument(s) were passed.)", + ) +}) + +describe("symbol not defined", () => { + testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") + testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") + testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") + testEvalToBe("f(x)=x(y); f(2)", "Error(2 is not a function)") + testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") +}) + +describe("call and bindings", () => { + testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})") + testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") + testEvalToBe("f=1;y=2", "Ok({f: 1,y: 2})") + testEvalToBe("f(x)=x+1; y=f(1)", "Ok({f: lambda(x=>internal code),y: 2})") + testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") + testEvalToBe("f(x)=x+1; y=f(1); z=f(1)", "Ok({f: lambda(x=>internal code),y: 2,z: 2})") + testEvalToBe( + "f(x)=x+1; g(x)=f(x)+1", + "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code)})", + ) + testParseToBe( + "f=99; g(x)=f; g(2)", + "Ok((:$$block (:$$block (:$let :f 99) (:$let :g (:$$lambda [x] (:$$block :f))) (:g 2))))", + ) + testEvalToBe("f=99; g(x)=f; g(2)", "Ok(99)") + testEvalToBe("f(x)=x; g(x)=f(x); g(2)", "Ok(2)") + testEvalToBe( + "f(x)=x+1; g(x)=f(x)+1; y=g(2)", + "Ok({f: lambda(x=>internal code),g: lambda(x=>internal code),y: 4})", + ) + testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)") +}) + +describe("function tricks", () => { + testParseToBe( + "f(x)=f(y)=2; f(2)", + "Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))", + ) + testEvalToBe("f(x)=f(y)=2; f(2)", "Ok({f: lambda(y=>internal code),x: 2})") + testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") + testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok({g: lambda(x=>internal code),y: 2})") + MySkip.testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? + MySkip.testEvalToBe("f(x, x)=x+x; f(1,2)", "????") // TODO: Duplicate parameters + MySkip.testEvalToBe("myadd(x,y)=x+y; z=[add]; z[0](3,2)", "????") //TODO: to fix with new parser + MySkip.testEvalToBe("myaddd(x,y)=x+y; z={x: add}; z.x(3,2)", "????") //TODO: to fix with new parser +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res new file mode 100644 index 00000000..5414f827 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -0,0 +1,16 @@ +open Jest +open Reducer_TestHelpers + +describe("map reduce", () => { + testEvalToBe("double(x)=2*x; arr=[1,2,3]; map(arr, double)", "Ok([2,4,6])") + testEvalToBe("myadd(acc,x)=acc+x; arr=[1,2,3]; reduce(arr, 0, myadd)", "Ok(6)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduce(arr, 0, change)", "Ok(15)") + testEvalToBe("change(acc,x)=acc*x+x; arr=[1,2,3]; reduceReverse(arr, 0, change)", "Ok(9)") + testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])") + testEvalToBe("check(x)=(x==2);arr=[1,2,3]; keep(arr,check)", "Ok([2])") +}) + +Skip.describe("map reduce (sam)", () => { + testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???") + testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 61bfc8c7..c0311450 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -1,12 +1,14 @@ open Jest open Reducer_TestHelpers -Skip.describe("Parse ternary operator", () => { - testParseToBe("true ? 'YES' : 'NO'", "Ok('YES')") - testParseToBe("false ? 'YES' : 'NO'", "Ok('NO')") +describe("Parse ternary operator", () => { + testParseToBe("true ? 'YES' : 'NO'", "Ok((:$$block (:$$ternary true 'YES' 'NO')))") }) -Skip.describe("Evaluate ternary operator", () => { +describe("Evaluate ternary operator", () => { testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')") testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')") + testEvalToBe("2 > 1 ? 'YES' : 'NO'", "Ok('YES')") + testEvalToBe("2 <= 1 ? 'YES' : 'NO'", "Ok('NO')") + testEvalToBe("1+1 ? 'YES' : 'NO'", "Error(Expected type: Boolean)") }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index 5514b67c..80468c0f 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -10,46 +10,39 @@ describe("reducer using mathjs parse", () => { // Those tests toString that we are converting mathjs parse tree to what we need describe("expressions", () => { - testParseToBe("1", "Ok(1)") - testParseToBe("(1)", "Ok(1)") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2", "Ok((:add 1 2))") - testParseToBe("1+2*3", "Ok((:add 1 (:multiply 2 3)))") + testParseToBe("1", "Ok((:$$block 1))") + testParseToBe("(1)", "Ok((:$$block 1))") + testParseToBe("1+2", "Ok((:$$block (:add 1 2)))") + testParseToBe("1+2*3", "Ok((:$$block (:add 1 (:multiply 2 3))))") }) describe("arrays", () => { //Note. () is a empty list in Lisp // The only builtin structure in Lisp is list. There are no arrays // [1,2,3] becomes (1 2 3) - testDescriptionParseToBe("empty", "[]", "Ok(())") - testParseToBe("[1, 2, 3]", "Ok((1 2 3))") - testParseToBe("['hello', 'world']", "Ok(('hello' 'world'))") - testDescriptionParseToBe("index", "([0,1,2])[1]", "Ok((:$atIndex (0 1 2) (1)))") + testDescriptionParseToBe("empty", "[]", "Ok((:$$block ()))") + testParseToBe("[1, 2, 3]", "Ok((:$$block (1 2 3)))") + testParseToBe("['hello', 'world']", "Ok((:$$block ('hello' 'world')))") + testDescriptionParseToBe("index", "([0,1,2])[1]", "Ok((:$$block (:$atIndex (0 1 2) (1))))") }) describe("records", () => { - testDescriptionParseToBe("define", "{a: 1, b: 2}", "Ok((:$constructRecord (('a' 1) ('b' 2))))") + testDescriptionParseToBe( + "define", + "{a: 1, b: 2}", + "Ok((:$$block (:$constructRecord (('a' 1) ('b' 2)))))", + ) testDescriptionParseToBe( "use", "{a: 1, b: 2}.a", - "Ok((:$atIndex (:$constructRecord (('a' 1) ('b' 2))) ('a')))", + "Ok((:$$block (:$atIndex (:$constructRecord (('a' 1) ('b' 2))) ('a'))))", ) }) describe("multi-line", () => { - testParseToBe("1; 2", "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) 1) 2))") - testParseToBe( - "1+1; 2+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:add 1 1)) (:add 2 1)))", - ) + testParseToBe("1; 2", "Ok((:$$block (:$$block 1 2)))") + testParseToBe("1+1; 2+1", "Ok((:$$block (:$$block (:add 1 1) (:add 2 1))))") }) describe("assignment", () => { - testParseToBe( - "x=1; x", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x 1)) :x))", - ) - testParseToBe( - "x=1+1; x+1", - "Ok((:$$bindExpression (:$$bindStatement (:$$bindings) (:$let :x (:add 1 1))) (:add :x 1)))", - ) + testParseToBe("x=1; x", "Ok((:$$block (:$$block (:$let :x 1) :x)))") + testParseToBe("x=1+1; x+1", "Ok((:$$block (:$$block (:$let :x (:add 1 1)) (:add :x 1))))") }) }) @@ -70,13 +63,13 @@ describe("eval", () => { }) describe("arrays", () => { test("empty array", () => expectEvalToBe("[]", "Ok([])")) - testEvalToBe("[1, 2, 3]", "Ok([1, 2, 3])") - testEvalToBe("['hello', 'world']", "Ok(['hello', 'world'])") + testEvalToBe("[1, 2, 3]", "Ok([1,2,3])") + testEvalToBe("['hello', 'world']", "Ok(['hello','world'])") testEvalToBe("([0,1,2])[1]", "Ok(1)") testDescriptionEvalToBe("index not found", "([0,1,2])[10]", "Error(Array index not found: 10)") }) describe("records", () => { - test("define", () => expectEvalToBe("{a: 1, b: 2}", "Ok({a: 1, b: 2})")) + test("define", () => expectEvalToBe("{a: 1, b: 2}", "Ok({a: 1,b: 2})")) test("index", () => expectEvalToBe("{a: 1}.a", "Ok(1)")) test("index not found", () => expectEvalToBe("{a: 1}.b", "Error(Record property not found: b)")) }) @@ -91,7 +84,7 @@ describe("eval", () => { testEvalToBe("x=1; y=x+1; y+1", "Ok(3)") testEvalToBe("1; x=1", "Error(Assignment expected)") testEvalToBe("1; 1", "Error(Assignment expected)") - testEvalToBe("x=1; x=1", "Error(Expression expected)") + testEvalToBe("x=1; x=1", "Ok({x: 1})") }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 4df843bb..571a838b 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -30,6 +30,7 @@ describe("eval on distribution functions", () => { describe("mean", () => { testEval("mean(normal(5,2))", "Ok(5)") testEval("mean(lognormal(1,2))", "Ok(20.085536923187668)") + testEval("mean(gamma(5,5))", "Ok(25)") }) describe("toString", () => { testEval("toString(normal(5,2))", "Ok('Normal(5,2)')") @@ -119,27 +120,34 @@ describe("eval on distribution functions", () => { describe("parse on distribution functions", () => { describe("power", () => { - testParse("normal(5,2) ^ normal(5,1)", "Ok((:pow (:normal 5 2) (:normal 5 1)))") - testParse("3 ^ normal(5,1)", "Ok((:pow 3 (:normal 5 1)))") - testParse("normal(5,2) ^ 3", "Ok((:pow (:normal 5 2) 3))") + testParse("normal(5,2) ^ normal(5,1)", "Ok((:$$block (:pow (:normal 5 2) (:normal 5 1))))") + testParse("3 ^ normal(5,1)", "Ok((:$$block (:pow 3 (:normal 5 1))))") + testParse("normal(5,2) ^ 3", "Ok((:$$block (:pow (:normal 5 2) 3)))") }) describe("subtraction", () => { - testParse("10 - normal(5,1)", "Ok((:subtract 10 (:normal 5 1)))") - testParse("normal(5,1) - 10", "Ok((:subtract (:normal 5 1) 10))") + testParse("10 - normal(5,1)", "Ok((:$$block (:subtract 10 (:normal 5 1))))") + testParse("normal(5,1) - 10", "Ok((:$$block (:subtract (:normal 5 1) 10)))") }) describe("pointwise arithmetic expressions", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") testParse( ~skip=true, "normal(5,2) .- normal(5,1)", - "Ok((:dotSubtract (:normal 5 2) (:normal 5 1)))", + "Ok((:$$block (:dotSubtract (:normal 5 2) (:normal 5 1))))", + // TODO: !!! returns "Ok((:$$block (:dotPow (:normal 5 2) (:normal 5 1))))" ) - testParse("normal(5,2) .* normal(5,1)", "Ok((:dotMultiply (:normal 5 2) (:normal 5 1)))") - testParse("normal(5,2) ./ normal(5,1)", "Ok((:dotDivide (:normal 5 2) (:normal 5 1)))") - testParse("normal(5,2) .^ normal(5,1)", "Ok((:dotPow (:normal 5 2) (:normal 5 1)))") + testParse( + "normal(5,2) .* normal(5,1)", + "Ok((:$$block (:dotMultiply (:normal 5 2) (:normal 5 1))))", + ) + testParse( + "normal(5,2) ./ normal(5,1)", + "Ok((:$$block (:dotDivide (:normal 5 2) (:normal 5 1))))", + ) + testParse("normal(5,2) .^ normal(5,1)", "Ok((:$$block (:dotPow (:normal 5 2) (:normal 5 1))))") }) describe("equality", () => { - testParse("5 == normal(5,2)", "Ok((:equal 5 (:normal 5 2)))") + testParse("5 == normal(5,2)", "Ok((:$$block (:equal 5 (:normal 5 2))))") }) describe("pointwise adding two normals", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res index fc2d555e..888aca7e 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res @@ -3,9 +3,9 @@ open Jest open Expect describe("ExpressionValue", () => { - test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1, 'a'")) + test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1,'a'")) test("toStringFunctionCall", () => - expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1, 'a')") + expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1,'a')") ) }) diff --git a/packages/squiggle-lang/__tests__/TS/JS_test.ts b/packages/squiggle-lang/__tests__/TS/JS_test.ts index 1974dee6..76871fc8 100644 --- a/packages/squiggle-lang/__tests__/TS/JS_test.ts +++ b/packages/squiggle-lang/__tests__/TS/JS_test.ts @@ -1,23 +1,5 @@ -import { - run, - Distribution, - resultMap, - squiggleExpression, - errorValueToString, -} from "../../src/js/index"; - -let testRun = (x: string): squiggleExpression => { - let result = run(x, { sampleCount: 100, xyPointLength: 100 }); - expect(result.tag).toEqual("Ok"); - if (result.tag === "Ok") { - return result.value; - } else { - throw Error( - "Expected squiggle expression to evaluate but got error: " + - errorValueToString(result.value) - ); - } -}; +import { Distribution, resultMap, defaultBindings } from "../../src/js/index"; +import { testRun, testRunPartial } from "./TestHelpers"; function Ok(x: b) { return { tag: "Ok", value: x }; @@ -42,6 +24,72 @@ describe("Log function", () => { }); }); +describe("Array", () => { + test("nested Array", () => { + expect(testRun("[[1]]")).toEqual({ + tag: "array", + value: [ + { + tag: "array", + value: [ + { + tag: "number", + value: 1, + }, + ], + }, + ], + }); + }); +}); + +describe("Record", () => { + test("Return record", () => { + expect(testRun("{a: 1}")).toEqual({ + tag: "record", + value: { + a: { + tag: "number", + value: 1, + }, + }, + }); + }); +}); + +describe("Partials", () => { + test("Can pass variables between partials and cells", () => { + let bindings = testRunPartial(`x = 5`); + let bindings2 = testRunPartial(`y = x + 2`, bindings); + expect(testRun(`y + 3`, bindings2)).toEqual({ + tag: "number", + value: 10, + }); + }); +}); + +describe("JS Imports", () => { + test("Can pass parameters into partials and cells", () => { + let bindings = testRunPartial(`y = $x + 2`, defaultBindings, { x: 1 }); + let bindings2 = testRunPartial(`z = y + $a`, bindings, { a: 3 }); + expect(testRun(`z`, bindings2)).toEqual({ + tag: "number", + value: 6, + }); + }); + test("Complicated deep parameters", () => { + expect( + testRun(`$x.y[0][0].w + $x.z + $u.v`, defaultBindings, { + x: { y: [[{ w: 1 }]], z: 2 }, + u: { v: 3 }, + }) + ).toEqual({ + tag: "number", + value: 6, + }); + }); +}); + describe("Distribution", () => { //It's important that sampleCount is less than 9. If it's more, than that will create randomness //Also, note, the value should be created using makeSampleSetDist() later on. diff --git a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts index a617010b..2c77e210 100644 --- a/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts +++ b/packages/squiggle-lang/__tests__/TS/SampleSet_test.ts @@ -1,5 +1,5 @@ import { Distribution } from "../../src/js/index"; -import { expectErrorToBeBounded, failDefault } from "./TestHelpers"; +import { expectErrorToBeBounded, failDefault, testRun } from "./TestHelpers"; import * as fc from "fast-check"; // Beware: float64Array makes it appear in an infinite loop. @@ -212,3 +212,18 @@ describe("mean is mean", () => { ); }); }); + +describe("fromSamples function", () => { + test.skip("gives a mean near the mean of the input", () => { + fc.assert( + fc.property(arrayGen(), (xs_) => { + let xs = Array.from(xs_); + let xsString = xs.toString(); + let squiggleString = `x = fromSamples([${xsString}]); mean(x)`; + let squiggleResult = testRun(squiggleString); + let mean = xs.reduce((a, b) => a + b, 0.0) / xs.length; + expect(squiggleResult.value).toBeCloseTo(mean, 4); + }) + ); + }); +}); diff --git a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts index 3d4153ef..d9d8444f 100644 --- a/packages/squiggle-lang/__tests__/TS/TestHelpers.ts +++ b/packages/squiggle-lang/__tests__/TS/TestHelpers.ts @@ -1,15 +1,53 @@ import { run, - // Distribution, + runPartial, + bindings, squiggleExpression, errorValueToString, - // errorValue, - // result, + defaultImports, + defaultBindings, + jsImports, } from "../../src/js/index"; -export function testRun(x: string): squiggleExpression { - let squiggleResult = run(x, { sampleCount: 1000, xyPointLength: 100 }); - // return squiggleResult.value +export function testRun( + x: string, + bindings: bindings = defaultBindings, + imports: jsImports = defaultImports +): squiggleExpression { + let squiggleResult = run( + x, + bindings, + { + sampleCount: 1000, + xyPointLength: 100, + }, + imports + ); + if (squiggleResult.tag === "Ok") { + return squiggleResult.value; + } else { + throw new Error( + `Expected squiggle expression to evaluate but got error: ${errorValueToString( + squiggleResult.value + )}` + ); + } +} + +export function testRunPartial( + x: string, + bindings: bindings = defaultBindings, + imports: jsImports = defaultImports +): bindings { + let squiggleResult = runPartial( + x, + bindings, + { + sampleCount: 1000, + xyPointLength: 100, + }, + imports + ); if (squiggleResult.tag === "Ok") { return squiggleResult.value; } else { diff --git a/packages/squiggle-lang/__tests__/XYShape_test.res b/packages/squiggle-lang/__tests__/XYShape_test.res index 701d82e1..38535020 100644 --- a/packages/squiggle-lang/__tests__/XYShape_test.res +++ b/packages/squiggle-lang/__tests__/XYShape_test.res @@ -18,7 +18,26 @@ let pointSetDist3: PointSetTypes.xyShape = { ys: [0.2, 0.5, 0.8], } +let makeAndGetErrorString = (~xs, ~ys) => + XYShape.T.make(~xs, ~ys)->E.R.getError->E.O2.fmap(XYShape.Error.toString) + describe("XYShapes", () => { + describe("Validator", () => { + makeTest( + "with no errors", + makeAndGetErrorString(~xs=[1.0, 4.0, 8.0], ~ys=[0.2, 0.4, 0.8]), + None, + ) + makeTest("when empty", makeAndGetErrorString(~xs=[], ~ys=[]), Some("Xs is empty")) + makeTest( + "when not sorted, different lengths, and not finite", + makeAndGetErrorString(~xs=[2.0, 1.0, infinity, 0.0], ~ys=[3.0, Js.Float._NaN]), + Some( + "Multiple Errors: [Xs is not sorted], [Xs and Ys have different lengths. Xs has length 4 and Ys has length 2], [Xs is not finite. Example value: Infinity], [Ys is not finite. Example value: NaN]", + ), + ) + }) + describe("logScorePoint", () => { makeTest("When identical", XYShape.logScorePoint(30, pointSetDist1, pointSetDist1), Some(0.0)) makeTest( @@ -32,16 +51,6 @@ describe("XYShapes", () => { Some(210.3721280423322), ) }) - // describe("transverse", () => { - // makeTest( - // "When very different", - // XYShape.Transversal._transverse( - // (aCurrent, aLast) => aCurrent +. aLast, - // [|1.0, 2.0, 3.0, 4.0|], - // ), - // [|1.0, 3.0, 6.0, 10.0|], - // ) - // }); describe("integrateWithTriangles", () => makeTest( "integrates correctly", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 75583bfc..97b710b6 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,13 +1,15 @@ { "name": "@quri/squiggle-lang", - "version": "0.2.5", + "version": "0.2.8", "homepage": "https://squiggle-language.com", - "licence": "MIT", + "license": "MIT", "scripts": { - "build": "rescript build -with-deps", + "build": "yarn build:rescript && yarn build:typescript", + "build:rescript": "rescript build -with-deps", + "build:typescript": "tsc", "bundle": "webpack", "start": "rescript build -w -with-deps", - "clean": "rescript clean", + "clean": "rescript clean && rm -r dist", "test:reducer": "jest __tests__/Reducer*/", "benchmark": "ts-node benchmark/conversion_tests.ts", "test": "jest", @@ -24,6 +26,7 @@ "format:rescript": "rescript format -all", "format:prettier": "prettier --write .", "format": "yarn format:rescript && yarn format:prettier", + "prepack": "yarn build && yarn test && yarn bundle", "all": "yarn build && yarn bundle && yarn test" }, "keywords": [ @@ -31,34 +34,36 @@ ], "author": "Quantified Uncertainty Research Institute", "license": "MIT", + "dependencies": { + "rescript": "^9.1.4", + "jstat": "^1.9.5", + "pdfast": "^0.2.0", + "mathjs": "^10.5.0" + }, "devDependencies": { "bisect_ppx": "^2.7.1", - "jstat": "^1.9.5", - "lodash": "4.17.21", - "rescript": "^9.1.4", + "lodash": "^4.17.21", "rescript-fast-check": "^1.1.1", "@glennsl/rescript-jest": "^0.9.0", "@istanbuljs/nyc-config-typescript": "^1.0.2", - "@types/jest": "^27.4.0", + "@types/jest": "^27.5.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "chalk": "^5.0.1", - "codecov": "3.8.3", - "fast-check": "2.25.0", + "codecov": "^3.8.3", + "fast-check": "^2.25.0", "gentype": "^4.3.0", "jest": "^27.5.1", - "mathjs": "10.5.0", - "moduleserve": "0.9.1", + "moduleserve": "^0.9.1", "nyc": "^15.1.0", - "pdfast": "^0.2.0", "reanalyze": "^2.19.0", "ts-jest": "^27.1.4", - "ts-loader": "^9.2.8", + "ts-loader": "^9.3.0", "ts-node": "^10.7.0", "typescript": "^4.6.3", "webpack": "^5.72.0", "webpack-cli": "^4.9.2" }, "source": "./src/js/index.ts", - "main": "./dist/bundle.js", - "types": "./dist/js/index.d.ts" + "main": "./dist/src/js/index.js", + "types": "./dist/src/js/index.d.ts" } diff --git a/packages/squiggle-lang/src/js/distribution.ts b/packages/squiggle-lang/src/js/distribution.ts new file mode 100644 index 00000000..44c15882 --- /dev/null +++ b/packages/squiggle-lang/src/js/distribution.ts @@ -0,0 +1,247 @@ +import * as _ from "lodash"; +import { + genericDist, + continuousShape, + discreteShape, + environment, + distributionError, + toPointSet, + distributionErrorToString, +} from "../rescript/TypescriptInterface.gen"; +import { result, resultMap, Ok } from "./types"; +import { + Constructors_mean, + Constructors_sample, + Constructors_pdf, + Constructors_cdf, + Constructors_inv, + Constructors_normalize, + Constructors_isNormalized, + Constructors_toPointSet, + Constructors_toSampleSet, + Constructors_truncate, + Constructors_inspect, + Constructors_toString, + Constructors_toSparkline, + Constructors_algebraicAdd, + Constructors_algebraicMultiply, + Constructors_algebraicDivide, + Constructors_algebraicSubtract, + Constructors_algebraicLogarithm, + Constructors_algebraicPower, + Constructors_pointwiseAdd, + Constructors_pointwiseMultiply, + Constructors_pointwiseDivide, + Constructors_pointwiseSubtract, + Constructors_pointwiseLogarithm, + Constructors_pointwisePower, +} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; + +export type point = { x: number; y: number }; + +function shapePoints(x: continuousShape | discreteShape): point[] { + let xs = x.xyShape.xs; + let ys = x.xyShape.ys; + return _.zipWith(xs, ys, (x, y) => ({ x, y })); +} +export type shape = { + continuous: point[]; + discrete: point[]; +}; + +export class Distribution { + t: genericDist; + env: environment; + + constructor(t: genericDist, env: environment) { + this.t = t; + this.env = env; + return this; + } + + mapResultDist( + r: result + ): result { + return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); + } + + mean(): result { + return Constructors_mean({ env: this.env }, this.t); + } + + sample(): result { + return Constructors_sample({ env: this.env }, this.t); + } + + pdf(n: number): result { + return Constructors_pdf({ env: this.env }, this.t, n); + } + + cdf(n: number): result { + return Constructors_cdf({ env: this.env }, this.t, n); + } + + inv(n: number): result { + return Constructors_inv({ env: this.env }, this.t, n); + } + + isNormalized(): result { + return Constructors_isNormalized({ env: this.env }, this.t); + } + + normalize(): result { + return this.mapResultDist( + Constructors_normalize({ env: this.env }, this.t) + ); + } + + type() { + return this.t.tag; + } + + pointSet(): result { + let pointSet = toPointSet( + this.t, + { + xyPointLength: this.env.xyPointLength, + sampleCount: this.env.sampleCount, + }, + undefined + ); + if (pointSet.tag === "Ok") { + let distribution = pointSet.value; + if (distribution.tag === "Continuous") { + return Ok({ + continuous: shapePoints(distribution.value), + discrete: [], + }); + } else if (distribution.tag === "Discrete") { + return Ok({ + discrete: shapePoints(distribution.value), + continuous: [], + }); + } else { + return Ok({ + discrete: shapePoints(distribution.value.discrete), + continuous: shapePoints(distribution.value.continuous), + }); + } + } else { + return pointSet; + } + } + + toPointSet(): result { + return this.mapResultDist( + Constructors_toPointSet({ env: this.env }, this.t) + ); + } + + toSampleSet(n: number): result { + return this.mapResultDist( + Constructors_toSampleSet({ env: this.env }, this.t, n) + ); + } + + truncate( + left: number, + right: number + ): result { + return this.mapResultDist( + Constructors_truncate({ env: this.env }, this.t, left, right) + ); + } + + inspect(): result { + return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); + } + + toString(): string { + let result = Constructors_toString({ env: this.env }, this.t); + if (result.tag === "Ok") { + return result.value; + } else { + return distributionErrorToString(result.value); + } + } + + toSparkline(n: number): result { + return Constructors_toSparkline({ env: this.env }, this.t, n); + } + + algebraicAdd(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) + ); + } + + algebraicMultiply(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) + ); + } + + algebraicDivide(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) + ); + } + + algebraicSubtract(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) + ); + } + + algebraicLogarithm( + d2: Distribution + ): result { + return this.mapResultDist( + Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) + ); + } + + algebraicPower(d2: Distribution): result { + return this.mapResultDist( + Constructors_algebraicPower({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseAdd(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseMultiply(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseDivide(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseSubtract(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) + ); + } + + pointwiseLogarithm( + d2: Distribution + ): result { + return this.mapResultDist( + Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) + ); + } + + pointwisePower(d2: Distribution): result { + return this.mapResultDist( + Constructors_pointwisePower({ env: this.env }, this.t, d2.t) + ); + } +} diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 6ff022e0..589548e3 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,346 +1,159 @@ import * as _ from "lodash"; import { - genericDist, samplingParams, - evaluate, + environment, + defaultEnvironment, + evaluatePartialUsingExternalBindings, + evaluateUsingOptions, + externalBindings, expressionValue, errorValue, - distributionError, - toPointSet, - continuousShape, - discreteShape, - distributionErrorToString, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, errorValueToString, distributionErrorToString, + distributionError, } from "../rescript/TypescriptInterface.gen"; +export type { + samplingParams, + errorValue, + externalBindings as bindings, + jsImports, +}; import { - Constructors_mean, - Constructors_sample, - Constructors_pdf, - Constructors_cdf, - Constructors_inv, - Constructors_normalize, - Constructors_isNormalized, - Constructors_toPointSet, - Constructors_toSampleSet, - Constructors_truncate, - Constructors_inspect, - Constructors_toString, - Constructors_toSparkline, - Constructors_algebraicAdd, - Constructors_algebraicMultiply, - Constructors_algebraicDivide, - Constructors_algebraicSubtract, - Constructors_algebraicLogarithm, - Constructors_algebraicPower, - Constructors_pointwiseAdd, - Constructors_pointwiseMultiply, - Constructors_pointwiseDivide, - Constructors_pointwiseSubtract, - Constructors_pointwiseLogarithm, - Constructors_pointwisePower, -} from "../rescript/Distributions/DistributionOperation/DistributionOperation.gen"; -export type { samplingParams, errorValue }; + jsValueToBinding, + jsValue, + rescriptExport, + squiggleExpression, + convertRawToTypescript, +} from "./rescript_interop"; +import { result, resultMap, tag, tagged } from "./types"; +import { Distribution, shape } from "./distribution"; + +export { Distribution, squiggleExpression, result, resultMap, shape }; export let defaultSamplingInputs: samplingParams = { sampleCount: 10000, xyPointLength: 10000, }; -export type result = - | { - tag: "Ok"; - value: a; - } - | { - tag: "Error"; - value: b; - }; - -export function resultMap( - r: result, - mapFn: (x: a) => b -): result { - if (r.tag === "Ok") { - return { tag: "Ok", value: mapFn(r.value) }; - } else { - return r; - } -} - -function Ok(x: a): result { - return { tag: "Ok", value: x }; -} - -type tagged = { tag: a; value: b }; - -function tag(x: a, y: b): tagged { - return { tag: x, value: y }; -} - -export type squiggleExpression = - | tagged<"symbol", string> - | tagged<"string", string> - | tagged<"call", string> - | tagged<"array", squiggleExpression[]> - | tagged<"boolean", boolean> - | tagged<"distribution", Distribution> - | tagged<"number", number> - | tagged<"record", { [key: string]: squiggleExpression }>; export function run( squiggleString: string, - samplingInputs?: samplingParams + bindings?: externalBindings, + environment?: environment, + imports?: jsImports ): result { - let si: samplingParams = samplingInputs - ? samplingInputs - : defaultSamplingInputs; - let result: result = evaluate(squiggleString); - return resultMap(result, (x) => createTsExport(x, si)); + let b = bindings ? bindings : defaultBindings; + let i = imports ? imports : defaultImports; + let e = environment ? environment : defaultEnvironment; + let res: result = evaluateUsingOptions( + { externalBindings: mergeImports(b, i), environment: e }, + squiggleString + ); + return resultMap(res, (x) => createTsExport(x, e)); } +// Run Partial. A partial is a block of code that doesn't return a value +export function runPartial( + squiggleString: string, + bindings?: externalBindings, + environment?: environment, + imports?: jsImports +): result { + let b = bindings ? bindings : defaultBindings; + let i = imports ? imports : defaultImports; + let e = environment ? environment : defaultEnvironment; + + return evaluatePartialUsingExternalBindings( + squiggleString, + mergeImports(b, i), + e + ); +} + +function mergeImports( + bindings: externalBindings, + imports: jsImports +): externalBindings { + let transformedImports = Object.fromEntries( + Object.entries(imports).map(([key, value]) => [ + "$" + key, + jsValueToBinding(value), + ]) + ); + return _.merge(bindings, transformedImports); +} + +type jsImports = { [key: string]: jsValue }; + +export let defaultImports: jsImports = {}; +export let defaultBindings: externalBindings = {}; + function createTsExport( x: expressionValue, - sampEnv: samplingParams + environment: environment ): squiggleExpression { switch (x.tag) { case "EvArray": + // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} + // format, leaving it as the raw values. This converts the raw values + // directly into typescript values. + // + // The casting here is because genType is about the types of the returned + // values, claiming they are fully recursive when that's not actually the + // case return tag( "array", - x.value.map((x) => createTsExport(x, sampEnv)) + x.value.map((arrayItem): squiggleExpression => { + switch (arrayItem.tag) { + case "EvRecord": + return tag( + "record", + _.mapValues(arrayItem.value, (recordValue: unknown) => + convertRawToTypescript( + recordValue as rescriptExport, + environment + ) + ) + ); + case "EvArray": + let y = arrayItem.value as unknown as rescriptExport[]; + return tag( + "array", + y.map((childArrayItem) => + convertRawToTypescript(childArrayItem, environment) + ) + ); + default: + return createTsExport(arrayItem, environment); + } + }) ); + case "EvArrayString": + return tag("arraystring", x.value); case "EvBool": return tag("boolean", x.value); case "EvCall": return tag("call", x.value); + case "EvLambda": + return tag("lambda", x.value); case "EvDistribution": - return tag("distribution", new Distribution(x.value, sampEnv)); + return tag("distribution", new Distribution(x.value, environment)); case "EvNumber": return tag("number", x.value); case "EvRecord": - return tag( + // genType doesn't support records, so we have to do the raw conversion ourself + let result: tagged<"record", { [key: string]: squiggleExpression }> = tag( "record", - _.mapValues(x.value, (x) => createTsExport(x, sampEnv)) + _.mapValues(x.value, (x: unknown) => + convertRawToTypescript(x as rescriptExport, environment) + ) ); + return result; case "EvString": return tag("string", x.value); case "EvSymbol": return tag("symbol", x.value); } } - -export function resultExn(r: result): a | c { - return r.value; -} - -export type point = { x: number; y: number }; - -export type shape = { - continuous: point[]; - discrete: point[]; -}; - -function shapePoints(x: continuousShape | discreteShape): point[] { - let xs = x.xyShape.xs; - let ys = x.xyShape.ys; - return _.zipWith(xs, ys, (x, y) => ({ x, y })); -} - -export class Distribution { - t: genericDist; - env: samplingParams; - - constructor(t: genericDist, env: samplingParams) { - this.t = t; - this.env = env; - return this; - } - - mapResultDist( - r: result - ): result { - return resultMap(r, (v: genericDist) => new Distribution(v, this.env)); - } - - mean(): result { - return Constructors_mean({ env: this.env }, this.t); - } - - sample(): result { - return Constructors_sample({ env: this.env }, this.t); - } - - pdf(n: number): result { - return Constructors_pdf({ env: this.env }, this.t, n); - } - - cdf(n: number): result { - return Constructors_cdf({ env: this.env }, this.t, n); - } - - inv(n: number): result { - return Constructors_inv({ env: this.env }, this.t, n); - } - - isNormalized(): result { - return Constructors_isNormalized({ env: this.env }, this.t); - } - - normalize(): result { - return this.mapResultDist( - Constructors_normalize({ env: this.env }, this.t) - ); - } - - type() { - return this.t.tag; - } - - pointSet(): result { - let pointSet = toPointSet( - this.t, - { - xyPointLength: this.env.xyPointLength, - sampleCount: this.env.sampleCount, - }, - undefined - ); - if (pointSet.tag === "Ok") { - let distribution = pointSet.value; - if (distribution.tag === "Continuous") { - return Ok({ - continuous: shapePoints(distribution.value), - discrete: [], - }); - } else if (distribution.tag === "Discrete") { - return Ok({ - discrete: shapePoints(distribution.value), - continuous: [], - }); - } else { - return Ok({ - discrete: shapePoints(distribution.value.discrete), - continuous: shapePoints(distribution.value.continuous), - }); - } - } else { - return pointSet; - } - } - - toPointSet(): result { - return this.mapResultDist( - Constructors_toPointSet({ env: this.env }, this.t) - ); - } - - toSampleSet(n: number): result { - return this.mapResultDist( - Constructors_toSampleSet({ env: this.env }, this.t, n) - ); - } - - truncate( - left: number, - right: number - ): result { - return this.mapResultDist( - Constructors_truncate({ env: this.env }, this.t, left, right) - ); - } - - inspect(): result { - return this.mapResultDist(Constructors_inspect({ env: this.env }, this.t)); - } - - toString(): string { - let result = Constructors_toString({ env: this.env }, this.t); - if (result.tag === "Ok") { - return result.value; - } else { - return distributionErrorToString(result.value); - } - } - - toSparkline(n: number): result { - return Constructors_toSparkline({ env: this.env }, this.t, n); - } - - algebraicAdd(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicAdd({ env: this.env }, this.t, d2.t) - ); - } - - algebraicMultiply(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicMultiply({ env: this.env }, this.t, d2.t) - ); - } - - algebraicDivide(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicDivide({ env: this.env }, this.t, d2.t) - ); - } - - algebraicSubtract(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicSubtract({ env: this.env }, this.t, d2.t) - ); - } - - algebraicLogarithm( - d2: Distribution - ): result { - return this.mapResultDist( - Constructors_algebraicLogarithm({ env: this.env }, this.t, d2.t) - ); - } - - algebraicPower(d2: Distribution): result { - return this.mapResultDist( - Constructors_algebraicPower({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseAdd(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseAdd({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseMultiply(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseMultiply({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseDivide(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseDivide({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseSubtract(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwiseSubtract({ env: this.env }, this.t, d2.t) - ); - } - - pointwiseLogarithm( - d2: Distribution - ): result { - return this.mapResultDist( - Constructors_pointwiseLogarithm({ env: this.env }, this.t, d2.t) - ); - } - - pointwisePower(d2: Distribution): result { - return this.mapResultDist( - Constructors_pointwisePower({ env: this.env }, this.t, d2.t) - ); - } -} diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts new file mode 100644 index 00000000..45f4124b --- /dev/null +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -0,0 +1,170 @@ +import * as _ from "lodash"; +import { + mixedShape, + sampleSetDist, + genericDist, + environment, + symbolicDist, + discreteShape, + continuousShape, + lambdaValue, +} from "../rescript/TypescriptInterface.gen"; +import { Distribution } from "./distribution"; +import { tagged, tag } from "./types"; +// This file is here to compensate for genType not fully recursively converting types + +// Raw rescript types. +export type rescriptExport = + | { + TAG: 0; // EvArray + _0: rescriptExport[]; + } + | { + TAG: 1; // EvString + _0: string[]; + } + | { + TAG: 2; // EvBool + _0: boolean; + } + | { + TAG: 3; // EvCall + _0: string; + } + | { + TAG: 4; // EvDistribution + _0: rescriptDist; + } + | { + TAG: 5; // EvLambda + _0: lambdaValue; + } + | { + TAG: 6; // EvNumber + _0: number; + } + | { + TAG: 7; // EvRecord + _0: { [key: string]: rescriptExport }; + } + | { + TAG: 8; // EvString + _0: string; + } + | { + TAG: 9; // EvSymbol + _0: string; + }; + +type rescriptDist = + | { TAG: 0; _0: rescriptPointSetDist } + | { TAG: 1; _0: sampleSetDist } + | { TAG: 2; _0: symbolicDist }; + +type rescriptPointSetDist = + | { + TAG: 0; // Mixed + _0: mixedShape; + } + | { + TAG: 1; // Discrete + _0: discreteShape; + } + | { + TAG: 2; // ContinuousShape + _0: continuousShape; + }; + +export type squiggleExpression = + | tagged<"symbol", string> + | tagged<"string", string> + | tagged<"call", string> + | tagged<"lambda", lambdaValue> + | tagged<"array", squiggleExpression[]> + | tagged<"arraystring", string[]> + | tagged<"boolean", boolean> + | tagged<"distribution", Distribution> + | tagged<"number", number> + | tagged<"record", { [key: string]: squiggleExpression }>; + +export function convertRawToTypescript( + result: rescriptExport, + environment: environment +): squiggleExpression { + switch (result.TAG) { + case 0: // EvArray + return tag( + "array", + result._0.map((x) => convertRawToTypescript(x, environment)) + ); + case 1: // EvArrayString + return tag("arraystring", result._0); + case 2: // EvBool + return tag("boolean", result._0); + case 3: // EvCall + return tag("call", result._0); + case 4: // EvDistribution + return tag( + "distribution", + new Distribution( + convertRawDistributionToGenericDist(result._0), + environment + ) + ); + case 5: // EvDistribution + return tag("lambda", result._0); + case 6: // EvNumber + return tag("number", result._0); + case 7: // EvRecord + return tag( + "record", + _.mapValues(result._0, (x) => convertRawToTypescript(x, environment)) + ); + case 8: // EvString + return tag("string", result._0); + case 9: // EvSymbol + return tag("symbol", result._0); + } +} + +function convertRawDistributionToGenericDist( + result: rescriptDist +): genericDist { + switch (result.TAG) { + case 0: // Point Set Dist + switch (result._0.TAG) { + case 0: // Mixed + return tag("PointSet", tag("Mixed", result._0._0)); + case 1: // Discrete + return tag("PointSet", tag("Discrete", result._0._0)); + case 2: // Continuous + return tag("PointSet", tag("Continuous", result._0._0)); + } + case 1: // Sample Set Dist + return tag("SampleSet", result._0); + case 2: // Symbolic Dist + return tag("Symbolic", result._0); + } +} + +export type jsValue = + | string + | number + | jsValue[] + | { [key: string]: jsValue } + | boolean; + +export function jsValueToBinding(value: jsValue): rescriptExport { + if (typeof value === "boolean") { + return { TAG: 2, _0: value as boolean }; + } else if (typeof value === "string") { + return { TAG: 8, _0: value as string }; + } else if (typeof value === "number") { + return { TAG: 6, _0: value as number }; + } else if (Array.isArray(value)) { + return { TAG: 0, _0: value.map(jsValueToBinding) }; + } else { + // Record + return { TAG: 7, _0: _.mapValues(value, jsValueToBinding) }; + } +} diff --git a/packages/squiggle-lang/src/js/types.ts b/packages/squiggle-lang/src/js/types.ts new file mode 100644 index 00000000..8851b520 --- /dev/null +++ b/packages/squiggle-lang/src/js/types.ts @@ -0,0 +1,30 @@ +export type result = + | { + tag: "Ok"; + value: a; + } + | { + tag: "Error"; + value: b; + }; + +export function resultMap( + r: result, + mapFn: (x: a) => b +): result { + if (r.tag === "Ok") { + return { tag: "Ok", value: mapFn(r.value) }; + } else { + return r; + } +} + +export function Ok(x: a): result { + return { tag: "Ok", value: x }; +} + +export type tagged = { tag: a; value: b }; + +export function tag(x: a, y: b): tagged { + return { tag: x, value: y }; +} diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res index 18ee2d6a..1af12e1a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.res @@ -9,6 +9,11 @@ type env = { xyPointLength: int, } +let defaultEnv = { + sampleCount: 10000, + xyPointLength: 10000, +} + type outputType = | Dist(genericDist) | Float(float) @@ -154,6 +159,16 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.toPointSet(~xyPointLength, ~sampleCount, ()) ->E.R2.fmap(r => Dist(PointSet(r))) ->OutputLocal.fromResult + | ToDist(Scale(#Logarithm, f)) => + dist + ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Logarithm, ~f) + ->E.R2.fmap(r => Dist(r)) + ->OutputLocal.fromResult + | ToDist(Scale(#Power, f)) => + dist + ->GenericDist.pointwiseCombinationFloat(~toPointSetFn, ~algebraicCombination=#Power, ~f) + ->E.R2.fmap(r => Dist(r)) + ->OutputLocal.fromResult | ToDistCombination(Algebraic(_), _, #Float(_)) => GenDistError(NotYetImplemented) | ToDistCombination(Algebraic(strategy), arithmeticOperation, #Dist(t2)) => dist @@ -189,6 +204,12 @@ let rec run = (~env, functionCallInfo: functionCallInfo): outputType => { ->GenericDist.mixture(~scaleMultiplyFn=scaleMultiply, ~pointwiseAddFn=pointwiseAdd) ->E.R2.fmap(r => Dist(r)) ->OutputLocal.fromResult + | FromSamples(xs) => + xs + ->SampleSetDist.make + ->E.R2.errMap(x => DistributionTypes.SampleSetError(x)) + ->E.R2.fmap(x => x->DistributionTypes.SampleSet->Dist) + ->OutputLocal.fromResult } } @@ -229,6 +250,7 @@ module Constructors = { let isNormalized = (~env, dist) => C.isNormalized(dist)->run(~env)->toBoolR let toPointSet = (~env, dist) => C.toPointSet(dist)->run(~env)->toDistR let toSampleSet = (~env, dist, n) => C.toSampleSet(dist, n)->run(~env)->toDistR + let fromSamples = (~env, xs) => C.fromSamples(xs)->run(~env)->toDistR let truncate = (~env, dist, leftCutoff, rightCutoff) => C.truncate(dist, leftCutoff, rightCutoff)->run(~env)->toDistR let inspect = (~env, dist) => C.inspect(dist)->run(~env)->toDistR diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi index 5ad34354..77aa546b 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation/DistributionOperation.resi @@ -4,6 +4,9 @@ type env = { xyPointLength: int, } +@genType +let defaultEnv: env + open DistributionTypes @genType @@ -61,6 +64,8 @@ module Constructors: { @genType let toSampleSet: (~env: env, genericDist, int) => result @genType + let fromSamples: (~env: env, SampleSetDist.t) => result + @genType let truncate: (~env: env, genericDist, option, option) => result @genType let inspect: (~env: env, genericDist) => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index e27a138d..a9151a8f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -11,7 +11,7 @@ type error = | NotYetImplemented | Unreachable | DistributionVerticalShiftIsInvalid - | TooFewSamples + | SampleSetError(SampleSetDist.sampleSetError) | ArgumentError(string) | OperationError(Operation.Error.t) | PointSetConversionError(SampleSetDist.pointsetConversionError) @@ -19,6 +19,7 @@ type error = | RequestedStrategyInvalidError(string) | LogarithmOfDistributionError(string) | OtherError(string) + | XYShapeError(XYShape.error) @genType module Error = { @@ -34,21 +35,20 @@ module Error = { | DistributionVerticalShiftIsInvalid => "Distribution Vertical Shift is Invalid" | ArgumentError(s) => `Argument Error ${s}` | LogarithmOfDistributionError(s) => `Logarithm of input error: ${s}` - | TooFewSamples => "Too Few Samples" + | SampleSetError(TooFewSamples) => "Too Few Samples" + | SampleSetError(NonNumericInput(err)) => `Found a non-number in input: ${err}` | OperationError(err) => Operation.Error.toString(err) | PointSetConversionError(err) => SampleSetDist.pointsetConversionErrorToString(err) | SparklineError(err) => PointSetTypes.sparklineErrorToString(err) | RequestedStrategyInvalidError(err) => `Requested strategy invalid: ${err}` + | XYShapeError(err) => `XY Shape Error: ${XYShape.Error.toString(err)}` | OtherError(s) => s } let resultStringToResultError: result<'a, string> => result<'a, error> = n => n->E.R2.errMap(r => r->fromString) - let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => - switch err { - | TooFewSamples => TooFewSamples - } + let sampleErrorToDistErr = (err: SampleSetDist.sampleSetError): error => SampleSetError(err) } @genType @@ -66,12 +66,19 @@ module DistributionOperation = { | #Pdf(float) | #Mean | #Sample + | #IntegralSum + ] + + type toScaleFn = [ + | #Power + | #Logarithm ] type toDist = | Normalize | ToPointSet | ToSampleSet(int) + | Scale(toScaleFn, float) | Truncate(option, option) | Inspect @@ -97,6 +104,7 @@ module DistributionOperation = { type genericFunctionCallInfo = | FromDist(fromDist, genericDist) | FromFloat(fromDist, float) + | FromSamples(array) | Mixture(array<(genericDist, float)>) let distCallToString = (distFunction: fromDist): string => @@ -106,11 +114,14 @@ module DistributionOperation = { | ToFloat(#Mean) => `mean` | ToFloat(#Pdf(r)) => `pdf(${E.Float.toFixed(r)})` | ToFloat(#Sample) => `sample` + | ToFloat(#IntegralSum) => `integralSum` | ToDist(Normalize) => `normalize` | ToDist(ToPointSet) => `toPointSet` | ToDist(ToSampleSet(r)) => `toSampleSet(${E.I.toString(r)})` | ToDist(Truncate(_, _)) => `truncate` | ToDist(Inspect) => `inspect` + | ToDist(Scale(#Power, r)) => `scalePower(${E.Float.toFixed(r)})` + | ToDist(Scale(#Logarithm, r)) => `scaleLog(${E.Float.toFixed(r)})` | ToString(ToString) => `toString` | ToString(ToSparkline(n)) => `toSparkline(${E.I.toString(n)})` | ToBool(IsNormalized) => `isNormalized` @@ -122,6 +133,7 @@ module DistributionOperation = { switch d { | FromDist(f, _) | FromFloat(f, _) => distCallToString(f) | Mixture(_) => `mixture` + | FromSamples(_) => `fromSamples` } } module Constructors = { @@ -138,8 +150,11 @@ module Constructors = { let isNormalized = (dist): t => FromDist(ToBool(IsNormalized), dist) let toPointSet = (dist): t => FromDist(ToDist(ToPointSet), dist) let toSampleSet = (dist, r): t => FromDist(ToDist(ToSampleSet(r)), dist) + let fromSamples = (xs): t => FromSamples(xs) let truncate = (dist, left, right): t => FromDist(ToDist(Truncate(left, right)), dist) let inspect = (dist): t => FromDist(ToDist(Inspect), dist) + let scalePower = (dist, n): t => FromDist(ToDist(Scale(#Power, n)), dist) + let scaleLogarithm = (dist, n): t => FromDist(ToDist(Scale(#Logarithm, n)), dist) let toString = (dist): t => FromDist(ToString(ToString), dist) let toSparkline = (dist, n): t => FromDist(ToString(ToSparkline(n)), dist) let algebraicAdd = (dist1, dist2: genericDist): t => FromDist( diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res index c19bdf7f..160ce640 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.res @@ -62,26 +62,31 @@ let isNormalized = (t: t): bool => Js.Math.abs_float(integralEndY(t) -. 1.0) < 1 let toFloatOperation = ( t, ~toPointSetFn: toPointSetFn, - ~distToFloatOperation: Operation.distToFloatOperation, + ~distToFloatOperation: DistributionTypes.DistributionOperation.toFloat, ) => { - let trySymbolicSolution = switch (t: t) { - | Symbolic(r) => SymbolicDist.T.operate(distToFloatOperation, r)->E.R.toOption - | _ => None - } + switch distToFloatOperation { + | #IntegralSum => Ok(integralEndY(t)) + | (#Pdf(_) | #Cdf(_) | #Inv(_) | #Mean | #Sample) as op => { + let trySymbolicSolution = switch (t: t) { + | Symbolic(r) => SymbolicDist.T.operate(op, r)->E.R.toOption + | _ => None + } - let trySampleSetSolution = switch ((t: t), distToFloatOperation) { - | (SampleSet(sampleSet), #Mean) => SampleSetDist.mean(sampleSet)->Some - | (SampleSet(sampleSet), #Sample) => SampleSetDist.sample(sampleSet)->Some - | (SampleSet(sampleSet), #Inv(r)) => SampleSetDist.percentile(sampleSet, r)->Some - | _ => None - } + let trySampleSetSolution = switch ((t: t), distToFloatOperation) { + | (SampleSet(sampleSet), #Mean) => SampleSetDist.mean(sampleSet)->Some + | (SampleSet(sampleSet), #Sample) => SampleSetDist.sample(sampleSet)->Some + | (SampleSet(sampleSet), #Inv(r)) => SampleSetDist.percentile(sampleSet, r)->Some + | _ => None + } - switch trySymbolicSolution { - | Some(r) => Ok(r) - | None => - switch trySampleSetSolution { - | Some(r) => Ok(r) - | None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(distToFloatOperation)) + switch trySymbolicSolution { + | Some(r) => Ok(r) + | None => + switch trySampleSetSolution { + | Some(r) => Ok(r) + | None => toPointSetFn(t)->E.R2.fmap(PointSetDist.operate(op)) + } + } } } } diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi index e91803e2..3d143edc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist/GenericDist.resi @@ -20,7 +20,7 @@ let isNormalized: t => bool let toFloatOperation: ( t, ~toPointSetFn: toPointSetFn, - ~distToFloatOperation: Operation.distToFloatOperation, + ~distToFloatOperation: DistributionTypes.DistributionOperation.toFloat, ) => result @genType diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res index 63600e43..a51de00d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/AlgebraicShapeCombination.res @@ -263,4 +263,4 @@ let combineShapesContinuousDiscrete = ( ) } -let isOrdered = (a: XYShape.T.t): bool => E.A.Sorted.Floats.isSorted(a.xs) +let isOrdered = (a: XYShape.T.t): bool => E.A.Floats.isSorted(a.xs) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res index d4286387..105b5a05 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Continuous.res @@ -156,8 +156,10 @@ let reduce = ( ~integralSumCachesFn: (float, float) => option=(_, _) => None, fn: (float, float) => result, continuousShapes, -): result => - continuousShapes |> E.A.R.foldM(combinePointwise(~integralSumCachesFn, fn), empty) +): result => { + let merge = combinePointwise(~integralSumCachesFn, fn) + continuousShapes |> E.A.R.foldM(merge, empty) +} let mapYResult = ( ~integralSumCacheFn=_ => None, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res index fdc921c6..1149df7e 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Discrete.res @@ -34,9 +34,10 @@ let lastY = (t: t) => t |> getShape |> XYShape.T.lastY let combinePointwise = ( ~integralSumCachesFn=(_, _) => None, + fn, t1: PointSetTypes.discreteShape, t2: PointSetTypes.discreteShape, -): PointSetTypes.discreteShape => { +): result => { let combinedIntegralSum = Common.combineIntegralSums( integralSumCachesFn, t1.integralSumCache, @@ -49,16 +50,22 @@ let combinePointwise = ( make( ~integralSumCache=combinedIntegralSum, XYShape.PointwiseCombination.combine( - (a, b) => Ok(a +. b), + fn, XYShape.XtoY.discreteInterpolator, t1.xyShape, t2.xyShape, )->E.R.toExn("Addition operation should never fail", _), - ) + )->Ok } -let reduce = (~integralSumCachesFn=(_, _) => None, discreteShapes): PointSetTypes.discreteShape => - discreteShapes |> E.A.fold_left(combinePointwise(~integralSumCachesFn), empty) +let reduce = ( + ~integralSumCachesFn=(_, _) => None, + fn: (float, float) => result, + discreteShapes: array, +): result => { + let merge = combinePointwise(~integralSumCachesFn, fn) + discreteShapes |> E.A.R.foldM(merge, empty) +} let updateIntegralSumCache = (integralSumCache, t: t): t => { ...t, diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res index 4ce2bdd6..98e7923a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/Mixed.res @@ -316,7 +316,10 @@ let combinePointwise = ( t2: t, ): result => { let reducedDiscrete = - [t1, t2] |> E.A.fmap(toDiscrete) |> E.A.O.concatSomes |> Discrete.reduce(~integralSumCachesFn) + [t1, t2] + |> E.A.fmap(toDiscrete) + |> E.A.O.concatSomes + |> Discrete.reduce(~integralSumCachesFn, fn) let reducedContinuous = [t1, t2] @@ -335,11 +338,11 @@ let combinePointwise = ( t1.integralCache, t2.integralCache, ) - reducedContinuous->E.R2.fmap(continuous => + E.R.merge(reducedContinuous, reducedDiscrete)->E.R2.fmap(((continuous, discrete)) => make( ~integralSumCache=combinedIntegralSum, ~integralCache=combinedIntegral, - ~discrete=reducedDiscrete, + ~discrete, ~continuous, ) ) diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res index 12aa5477..00c900dc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetDist.res @@ -84,7 +84,12 @@ let combinePointwise = ( m2, )->E.R2.fmap(x => PointSetTypes.Continuous(x)) | (Discrete(m1), Discrete(m2)) => - Ok(PointSetTypes.Discrete(Discrete.combinePointwise(~integralSumCachesFn, m1, m2))) + Discrete.combinePointwise( + ~integralSumCachesFn, + fn, + m1, + m2, + )->E.R2.fmap(x => PointSetTypes.Discrete(x)) | (m1, m2) => Mixed.combinePointwise( ~integralSumCachesFn, diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res index 14c66812..55b334c5 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist.res @@ -1,11 +1,12 @@ @genType module Error = { @genType - type sampleSetError = TooFewSamples + type sampleSetError = TooFewSamples | NonNumericInput(string) let sampleSetErrorToString = (err: sampleSetError): string => switch err { | TooFewSamples => "Too few samples when constructing sample set" + | NonNumericInput(err) => `Found a non-number in input: ${err}` } @genType diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res index aef659d1..29d48ad3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_Bandwidth.res @@ -1,27 +1,30 @@ //The math here was taken from https://github.com/jasondavies/science.js/blob/master/src/stats/SampleSetDist_Bandwidth.js - +let {iqr_percentile, nrd0_lo_denominator, one, nrd0_coef, nrd_coef, nrd_fractionalPower} = module( + MagicNumbers.SampleSetBandwidth +) let len = x => E.A.length(x) |> float_of_int -let iqr = x => Jstat.percentile(x, 0.75, true) -. Jstat.percentile(x, 0.25, true) +let iqr = x => + Jstat.percentile(x, iqr_percentile, true) -. Jstat.percentile(x, 1.0 -. iqr_percentile, true) // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. let nrd0 = x => { let hi = Js_math.sqrt(Jstat.variance(x)) - let lo = Js_math.minMany_float([hi, iqr(x) /. 1.34]) + let lo = Js_math.minMany_float([hi, iqr(x) /. nrd0_lo_denominator]) let e = Js_math.abs_float(x[1]) let lo' = switch (lo, hi, e) { | (lo, _, _) if !Js.Float.isNaN(lo) => lo | (_, hi, _) if !Js.Float.isNaN(hi) => hi | (_, _, e) if !Js.Float.isNaN(e) => e - | _ => 1.0 + | _ => one } - 0.9 *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=-0.2) + nrd0_coef *. lo' *. Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. let nrd = x => { - let h = iqr(x) /. 1.34 - 1.06 *. + let h = iqr(x) /. nrd0_lo_denominator + nrd_coef *. Js.Math.min_float(Js.Math.sqrt(Jstat.variance(x)), h) *. - Js.Math.pow_float(~base=len(x), ~exp=-1.0 /. 5.0) + Js.Math.pow_float(~base=len(x), ~exp=nrd_fractionalPower) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index 142f10b2..ec2bf0d0 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -64,7 +64,7 @@ let toPointSetDist = ( ): Internals.Types.outputs => { Array.fast_sort(compare, samples) let minDiscreteToKeep = MagicNumbers.ToPointSet.minDiscreteToKeep(samples) - let (continuousPart, discretePart) = E.A.Sorted.Floats.splitContinuousAndDiscreteForMinWeight( + let (continuousPart, discretePart) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( samples, ~minDiscreteWeight=minDiscreteToKeep, ) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res index 997506d9..fb338ded 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDist.res @@ -216,15 +216,42 @@ module Uniform = { } } +module Gamma = { + type t = gamma + let make = (shape: float, scale: float) => { + if shape > 0. { + if scale > 0. { + Ok(#Gamma({shape: shape, scale: scale})) + } else { + Error("scale must be larger than 0") + } + } else { + Error("shape must be larger than 0") + } + } + let pdf = (x: float, t: t) => Jstat.Gamma.pdf(x, t.shape, t.scale) + let cdf = (x: float, t: t) => Jstat.Gamma.cdf(x, t.shape, t.scale) + let inv = (p: float, t: t) => Jstat.Gamma.inv(p, t.shape, t.scale) + let sample = (t: t) => Jstat.Gamma.sample(t.shape, t.scale) + let mean = (t: t) => Ok(Jstat.Gamma.mean(t.shape, t.scale)) + let toString = ({shape, scale}: t) => j`($shape, $scale)` +} + module Float = { type t = float let make = t => #Float(t) + let makeSafe = t => + if E.Float.isFinite(t) { + Ok(#Float(t)) + } else { + Error("Float must be finite") + } let pdf = (x, t: t) => x == t ? 1.0 : 0.0 let cdf = (x, t: t) => x >= t ? 1.0 : 0.0 let inv = (p, t: t) => p < t ? 0.0 : 1.0 let mean = (t: t) => Ok(t) let sample = (t: t) => t - let toString = Js.Float.toString + let toString = (t: t) => j`Delta($t)` } module From90thPercentile = { @@ -246,6 +273,7 @@ module T = { | #Triangular(n) => Triangular.pdf(x, n) | #Exponential(n) => Exponential.pdf(x, n) | #Cauchy(n) => Cauchy.pdf(x, n) + | #Gamma(n) => Gamma.pdf(x, n) | #Lognormal(n) => Lognormal.pdf(x, n) | #Uniform(n) => Uniform.pdf(x, n) | #Beta(n) => Beta.pdf(x, n) @@ -258,6 +286,7 @@ module T = { | #Triangular(n) => Triangular.cdf(x, n) | #Exponential(n) => Exponential.cdf(x, n) | #Cauchy(n) => Cauchy.cdf(x, n) + | #Gamma(n) => Gamma.cdf(x, n) | #Lognormal(n) => Lognormal.cdf(x, n) | #Uniform(n) => Uniform.cdf(x, n) | #Beta(n) => Beta.cdf(x, n) @@ -270,6 +299,7 @@ module T = { | #Triangular(n) => Triangular.inv(x, n) | #Exponential(n) => Exponential.inv(x, n) | #Cauchy(n) => Cauchy.inv(x, n) + | #Gamma(n) => Gamma.inv(x, n) | #Lognormal(n) => Lognormal.inv(x, n) | #Uniform(n) => Uniform.inv(x, n) | #Beta(n) => Beta.inv(x, n) @@ -282,6 +312,7 @@ module T = { | #Triangular(n) => Triangular.sample(n) | #Exponential(n) => Exponential.sample(n) | #Cauchy(n) => Cauchy.sample(n) + | #Gamma(n) => Gamma.sample(n) | #Lognormal(n) => Lognormal.sample(n) | #Uniform(n) => Uniform.sample(n) | #Beta(n) => Beta.sample(n) @@ -304,6 +335,7 @@ module T = { | #Exponential(n) => Exponential.toString(n) | #Cauchy(n) => Cauchy.toString(n) | #Normal(n) => Normal.toString(n) + | #Gamma(n) => Gamma.toString(n) | #Lognormal(n) => Lognormal.toString(n) | #Uniform(n) => Uniform.toString(n) | #Beta(n) => Beta.toString(n) @@ -317,6 +349,7 @@ module T = { | #Cauchy(n) => Cauchy.inv(minCdfValue, n) | #Normal(n) => Normal.inv(minCdfValue, n) | #Lognormal(n) => Lognormal.inv(minCdfValue, n) + | #Gamma(n) => Gamma.inv(minCdfValue, n) | #Uniform({low}) => low | #Beta(n) => Beta.inv(minCdfValue, n) | #Float(n) => n @@ -328,6 +361,7 @@ module T = { | #Exponential(n) => Exponential.inv(maxCdfValue, n) | #Cauchy(n) => Cauchy.inv(maxCdfValue, n) | #Normal(n) => Normal.inv(maxCdfValue, n) + | #Gamma(n) => Gamma.inv(maxCdfValue, n) | #Lognormal(n) => Lognormal.inv(maxCdfValue, n) | #Beta(n) => Beta.inv(maxCdfValue, n) | #Uniform({high}) => high @@ -343,6 +377,7 @@ module T = { | #Lognormal(n) => Lognormal.mean(n) | #Beta(n) => Beta.mean(n) | #Uniform(n) => Uniform.mean(n) + | #Gamma(n) => Gamma.mean(n) | #Float(n) => Float.mean(n) } diff --git a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res index 333e2e63..7878a3bc 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SymbolicDist/SymbolicDistTypes.res @@ -31,6 +31,11 @@ type triangular = { high: float, } +type gamma = { + shape: float, + scale: float, +} + @genType type symbolicDist = [ | #Normal(normal) @@ -40,6 +45,7 @@ type symbolicDist = [ | #Exponential(exponential) | #Cauchy(cauchy) | #Triangular(triangular) + | #Gamma(gamma) | #Float(float) ] diff --git a/packages/squiggle-lang/src/rescript/MagicNumbers.res b/packages/squiggle-lang/src/rescript/MagicNumbers.res index 124a44f4..0f059c03 100644 --- a/packages/squiggle-lang/src/rescript/MagicNumbers.res +++ b/packages/squiggle-lang/src/rescript/MagicNumbers.res @@ -35,3 +35,16 @@ module ToPointSet = { */ let minDiscreteToKeep = samples => max(20, E.A.length(samples) / 50) } + +module SampleSetBandwidth = { + // Silverman, B. W. (1986) Density Estimation. London: Chapman and Hall. + // Scott, D. W. (1992) Multivariate Density Estimation: Theory, Practice, and Visualization. Wiley. + let iqr_percentile = 0.75 + let iqr_percentile_complement = 1.0 -. iqr_percentile + let nrd0_lo_denominator = 1.34 + let one = 1.0 + let nrd0_coef = 0.9 + + let nrd_coef = 1.06 + let nrd_fractionalPower = -0.2 +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index d2e4858f..3b3450c3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -1,15 +1,27 @@ -module Dispatch = Reducer_Dispatch module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression -module Extra = Reducer_Extra -module Js = Reducer_Js -module MathJs = Reducer_MathJs +module ExpressionValue = ReducerInterface_ExpressionValue +module Lambda = Reducer_Expression_Lambda -type expressionValue = Reducer_Expression.expressionValue -type externalBindings = Expression.externalBindings -let evaluate = Expression.eval -let evaluateUsingExternalBindings = Expression.evalUsingExternalBindings -let evaluatePartialUsingExternalBindings = Expression.evalPartialUsingExternalBindings +type environment = ReducerInterface_ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type lambdaValue = ExpressionValue.lambdaValue + +let evaluate = Expression.evaluate +let evaluateUsingOptions = Expression.evaluateUsingOptions +let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings let parse = Expression.parse -let parseOuter = Expression.parseOuter -let parsePartial = Expression.parsePartial + +let foreignFunctionInterface = ( + lambdaValue: lambdaValue, + argArray: array, + environment: ExpressionValue.environment, +) => { + Lambda.foreignFunctionInterface(lambdaValue, argArray, environment, Expression.reduceExpression) +} + +let defaultEnvironment = ExpressionValue.defaultEnvironment + +let defaultExternalBindings = ExpressionValue.defaultExternalBindings diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index 8bbfc0b5..d4e40a63 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -1,26 +1,43 @@ -module Dispatch = Reducer_Dispatch module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression -module Extra = Reducer_Extra -module Js = Reducer_Js -module MathJs = Reducer_MathJs +@genType +type environment = ReducerInterface_ExpressionValue.environment +@genType +type errorValue = Reducer_ErrorValue.errorValue @genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue @genType type externalBindings = ReducerInterface_ExpressionValue.externalBindings @genType -let evaluate: string => result +type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue + @genType -let evaluateUsingExternalBindings: ( +let evaluateUsingOptions: ( + ~environment: option, + ~externalBindings: option, string, - externalBindings, -) => result +) => result @genType let evaluatePartialUsingExternalBindings: ( string, - externalBindings, -) => result -let parse: string => result -let parseOuter: string => result -let parsePartial: string => result + QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings, + QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, +) => result +@genType +let evaluate: string => result + +let parse: string => result + +@genType +let foreignFunctionInterface: ( + QuriSquiggleLang.ReducerInterface_ExpressionValue.lambdaValue, + array, + QuriSquiggleLang.ReducerInterface_ExpressionValue.environment, +) => result + +@genType +let defaultEnvironment: environment + +@genType +let defaultExternalBindings: externalBindings diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 21c91dc2..d1a77040 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -1,5 +1,9 @@ +module Bindings = Reducer_Expression_Bindings +module ExpressionT = Reducer_Expression_T module ExternalLibrary = ReducerInterface.ExternalLibrary +module Lambda = Reducer_Expression_Lambda module MathJs = Reducer_MathJs +module Result = Belt.Result open ReducerInterface.ExpressionValue open Reducer_ErrorValue @@ -11,7 +15,10 @@ open Reducer_ErrorValue exception TestRescriptException -let callInternal = (call: functionCall): result<'b, errorValue> => { +let callInternal = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< + 'b, + errorValue, +> => { let callMathJs = (call: functionCall): result<'b, errorValue> => switch call { | ("javascriptraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests @@ -20,12 +27,12 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { } let constructRecord = arrayOfPairs => { - Belt.Array.map(arrayOfPairs, pairValue => { + Belt.Array.map(arrayOfPairs, pairValue => switch pairValue { | EvArray([EvString(key), valueValue]) => (key, valueValue) | _ => ("wrong key type", pairValue->toStringWithType->EvString) } - }) + ) ->Js.Dict.fromArray ->EvRecord ->Ok @@ -43,16 +50,89 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error } + let inspect = (value: expressionValue) => { + Js.log(value->toString) + value->Ok + } + + let inspectLabel = (value: expressionValue, label: string) => { + Js.log(`${label}: ${value->toString}`) + value->Ok + } + + let doSetBindings = ( + externalBindings: externalBindings, + symbol: string, + value: expressionValue, + ) => { + Bindings.fromExternalBindings(externalBindings) + ->Belt.Map.String.set(symbol, value) + ->Bindings.toExternalBindings + ->EvRecord + ->Ok + } + + let doExportBindings = (externalBindings: externalBindings) => EvRecord(externalBindings)->Ok + + let doKeepArray = (aValueArray, aLambdaValue) => { + let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->Result.flatMap(acc => { + let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) + rNewElem->Result.map(newElem => + switch newElem { + | EvBool(true) => list{elem, ...acc} + | _ => acc + } + ) + }) + ) + rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray) + } + + let doMapArray = (aValueArray, aLambdaValue) => { + let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => + rAcc->Result.flatMap(acc => { + let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer) + rNewElem->Result.map(newElem => list{newElem, ...acc}) + }) + ) + rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray) + } + + let doReduceArray = (aValueArray, initialValue, aLambdaValue) => { + aValueArray->Belt.Array.reduce(Ok(initialValue), (rAcc, elem) => + rAcc->Result.flatMap(acc => + Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } + + let doReduceReverseArray = (aValueArray, initialValue, aLambdaValue) => { + aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => + rAcc->Result.flatMap(acc => + Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + ) + ) + } + switch call { - // | ("$constructRecord", pairArray) - // | ("$atIndex", [EvArray(anArray), EvNumber(fIndex)]) => arrayAtIndex(anArray, fIndex) - // | ("$atIndex", [EvRecord(aRecord), EvString(sIndex)]) => recordAtIndex(aRecord, sIndex) - | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) | ("$atIndex", [EvArray(aValueArray), EvArray([EvNumber(fIndex)])]) => arrayAtIndex(aValueArray, fIndex) | ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex) - | ("$atIndex", [obj, index]) => - (toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok + | ("$constructRecord", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) + | ("$exportBindings", [EvRecord(externalBindings)]) => doExportBindings(externalBindings) + | ("$setBindings", [EvRecord(externalBindings), EvSymbol(symbol), value]) => + doSetBindings(externalBindings, symbol, value) + | ("inspect", [value, EvString(label)]) => inspectLabel(value, label) + | ("inspect", [value]) => inspect(value) + | ("keep", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => + doKeepArray(aValueArray, aLambdaValue) + | ("map", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doMapArray(aValueArray, aLambdaValue) + | ("reduce", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => + doReduceArray(aValueArray, initialValue, aLambdaValue) + | ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => + doReduceReverseArray(aValueArray, initialValue, aLambdaValue) + | ("reverse", [EvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->EvArray->Ok | call => callMathJs(call) } } @@ -60,12 +140,16 @@ let callInternal = (call: functionCall): result<'b, errorValue> => { /* Reducer uses Result monad while reducing expressions */ -let dispatch = (call: functionCall): result => +let dispatch = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< + expressionValue, + errorValue, +> => try { + let callInternalWithReducer = (call, environment) => callInternal(call, environment, reducer) let (fn, args) = call // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - ExternalLibrary.dispatch((Js.String.make(fn), args), callInternal) + ExternalLibrary.dispatch((Js.String.make(fn), args), environment, callInternalWithReducer) } catch { | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error | _ => RETodo("unhandled rescript exception")->Error diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index b7df0ff3..a771dd32 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -3,120 +3,189 @@ they take expressions as parameters and return a new expression. Macros are used to define language building blocks. They are like Lisp macros. */ +module Bindings = Reducer_Expression_Bindings module ExpressionT = Reducer_Expression_T module ExpressionValue = ReducerInterface.ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext module Result = Belt.Result +open Reducer_Expression_ExpressionBuilder -open Reducer_ErrorValue - +type environment = ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue type expression = ExpressionT.expression - -type reducerFn = ( - expression, - ExpressionT.bindings, -) => result +type expressionValue = ExpressionValue.expressionValue +type expressionWithContext = ExpressionWithContext.expressionWithContext let dispatchMacroCall = ( - list: list, + macroExpression: expression, bindings: ExpressionT.bindings, - reduceExpression: reducerFn, -): result => { - let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< - expression, - errorValue, - > => - switch expression { - | ExpressionT.EValue(EvSymbol(aSymbol)) => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error - } - | ExpressionT.EValue(_) => expression->Ok - | ExpressionT.EBindings(_) => expression->Ok - | ExpressionT.EList(list) => { - let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => - racc->Result.flatMap(acc => { - each - ->replaceSymbols(bindings) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.map(acc => acc->ExpressionT.EList) - } - } - - let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { + environment, + reduceExpression: ExpressionT.reducerFn, +): result => { + let doBindStatement = (bindingExpr: expression, statement: expression, environment) => switch statement { - | ExpressionT.EList(list{ - ExpressionT.EValue(EvCall("$let")), - ExpressionT.EValue(EvSymbol(aSymbol)), - expressionToReduce, - }) => { - let rNewExpressionToReduce = replaceSymbols(expressionToReduce, bindings) + | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) - let rNewValue = - rNewExpressionToReduce->Result.flatMap(newExpressionToReduce => - reduceExpression(newExpressionToReduce, bindings) + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + + // Js.log( + // `bindStatement ${Bindings.toString(newBindings)}<==${ExpressionT.toString( + // bindingExpr, + // )} statement: $let ${ExpressionT.toString(symbolExpr)}=${ExpressionT.toString( + // statement, + // )}`, + // ) + + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement->Result.map(newStatement => + ExpressionWithContext.withContext( + eFunction( + "$setBindings", + list{newBindings->Bindings.toExternalBindings->eRecord, symbolExpr, newStatement}, + ), + newBindings, + ) ) - - let rNewExpression = rNewValue->Result.map(newValue => ExpressionT.EValue(newValue)) - rNewExpression->Result.map(newExpression => - Belt.Map.String.set(bindings, aSymbol, newExpression)->ExpressionT.EBindings - ) + }) } | _ => REAssignmentExpected->Error } - } - let doExportVariableExpression = (bindings: ExpressionT.bindings) => { - let emptyDictionary: Js.Dict.t = Js.Dict.empty() - let reducedBindings = bindings->Belt.Map.String.keep((_key, value) => - switch value { - | ExpressionT.EValue(_) => true - | _ => false - } - ) - let externalBindings = reducedBindings->Belt.Map.String.reduce(emptyDictionary, ( - acc, - key, - expressionValue, - ) => { - let value = switch expressionValue { - | EValue(aValue) => aValue - | _ => EvSymbol("internal") - } - Js.Dict.set(acc, key, value) - acc - }) - externalBindings->ExpressionValue.EvRecord->ExpressionT.EValue->Ok - } + let doBindExpression = (bindingExpr: expression, statement: expression, environment): result< + expressionWithContext, + errorValue, + > => + switch statement { + | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), symbolExpr, statement}) => { + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) - let doBindExpression = (expression: expression, bindings: ExpressionT.bindings) => - switch expression { - | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), ..._}) => - REExpressionExpected->Error - | ExpressionT.EList(list{ExpressionT.EValue(EvCall("$exportVariablesExpression"))}) => - doExportVariableExpression(bindings) - | _ => replaceSymbols(expression, bindings) + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement->Result.map(newStatement => + ExpressionWithContext.withContext( + eFunction( + "$exportBindings", + list{ + eFunction( + "$setBindings", + list{ + newBindings->Bindings.toExternalBindings->eRecord, + symbolExpr, + newStatement, + }, + ), + }, + ), + newBindings, + ) + ) + }) + } + | _ => { + let rExternalBindingsValue: result = reduceExpression( + bindingExpr, + bindings, + environment, + ) + + rExternalBindingsValue->Result.flatMap(externalBindingsValue => { + let newBindings = Bindings.fromValue(externalBindingsValue) + let rNewStatement = Bindings.replaceSymbols(newBindings, statement) + rNewStatement->Result.map(newStatement => + ExpressionWithContext.withContext(newStatement, newBindings) + ) + }) + } } - switch list { - | list{ExpressionT.EValue(EvCall("$$bindings"))} => bindings->ExpressionT.EBindings->Ok + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< + expressionWithContext, + errorValue, + > => { + let exprsArray = Belt.List.toArray(exprs) + let maxIndex = Js.Array2.length(exprsArray) - 1 + let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => + if index == 0 { + if index == maxIndex { + eBindExpressionDefault(statement) + } else { + eBindStatementDefault(statement) + } + } else if index == maxIndex { + eBindExpression(acc, statement) + } else { + eBindStatement(acc, statement) + } + , eSymbol("undefined block")) + ExpressionWithContext.noContext(newStatement)->Ok + } - | list{ - ExpressionT.EValue(EvCall("$$bindStatement")), - ExpressionT.EBindings(bindings), - statement, - } => - doBindStatement(statement, bindings) - | list{ - ExpressionT.EValue(EvCall("$$bindExpression")), - ExpressionT.EBindings(bindings), - expression, - } => - doBindExpression(expression, bindings) - | _ => list->ExpressionT.EList->Ok + let doLambdaDefinition = ( + bindings: ExpressionT.bindings, + parameters: array, + lambdaDefinition: ExpressionT.expression, + ) => + ExpressionWithContext.noContext( + eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition), + )->Ok + + let doTernary = ( + condition: expression, + ifTrue: expression, + ifFalse: expression, + bindings: ExpressionT.bindings, + environment, + ): result => { + let rCondition = reduceExpression(condition, bindings, environment) + rCondition->Result.flatMap(conditionValue => + switch conditionValue { + | ExpressionValue.EvBool(false) => ExpressionWithContext.noContext(ifFalse)->Ok + | ExpressionValue.EvBool(true) => ExpressionWithContext.noContext(ifTrue)->Ok + | _ => REExpectedType("Boolean")->Error + } + ) + } + + let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result< + expressionWithContext, + errorValue, + > => + switch aList { + | list{ + ExpressionT.EValue(EvCall("$$bindStatement")), + bindingExpr: ExpressionT.expression, + statement, + } => + doBindStatement(bindingExpr, statement, environment) + | list{ExpressionT.EValue(EvCall("$$bindStatement")), statement} => + // bindings of the context are used when there is no binding expression + doBindStatement(eRecord(Bindings.toExternalBindings(bindings)), statement, environment) + | list{ + ExpressionT.EValue(EvCall("$$bindExpression")), + bindingExpr: ExpressionT.expression, + expression, + } => + doBindExpression(bindingExpr, expression, environment) + | list{ExpressionT.EValue(EvCall("$$bindExpression")), expression} => + // bindings of the context are used when there is no binding expression + doBindExpression(eRecord(Bindings.toExternalBindings(bindings)), expression, environment) + | list{ExpressionT.EValue(EvCall("$$block")), ...exprs} => doBlock(exprs, bindings, environment) + | list{ + ExpressionT.EValue(EvCall("$$lambda")), + ExpressionT.EValue(EvArrayString(parameters)), + lambdaDefinition, + } => + doLambdaDefinition(bindings, parameters, lambdaDefinition) + | list{ExpressionT.EValue(EvCall("$$ternary")), condition, ifTrue, ifFalse} => + doTernary(condition, ifTrue, ifFalse, bindings, environment) + | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok + } + + switch macroExpression { + | EList(aList) => expandExpressionList(aList, bindings, environment) + | _ => ExpressionWithContext.noContext(macroExpression)->Ok } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 96b73fd2..4d859a79 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -1,22 +1,29 @@ @genType type errorValue = + | REArityError(option, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting | REArrayIndexNotFound(string, int) | REAssignmentExpected + | REDistributionError(DistributionTypes.error) | REExpressionExpected | REFunctionExpected(string) | REJavaScriptExn(option, option) // Javascript Exception | REMacroNotFound(string) + | RENotAFunction(string) | RERecordPropertyNotFound(string, string) | RESymbolNotFound(string) | RESyntaxError(string) - | REDistributionError(DistributionTypes.error) | RETodo(string) // To do + | REExpectedType(string) type t = errorValue @genType let errorToString = err => switch err { + | REArityError(_oFnName, arity, usedArity) => + `${Js.String.make(arity)} arguments expected. Instead ${Js.String.make( + usedArity, + )} argument(s) were passed.` | REArrayIndexNotFound(msg, index) => `${msg}: ${Js.String.make(index)}` | REAssignmentExpected => "Assignment expected" | REExpressionExpected => "Expression expected" @@ -35,8 +42,10 @@ let errorToString = err => answer } | REMacroNotFound(macro) => `Macro not found: ${macro}` + | RENotAFunction(valueString) => `${valueString} is not a function` | RERecordPropertyNotFound(msg, index) => `${msg}: ${index}` | RESymbolNotFound(symbolName) => `${symbolName} is not defined` | RESyntaxError(desc) => `Syntax Error: ${desc}` | RETodo(msg) => `TODO: ${msg}` + | REExpectedType(typeName) => `Expected type: ${typeName}` } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index b45b8e14..81830e84 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -1,35 +1,22 @@ +module Bindings = Reducer_Expression_Bindings module BuiltIn = Reducer_Dispatch_BuiltIn +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionValue = ReducerInterface.ExpressionValue module Extra = Reducer_Extra +module Lambda = Reducer_Expression_Lambda +module Macro = Reducer_Expression_Macro module MathJs = Reducer_MathJs module Result = Belt.Result module T = Reducer_Expression_T -open Reducer_ErrorValue +type environment = ReducerInterface_ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue type expression = T.expression -type expressionValue = ExpressionValue.expressionValue +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type internalCode = ReducerInterface_ExpressionValue.internalCode type t = expression -/* - Shows the expression as text of expression -*/ -let rec toString = expression => - switch expression { - | T.EBindings(_) => "$$bound" - | T.EList(aList) => - `(${Belt.List.map(aList, aValue => toString(aValue)) - ->Extra.List.interperse(" ") - ->Belt.List.toArray - ->Js.String.concatMany("")})` - | EValue(aValue) => ExpressionValue.toString(aValue) - } - -let toStringResult = codeResult => - switch codeResult { - | Ok(a) => `Ok(${toString(a)})` - | Error(m) => `Error(${Js.String.make(m)})` - } - /* Converts a MathJs code to expression */ @@ -39,148 +26,116 @@ let parse_ = (expr: string, parser, converter): result => let parse = (mathJsCode: string): result => mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromNode) -let parsePartial = (mathJsCode: string): result => - mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromPartialNode) - -let parseOuter = (mathJsCode: string): result => - mathJsCode->parse_(MathJs.Parse.parse, MathJs.ToExpression.fromOuterNode) - -let defaultBindings: T.bindings = Belt.Map.String.empty - /* Recursively evaluate/reduce the expression (Lisp AST) */ -let rec reduceExpression = (expression: t, bindings: T.bindings): result => { - /* - Macros are like functions but instead of taking values as parameters, - they take expressions as parameters and return a new expression. - Macros are used to define language building blocks. They are like Lisp macros. - */ - let doMacroCall = (list: list, bindings: T.bindings): result => - Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, reduceExpression) +let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< + expressionValue, + 'e, +> => { + // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) + switch expression { + | T.EValue(value) => value->Ok + | T.EList(list) => + switch list { + | list{EValue(EvCall(fName)), ..._args} => + switch Macro.isMacroName(fName) { + // A macro expands then reduces itself + | true => Macro.doMacroCall(expression, bindings, environment, reduceExpression) + | false => reduceExpressionList(list, bindings, environment) + } + | _ => reduceExpressionList(list, bindings, environment) + } + } +} - /* +and reduceExpressionList = ( + expressions: list, + bindings: T.bindings, + environment: environment, +): result => { + let racc: result, 'e> = expressions->Belt.List.reduceReverse(Ok(list{}), ( + racc, + each: expression, + ) => + racc->Result.flatMap(acc => { + each + ->reduceExpression(bindings, environment) + ->Result.map(newNode => { + acc->Belt.List.add(newNode) + }) + }) + ) + racc->Result.flatMap(acc => acc->reduceValueList(environment)) +} + +/* After reducing each level of expression(Lisp AST), we have a value list to evaluate */ - let reduceValueList = (valueList: list): result => - switch valueList { - | list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch - | _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok - } +and reduceValueList = (valueList: list, environment): result< + expressionValue, + 'e, +> => + switch valueList { + | list{EvCall(fName), ...args} => + (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment, reduceExpression) - let rec seekMacros = (expression: t, bindings: T.bindings): result => - switch expression { - | T.EValue(_value) => expression->Ok - | T.EBindings(_value) => expression->Ok - | T.EList(list) => { - let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( - racc, - each: expression, - ) => - racc->Result.flatMap(acc => { - each - ->seekMacros(bindings) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.flatMap(acc => acc->doMacroCall(bindings)) - } - } + | list{EvLambda(lamdaCall), ...args} => + Lambda.doLambdaCall(lamdaCall, args, environment, reduceExpression) + | _ => + valueList + ->Lambda.checkIfReduced + ->Result.flatMap(reducedValueList => + reducedValueList->Belt.List.toArray->ExpressionValue.EvArray->Ok + ) + } - let rec reduceExpandedExpression = (expression: t): result => - switch expression { - | T.EValue(value) => value->Ok - | T.EList(list) => { - let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), ( - racc, - each: expression, - ) => - racc->Result.flatMap(acc => { - each - ->reduceExpandedExpression - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.flatMap(acc => acc->reduceValueList) - } - | EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error - } +let evalUsingBindingsExpression_ = (aExpression, bindings, environment): result< + expressionValue, + 'e, +> => reduceExpression(aExpression, bindings, environment) - let rExpandedExpression: result = expression->seekMacros(bindings) - rExpandedExpression->Result.flatMap(expandedExpression => - expandedExpression->reduceExpandedExpression - ) -} +let evaluateUsingOptions = ( + ~environment: option, + ~externalBindings: option, + code: string, +): result => { + let anEnvironment = switch environment { + | Some(env) => env + | None => ReducerInterface_ExpressionValue.defaultEnvironment + } -let evalUsingExternalBindingsExpression_ = (aExpression, bindings): result => - reduceExpression(aExpression, bindings) + let anExternalBindings = switch externalBindings { + | Some(bindings) => bindings + | None => ReducerInterface_ExpressionValue.defaultExternalBindings + } -/* - Evaluates MathJs code via Reducer using bindings and answers the result. - When bindings are used, the code is a partial code as if it is cut from a larger code. - Therefore all statements are assignments. -*/ -let evalPartialUsingExternalBindings_ = (codeText: string, bindings: T.bindings) => { - parsePartial(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings) - ) -} + let bindings = anExternalBindings->Bindings.fromExternalBindings -/* - Evaluates MathJs code via Reducer using bindings and answers the result. - When bindings are used, the code is a partial code as if it is cut from a larger code. - Therefore all statments are assignments. -*/ -let evalOuterWBindings_ = (codeText: string, bindings: T.bindings) => { - parseOuter(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(bindings) - ) + parse(code)->Result.flatMap(expr => evalUsingBindingsExpression_(expr, bindings, anEnvironment)) } /* Evaluates MathJs code and bindings via Reducer and answers the result */ -let eval = (codeText: string) => { - parse(codeText)->Result.flatMap(expression => - expression->evalUsingExternalBindingsExpression_(defaultBindings) - ) -} - -type externalBindings = ReducerInterface.ExpressionValue.externalBindings //Js.Dict.t - -let externalBindingsToBindings = (externalBindings: externalBindings): T.bindings => { - let keys = Js.Dict.keys(externalBindings) - keys->Belt.Array.reduce(defaultBindings, (acc, key) => { - let value = Js.Dict.unsafeGet(externalBindings, key) - acc->Belt.Map.String.set(key, T.EValue(value)) - }) -} -/* - Evaluates code with external bindings. External bindings are a record of expression values. -*/ -let evalUsingExternalBindings = (code: string, externalBindings: externalBindings) => { - let bindings = externalBindings->externalBindingsToBindings - evalOuterWBindings_(code, bindings) -} - -/* - Evaluates code with external bindings. External bindings are a record of expression values. - The code is a partial code as if it is cut from a larger code. Therefore all statments are assignments. -*/ -let evalPartialUsingExternalBindings = (code: string, externalBindings: externalBindings): result< - externalBindings, - 'e, -> => { - let bindings = externalBindings->externalBindingsToBindings - let answer = evalPartialUsingExternalBindings_(code, bindings) - answer->Result.flatMap(answer => - switch answer { - | EvRecord(aRecord) => Ok(aRecord) - | _ => RETodo("TODO: External bindings must be returned")->Error - } +let evaluate = (code: string): result => { + evaluateUsingOptions(~environment=None, ~externalBindings=None, code) +} +let eval = evaluate +let evaluatePartialUsingExternalBindings = ( + code: string, + externalBindings: ReducerInterface_ExpressionValue.externalBindings, + environment: ReducerInterface_ExpressionValue.environment, +): result => { + let rAnswer = evaluateUsingOptions( + ~environment=Some(environment), + ~externalBindings=Some(externalBindings), + code, ) + switch rAnswer { + | Ok(EvRecord(externalBindings)) => Ok(externalBindings) + | Ok(_) => + Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`)) + | Error(err) => err->Error + } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res new file mode 100644 index 00000000..dacd2462 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res @@ -0,0 +1,45 @@ +module Bindings = Reducer_Expression_Bindings +module ErrorValue = Reducer_ErrorValue +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type bindings = ExpressionT.bindings +type context = bindings +type environment = ExpressionValue.environment +type errorValue = Reducer_ErrorValue.errorValue +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type reducerFn = ExpressionT.reducerFn + +type expressionWithContext = + | ExpressionWithContext(expression, context) + | ExpressionNoContext(expression) + +let callReducer = ( + expressionWithContext: expressionWithContext, + bindings: bindings, + environment: environment, + reducer: reducerFn, +): result => + switch expressionWithContext { + | ExpressionNoContext(expr) => reducer(expr, bindings, environment) + | ExpressionWithContext(expr, context) => reducer(expr, context, environment) + } + +let withContext = (expression, context) => ExpressionWithContext(expression, context) +let noContext = expression => ExpressionNoContext(expression) + +let toString = expressionWithContext => + switch expressionWithContext { + | ExpressionNoContext(expr) => ExpressionT.toString(expr) + | ExpressionWithContext(expr, context) => + `${ExpressionT.toString(expr)} context: ${Bindings.toString(context)}` + } + +let toStringResult = rExpressionWithContext => + switch rExpressionWithContext { + | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` + | Error(errorValue) => ErrorValue.errorToString(errorValue) + } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res new file mode 100644 index 00000000..7c0c048a --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Bindings.res @@ -0,0 +1,85 @@ +module ErrorValue = Reducer_ErrorValue +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type errorValue = Reducer_ErrorValue.errorValue +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings + +let defaultBindings: ExpressionT.bindings = Belt.Map.String.empty + +let fromExternalBindings = (externalBindings: externalBindings): ExpressionT.bindings => { + let keys = Js.Dict.keys(externalBindings) + keys->Belt.Array.reduce(defaultBindings, (acc, key) => { + let value = Js.Dict.unsafeGet(externalBindings, key) + acc->Belt.Map.String.set(key, value) + }) +} + +let toExternalBindings = (bindings: ExpressionT.bindings): externalBindings => { + let keys = Belt.Map.String.keysToArray(bindings) + keys->Belt.Array.reduce(Js.Dict.empty(), (acc, key) => { + let value = bindings->Belt.Map.String.getExn(key) + Js.Dict.set(acc, key, value) + acc + }) +} + +let fromValue = (aValue: expressionValue) => + switch aValue { + | EvRecord(externalBindings) => fromExternalBindings(externalBindings) + | _ => defaultBindings + } + +let externalFromArray = anArray => Js.Dict.fromArray(anArray) + +let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") + +let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): result< + expression, + errorValue, +> => + switch expression { + | ExpressionT.EValue(value) => + replaceSymbolOnValue(bindings, value)->Result.map(evValue => evValue->ExpressionT.EValue) + | ExpressionT.EList(list) => + switch list { + | list{EValue(EvCall(fName)), ..._args} => + switch isMacroName(fName) { + // A macro reduces itself so we dont dive in it + | true => expression->Ok + | false => replaceSymbolsOnExpressionList(bindings, list) + } + | _ => replaceSymbolsOnExpressionList(bindings, list) + } + } + +and replaceSymbolsOnExpressionList = (bindings, list) => { + let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => + racc->Result.flatMap(acc => { + replaceSymbols(bindings, each)->Result.flatMap(newNode => { + acc->Belt.List.add(newNode)->Ok + }) + }) + ) + racc->Result.map(acc => acc->ExpressionT.EList) +} +and replaceSymbolOnValue = (bindings, evValue: expressionValue) => + switch evValue { + | EvSymbol(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok + | EvCall(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->checkIfCallable + | _ => evValue->Ok + } +and checkIfCallable = (evValue: expressionValue) => + switch evValue { + | EvCall(_) | EvLambda(_) => evValue->Ok + | _ => ErrorValue.RENotAFunction(ExpressionValue.toString(evValue))->Error + } + +let toString = (bindings: ExpressionT.bindings) => + bindings->toExternalBindings->ExpressionValue.EvRecord->ExpressionValue.toString + +let externalBindingsToString = (externalBindings: externalBindings) => + externalBindings->ExpressionValue.EvRecord->ExpressionValue.toString diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res new file mode 100644 index 00000000..9c9f922e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -0,0 +1,66 @@ +module BBindings = Reducer_Expression_Bindings +module BErrorValue = Reducer_ErrorValue +module BExpressionT = Reducer_Expression_T +module BExpressionValue = ReducerInterface.ExpressionValue + +type errorValue = BErrorValue.errorValue +type expression = BExpressionT.expression +type internalCode = ReducerInterface_ExpressionValue.internalCode + +external castExpressionToInternalCode: expression => internalCode = "%identity" + +let eArray = anArray => anArray->BExpressionValue.EvArray->BExpressionT.EValue + +let eArrayString = anArray => anArray->BExpressionValue.EvArrayString->BExpressionT.EValue + +let eBindings = (anArray: array<(string, BExpressionValue.expressionValue)>) => + anArray->Js.Dict.fromArray->EvRecord->BExpressionT.EValue + +let eBool = aBool => aBool->BExpressionValue.EvBool->BExpressionT.EValue + +let eCall = (name: string): expression => name->BExpressionValue.EvCall->BExpressionT.EValue + +let eFunction = (fName: string, lispArgs: list): expression => { + let fn = fName->eCall + list{fn, ...lispArgs}->BExpressionT.EList +} + +let eLambda = ( + parameters: array, + context: BExpressionValue.externalBindings, + expr: expression, +) => { + // Js.log(`eLambda context ${BBindings.externalBindingsToString(context)}`) + BExpressionValue.EvLambda({ + parameters: parameters, + context: context, + body: expr->castExpressionToInternalCode, + })->BExpressionT.EValue +} + +let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue + +let eRecord = aRecord => aRecord->BExpressionValue.EvRecord->BExpressionT.EValue + +let eString = aString => aString->BExpressionValue.EvString->BExpressionT.EValue + +let eSymbol = (name: string): expression => name->BExpressionValue.EvSymbol->BExpressionT.EValue + +let eList = (list: list): expression => list->BExpressionT.EList + +let eBlock = (exprs: list): expression => eFunction("$$block", exprs) + +let eLetStatement = (symbol: string, valueExpression: expression): expression => + eFunction("$let", list{eSymbol(symbol), valueExpression}) + +let eBindStatement = (bindingExpr: expression, letStatement: expression): expression => + eFunction("$$bindStatement", list{bindingExpr, letStatement}) + +let eBindStatementDefault = (letStatement: expression): expression => + eFunction("$$bindStatement", list{letStatement}) + +let eBindExpression = (bindingExpr: expression, expression: expression): expression => + eFunction("$$bindExpression", list{bindingExpr, expression}) + +let eBindExpressionDefault = (expression: expression): expression => + eFunction("$$bindExpression", list{expression}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res new file mode 100644 index 00000000..dc4920f3 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -0,0 +1,69 @@ +module Bindings = Reducer_Expression_Bindings +module ErrorValue = Reducer_ErrorValue +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module Result = Belt.Result + +type environment = ReducerInterface_ExpressionValue.environment +type expression = ExpressionT.expression +type expressionValue = ReducerInterface_ExpressionValue.expressionValue +type externalBindings = ReducerInterface_ExpressionValue.externalBindings +type internalCode = ReducerInterface_ExpressionValue.internalCode + +external castInternalCodeToExpression: internalCode => expression = "%identity" + +let checkArity = (lambdaValue: ExpressionValue.lambdaValue, args: list) => { + let argsLength = Belt.List.length(args) + let parametersLength = Js.Array2.length(lambdaValue.parameters) + if argsLength !== parametersLength { + ErrorValue.REArityError(None, parametersLength, argsLength)->Error + } else { + args->Ok + } +} + +let checkIfReduced = (args: list) => + args->Belt.List.reduceReverse(Ok(list{}), (rAcc, arg) => + rAcc->Result.flatMap(acc => + switch arg { + | EvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->Error + | _ => list{arg, ...acc}->Ok + } + ) + ) + +let applyParametersToLambda = ( + lambdaValue: ExpressionValue.lambdaValue, + args, + environment, + reducer: ExpressionT.reducerFn, +): result => { + checkArity(lambdaValue, args)->Result.flatMap(args => + checkIfReduced(args)->Result.flatMap(args => { + let expr = castInternalCodeToExpression(lambdaValue.body) + let parameterList = lambdaValue.parameters->Belt.List.fromArray + let zippedParameterList = parameterList->Belt.List.zip(args) + let bindings = Belt.List.reduce( + zippedParameterList, + lambdaValue.context->Bindings.fromExternalBindings, + (acc, (variable, variableValue)) => acc->Belt.Map.String.set(variable, variableValue), + ) + let newExpression = ExpressionBuilder.eBlock(list{expr}) + reducer(newExpression, bindings, environment) + }) + ) +} + +let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => + applyParametersToLambda(lambdaValue, args, environment, reducer) + +let foreignFunctionInterface = ( + lambdaValue: ExpressionValue.lambdaValue, + argArray: array, + environment: ExpressionValue.environment, + reducer: ExpressionT.reducerFn, +): result => { + let args = argArray->Belt.List.fromArray + applyParametersToLambda(lambdaValue, args, environment, reducer) +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res new file mode 100644 index 00000000..23fb70f8 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -0,0 +1,44 @@ +module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue +module ExpressionWithContext = Reducer_ExpressionWithContext +module Result = Belt.Result + +type environment = ExpressionValue.environment +type expression = ExpressionT.expression +type expressionValue = ExpressionValue.expressionValue +type expressionWithContext = ExpressionWithContext.expressionWithContext + +let expandMacroCall = ( + macroExpression: expression, + bindings: ExpressionT.bindings, + environment: environment, + reduceExpression: ExpressionT.reducerFn, +): result => + Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( + macroExpression, + bindings, + environment, + reduceExpression, + ) + +let doMacroCall = ( + macroExpression: expression, + bindings: ExpressionT.bindings, + environment: environment, + reduceExpression: ExpressionT.reducerFn, +): result => + expandMacroCall( + macroExpression, + bindings, + environment, + reduceExpression, + )->Result.flatMap(expressionWithContext => + ExpressionWithContext.callReducer( + expressionWithContext, + bindings, + environment, + reduceExpression, + ) + ) + +let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res index fe938316..b21ba8b7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res @@ -1,5 +1,3 @@ -open ReducerInterface.ExpressionValue - /* An expression is a Lisp AST. An expression is either a primitive value or a list of expressions. In the case of a list of expressions (e1, e2, e3, ...eN), the semantic is @@ -8,8 +6,51 @@ open ReducerInterface.ExpressionValue A Lisp AST contains only expressions/primitive values to apply to their left. The act of defining the semantics of a functional language is to write it in terms of Lisp AST. */ +module Extra = Reducer_Extra +module ExpressionValue = ReducerInterface.ExpressionValue + +type expressionValue = ExpressionValue.expressionValue +type environment = ExpressionValue.environment + type rec expression = | EList(list) // A list to map-reduce | EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible - | EBindings(bindings) // let/def kind of statements return bindings -and bindings = Belt.Map.String.t +and bindings = Belt.Map.String.t + +type reducerFn = ( + expression, + bindings, + environment, +) => result + +/* + Converts the expression to String +*/ +let rec toString = expression => + switch expression { + | EList(aList) => + `(${Belt.List.map(aList, aValue => toString(aValue)) + ->Extra.List.interperse(" ") + ->Belt.List.toArray + ->Js.String.concatMany("")})` + | EValue(aValue) => ExpressionValue.toString(aValue) + } + +let toStringResult = codeResult => + switch codeResult { + | Ok(a) => `Ok(${toString(a)})` + | Error(m) => `Error(${Reducer_ErrorValue.errorToString(m)})` + } + +let inspect = (expr: expression): expression => { + Js.log(toString(expr)) + expr +} + +let inspectResult = (r: result): result< + expression, + Reducer_ErrorValue.errorValue, +> => { + Js.log(toStringResult(r)) + r +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res index ad83edb1..7cd220bc 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res @@ -8,11 +8,10 @@ external castString: unit => string = "%identity" /* As JavaScript returns us any type, we need to type check and cast type propertype before using it */ -let jsToEv = (jsValue): result => { +let jsToEv = (jsValue): result => switch Js.typeof(jsValue) { | "boolean" => jsValue->castBool->EvBool->Ok | "number" => jsValue->castNumber->EvNumber->Ok | "string" => jsValue->castString->EvString->Ok | other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error } -} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res index e3e2955c..704d1d38 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Parse.res @@ -9,13 +9,12 @@ type node = {"type": string, "isNode": bool, "comment": string} type arrayNode = {...node, "items": array} type block = {"node": node} type blockNode = {...node, "blocks": array} -//conditionalNode +type conditionalNode = {...node, "condition": node, "trueExpr": node, "falseExpr": node} type constantNode = {...node, "value": unit} -//functionAssignmentNode +type functionAssignmentNode = {...node, "name": string, "params": array, "expr": node} type indexNode = {...node, "dimensions": array} type objectNode = {...node, "properties": Js.Dict.t} type accessorNode = {...node, "object": node, "index": indexNode, "name": string} - type parenthesisNode = {...node, "content": node} //rangeNode //relationalNode @@ -32,7 +31,9 @@ external castAssignmentNode: node => assignmentNode = "%identity" external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identity" external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity" external castBlockNode: node => blockNode = "%identity" +external castConditionalNode: node => conditionalNode = "%identity" external castConstantNode: node => constantNode = "%identity" +external castFunctionAssignmentNode: node => functionAssignmentNode = "%identity" external castFunctionNode: node => functionNode = "%identity" external castIndexNode: node => indexNode = "%identity" external castObjectNode: node => objectNode = "%identity" @@ -58,7 +59,9 @@ type mathJsNode = | MjArrayNode(arrayNode) | MjAssignmentNode(assignmentNode) | MjBlockNode(blockNode) + | MjConditionalNode(conditionalNode) | MjConstantNode(constantNode) + | MjFunctionAssignmentNode(functionAssignmentNode) | MjFunctionNode(functionNode) | MjIndexNode(indexNode) | MjObjectNode(objectNode) @@ -81,7 +84,9 @@ let castNodeType = (node: node) => { | "ArrayNode" => node->castArrayNode->MjArrayNode->Ok | "AssignmentNode" => node->decideAssignmentNode | "BlockNode" => node->castBlockNode->MjBlockNode->Ok + | "ConditionalNode" => node->castConditionalNode->MjConditionalNode->Ok | "ConstantNode" => node->castConstantNode->MjConstantNode->Ok + | "FunctionAssignmentNode" => node->castFunctionAssignmentNode->MjFunctionAssignmentNode->Ok | "FunctionNode" => node->castFunctionNode->MjFunctionNode->Ok | "IndexNode" => node->castIndexNode->MjIndexNode->Ok | "ObjectNode" => node->castObjectNode->MjObjectNode->Ok @@ -118,6 +123,10 @@ let rec toString = (mathJsNode: mathJsNode): string => { ->Extra.Array.interperse(", ") ->Js.String.concatMany("") + let toStringFunctionAssignmentNode = (faNode: functionAssignmentNode): string => { + let paramNames = Js.Array2.toString(faNode["params"]) + `${faNode["name"]} = (${paramNames}) => ${toStringMathJsNode(faNode["expr"])}` + } let toStringFunctionNode = (fnode: functionNode): string => `${fnode->nameOfFunctionNode}(${fnode["args"]->toStringNodeArray})` @@ -151,7 +160,12 @@ let rec toString = (mathJsNode: mathJsNode): string => { | MjAssignmentNode(aNode) => `${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}` | MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}` + | MjConditionalNode(cNode) => + `ternary(${toStringMathJsNode(cNode["condition"])}, ${toStringMathJsNode( + cNode["trueExpr"], + )}, ${toStringMathJsNode(cNode["falseExpr"])})` | MjConstantNode(cNode) => cNode["value"]->toStringValue + | MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode | MjFunctionNode(fNode) => fNode->toStringFunctionNode | MjIndexNode(iNode) => iNode->toStringIndexNode | MjObjectNode(oNode) => oNode->toStringObjectNode diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res index a8b7b39a..6355de88 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_ToExpression.res @@ -1,45 +1,35 @@ +/* * WARNING. DO NOT EDIT, BEAUTIFY, COMMENT ON OR REFACTOR THIS CODE. +We will stop using MathJs parser and +this whole file will go to trash +**/ module ErrorValue = Reducer_ErrorValue -module ExpressionValue = ReducerInterface.ExpressionValue +module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionT = Reducer_Expression_T +module ExpressionValue = ReducerInterface.ExpressionValue module JavaScript = Reducer_Js module Parse = Reducer_MathJs_Parse module Result = Belt.Result +type errorValue = ErrorValue.errorValue type expression = ExpressionT.expression type expressionValue = ExpressionValue.expressionValue -type errorValue = ErrorValue.errorValue -let passToFunction = (fName: string, rLispArgs): result => { - let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue +let blockToNode = block => block["node"] - let fn = fName->toEvCallValue - rLispArgs->Result.flatMap(lispArgs => list{fn, ...lispArgs}->ExpressionT.EList->Ok) -} - -type blockTag = - | ImportVariablesStatement - | ExportVariablesExpression -type tagOrNode = - | BlockTag(blockTag) - | BlockNode(Parse.node) - -let toTagOrNode = block => BlockNode(block["node"]) - -let rec fromNode = (mathJsNode: Parse.node): result => +let rec fromInnerNode = (mathJsNode: Parse.node): result => Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { let fromNodeList = (nodeList: list): result, 'e> => Belt.List.reduceReverse(nodeList, Ok(list{}), (racc, currNode) => racc->Result.flatMap(acc => - fromNode(currNode)->Result.map(currCode => list{currCode, ...acc}) + fromInnerNode(currNode)->Result.map(currCode => list{currCode, ...acc}) ) ) - let toEvSymbolValue = (name: string): expression => - name->ExpressionValue.EvSymbol->ExpressionT.EValue - let caseFunctionNode = fNode => { - let lispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList - passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs) + let rLispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList + rLispArgs->Result.map(lispArgs => + ExpressionBuilder.eFunction(fNode->Parse.nameOfFunctionNode, lispArgs) + ) } let caseObjectNode = oNode => { @@ -49,19 +39,16 @@ let rec fromNode = (mathJsNode: Parse.node): result => (key: string, value: Parse.node), ) => racc->Result.flatMap(acc => - fromNode(value)->Result.map(valueExpression => { + fromInnerNode(value)->Result.map(valueExpression => { let entryCode = - list{ - key->ExpressionValue.EvString->ExpressionT.EValue, - valueExpression, - }->ExpressionT.EList + list{ExpressionBuilder.eString(key), valueExpression}->ExpressionT.EList list{entryCode, ...acc} }) ) ) rargs->Result.flatMap(args => - passToFunction("$constructRecord", list{ExpressionT.EList(args)}->Ok) - ) // $consturctRecord gets a single argument: List of key-value paiers + ExpressionBuilder.eFunction("$constructRecord", list{ExpressionT.EList(args)})->Ok + ) // $constructRecord gets a single argument: List of key-value paiers } oNode["properties"]->Js.Dict.entries->Belt.List.fromArray->fromObjectEntries @@ -73,7 +60,7 @@ let rec fromNode = (mathJsNode: Parse.node): result => Ok(list{}), (racc, currentPropertyMathJsNode) => racc->Result.flatMap(acc => - fromNode(currentPropertyMathJsNode)->Result.map(propertyCode => list{ + fromInnerNode(currentPropertyMathJsNode)->Result.map(propertyCode => list{ propertyCode, ...acc, }) @@ -84,18 +71,41 @@ let rec fromNode = (mathJsNode: Parse.node): result => let caseAccessorNode = (objectNode, indexNode) => { caseIndexNode(indexNode)->Result.flatMap(indexCode => { - fromNode(objectNode)->Result.flatMap(objectCode => - passToFunction("$atIndex", list{objectCode, indexCode}->Ok) + fromInnerNode(objectNode)->Result.flatMap(objectCode => + ExpressionBuilder.eFunction("$atIndex", list{objectCode, indexCode})->Ok ) }) } + let caseBlock = (nodesArray: array): result => { + let rStatements: result, 'a> = + nodesArray + ->Belt.List.fromArray + ->Belt.List.reduceReverse(Ok(list{}), (racc, currNode) => + racc->Result.flatMap(acc => + fromInnerNode(currNode)->Result.map(currCode => list{currCode, ...acc}) + ) + ) + rStatements->Result.map(statements => ExpressionBuilder.eBlock(statements)) + } + let caseAssignmentNode = aNode => { - let symbol = aNode["object"]["name"]->toEvSymbolValue - let rValueExpression = fromNode(aNode["value"]) + let symbolName = aNode["object"]["name"] + let rValueExpression = fromInnerNode(aNode["value"]) + rValueExpression->Result.map(valueExpression => + ExpressionBuilder.eLetStatement(symbolName, valueExpression) + ) + } + + let caseFunctionAssignmentNode = faNode => { + let symbol = faNode["name"]->ExpressionBuilder.eSymbol + let rValueExpression = fromInnerNode(faNode["expr"]) + rValueExpression->Result.flatMap(valueExpression => { - let lispArgs = list{symbol, valueExpression}->Ok - passToFunction("$let", lispArgs) + let lispParams = ExpressionBuilder.eArrayString(faNode["params"]) + let valueBlock = ExpressionBuilder.eBlock(list{valueExpression}) + let lambda = ExpressionBuilder.eFunction("$$lambda", list{lispParams, valueBlock}) + ExpressionBuilder.eFunction("$let", list{symbol, lambda})->Ok }) } @@ -103,93 +113,42 @@ let rec fromNode = (mathJsNode: Parse.node): result => aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list)) } + let caseConditionalNode = cndNode => { + let rCondition = fromInnerNode(cndNode["condition"]) + let rTrueExpr = fromInnerNode(cndNode["trueExpr"]) + let rFalse = fromInnerNode(cndNode["falseExpr"]) + + rCondition->Result.flatMap(condition => + rTrueExpr->Result.flatMap(trueExpr => + rFalse->Result.flatMap(falseExpr => + ExpressionBuilder.eFunction("$$ternary", list{condition, trueExpr, falseExpr})->Ok + ) + ) + ) + } + let rFinalExpression: result = switch typedMathJsNode { | MjAccessorNode(aNode) => caseAccessorNode(aNode["object"], aNode["index"]) | MjArrayNode(aNode) => caseArrayNode(aNode) | MjAssignmentNode(aNode) => caseAssignmentNode(aNode) | MjSymbolNode(sNode) => { - let expr: expression = toEvSymbolValue(sNode["name"]) + let expr: expression = ExpressionBuilder.eSymbol(sNode["name"]) let rExpr: result = expr->Ok rExpr } - | MjBlockNode(bNode) => bNode["blocks"]->Belt.Array.map(toTagOrNode)->caseTagOrNodes + | MjBlockNode(bNode) => bNode["blocks"]->Js.Array2.map(blockToNode)->caseBlock + | MjConditionalNode(cndNode) => caseConditionalNode(cndNode) | MjConstantNode(cNode) => cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok) + | MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode) | MjFunctionNode(fNode) => fNode->caseFunctionNode | MjIndexNode(iNode) => caseIndexNode(iNode) | MjObjectNode(oNode) => caseObjectNode(oNode) | MjOperatorNode(opNode) => opNode->Parse.castOperatorNodeToFunctionNode->caseFunctionNode - | MjParenthesisNode(pNode) => pNode["content"]->fromNode + | MjParenthesisNode(pNode) => pNode["content"]->fromInnerNode } rFinalExpression }) -and caseTagOrNodes = (tagOrNodes): result => { - let initialBindings = passToFunction("$$bindings", list{}->Ok) - let lastIndex = Belt.Array.length(tagOrNodes) - 1 - tagOrNodes->Belt.Array.reduceWithIndex(initialBindings, (rPreviousBindings, tagOrNode, i) => { - rPreviousBindings->Result.flatMap(previousBindings => { - let rStatement: result = switch tagOrNode { - | BlockNode(node) => fromNode(node) - | BlockTag(tag) => - switch tag { - | ImportVariablesStatement => passToFunction("$importVariablesStatement", list{}->Ok) - | ExportVariablesExpression => passToFunction("$exportVariablesExpression", list{}->Ok) - } - } - let bindName = if i == lastIndex { - "$$bindExpression" - } else { - "$$bindStatement" - } - - rStatement->Result.flatMap((statement: expression) => { - let lispArgs = list{previousBindings, statement}->Ok - passToFunction(bindName, lispArgs) - }) - }) - }) -} - -let fromPartialNode = (mathJsNode: Parse.node): result => { - Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { - let casePartialBlockNode = (bNode: Parse.blockNode) => { - let blocksOrTags = bNode["blocks"]->Belt.Array.map(toTagOrNode) - let completed = Js.Array2.concat(blocksOrTags, [BlockTag(ExportVariablesExpression)]) - completed->caseTagOrNodes - } - - let casePartialExpression = (node: Parse.node) => { - let completed = [BlockNode(node), BlockTag(ExportVariablesExpression)] - - completed->caseTagOrNodes - } - - let rFinalExpression: result = switch typedMathJsNode { - | MjBlockNode(bNode) => casePartialBlockNode(bNode) - | _ => casePartialExpression(mathJsNode) - } - rFinalExpression - }) -} - -let fromOuterNode = (mathJsNode: Parse.node): result => { - Parse.castNodeType(mathJsNode)->Result.flatMap(typedMathJsNode => { - let casePartialBlockNode = (bNode: Parse.blockNode) => { - let blocksOrTags = bNode["blocks"]->Belt.Array.map(toTagOrNode) - let completed = blocksOrTags - completed->caseTagOrNodes - } - - let casePartialExpression = (node: Parse.node) => { - let completed = [BlockNode(node)] - completed->caseTagOrNodes - } - - let rFinalExpression: result = switch typedMathJsNode { - | MjBlockNode(bNode) => casePartialBlockNode(bNode) - | _ => casePartialExpression(mathJsNode) - } - rFinalExpression - }) -} +let fromNode = (node: Parse.node): result => + fromInnerNode(node)->Result.map(expr => ExpressionBuilder.eBlock(list{expr})) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 381cc654..5c9ee4b7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -5,37 +5,50 @@ module Extra_Array = Reducer_Extra_Array module ErrorValue = Reducer_ErrorValue +@genType.opaque +type internalCode = Object + @genType type rec expressionValue = | EvArray(array) + | EvArrayString(array) | EvBool(bool) | EvCall(string) // External function call | EvDistribution(DistributionTypes.genericDist) + | EvLambda(lambdaValue) | EvNumber(float) - | EvRecord(Js.Dict.t) + | EvRecord(record) | EvString(string) | EvSymbol(string) +and record = Js.Dict.t +and externalBindings = record +and lambdaValue = { + parameters: array, + context: externalBindings, + body: internalCode, +} @genType -type externalBindings = Js.Dict.t +let defaultExternalBindings: externalBindings = Js.Dict.empty() type functionCall = (string, array) let rec toString = aValue => switch aValue { + | EvArray(anArray) => { + let args = anArray->Js.Array2.map(each => toString(each))->Js.Array2.toString + `[${args}]` + } + | EvArrayString(anArray) => { + let args = anArray->Js.Array2.toString + `[${args}]` + } | EvBool(aBool) => Js.String.make(aBool) | EvCall(fName) => `:${fName}` + | EvLambda(lambdaValue) => `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` | EvNumber(aNumber) => Js.String.make(aNumber) | EvString(aString) => `'${aString}'` | EvSymbol(aString) => `:${aString}` - | EvArray(anArray) => { - let args = - anArray - ->Belt.Array.map(each => toString(each)) - ->Extra_Array.interperse(", ") - ->Js.String.concatMany("") - `[${args}]` - } | EvRecord(aRecord) => aRecord->toStringRecord | EvDistribution(dist) => GenericDist.toString(dist) } @@ -43,26 +56,27 @@ and toStringRecord = aRecord => { let pairs = aRecord ->Js.Dict.entries - ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) - ->Extra_Array.interperse(", ") - ->Js.String.concatMany("") + ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) + ->Js.Array2.toString `{${pairs}}` } let toStringWithType = aValue => switch aValue { + | EvArray(_) => `Array::${toString(aValue)}` + | EvArrayString(_) => `ArrayString::${toString(aValue)}` | EvBool(_) => `Bool::${toString(aValue)}` | EvCall(_) => `Call::${toString(aValue)}` + | EvDistribution(_) => `Distribution::${toString(aValue)}` + | EvLambda(_) => `Lambda::${toString(aValue)}` | EvNumber(_) => `Number::${toString(aValue)}` + | EvRecord(_) => `Record::${toString(aValue)}` | EvString(_) => `String::${toString(aValue)}` | EvSymbol(_) => `Symbol::${toString(aValue)}` - | EvArray(_) => `Array::${toString(aValue)}` - | EvRecord(_) => `Record::${toString(aValue)}` - | EvDistribution(_) => `Distribution::${toString(aValue)}` } let argsToString = (args: array): string => { - args->Belt.Array.map(arg => arg->toString)->Extra_Array.interperse(", ")->Js.String.concatMany("") + args->Js.Array2.map(arg => arg->toString)->Js.Array2.toString } let toStringFunctionCall = ((fn, args)): string => `${fn}(${argsToString(args)})` @@ -78,3 +92,9 @@ let toStringResultRecord = x => | Ok(a) => `Ok(${toStringRecord(a)})` | Error(m) => `Error(${ErrorValue.errorToString(m)})` } + +@genType +type environment = DistributionOperation.env + +@genType +let defaultEnvironment: environment = DistributionOperation.defaultEnv diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 84d37d95..0bdb0748 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -14,8 +14,13 @@ type expressionValue = ExpressionValue.expressionValue Map external calls of Reducer */ -let dispatch = (call: ExpressionValue.functionCall, chain): result => - ReducerInterface_GenericDistribution.dispatch(call) |> E.O.default(chain(call)) +let dispatch = (call: ExpressionValue.functionCall, environment, chain): result< + expressionValue, + 'e, +> => + ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default( + chain(call, environment), + ) /* If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally. diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index ab76f469..b6f42697 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -1,12 +1,12 @@ module ExpressionValue = ReducerInterface_ExpressionValue type expressionValue = ReducerInterface_ExpressionValue.expressionValue -let runGenericOperation = DistributionOperation.run( - ~env={ - sampleCount: MagicNumbers.Environment.defaultSampleCount, - xyPointLength: MagicNumbers.Environment.defaultXYPointLength, - }, -) +let defaultEnv: DistributionOperation.env = { + sampleCount: MagicNumbers.Environment.defaultSampleCount, + xyPointLength: MagicNumbers.Environment.defaultXYPointLength, +} + +let runGenericOperation = DistributionOperation.run(~env=defaultEnv) module Helpers = { let arithmeticMap = r => @@ -28,14 +28,13 @@ module Helpers = { let catchAndConvertTwoArgsToDists = (args: array): option<( DistributionTypes.genericDist, DistributionTypes.genericDist, - )> => { + )> => switch args { | [EvDistribution(a), EvDistribution(b)] => Some((a, b)) | [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) | [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b))) | _ => None } - } let toFloatFn = ( fnCall: DistributionTypes.DistributionOperation.toFloat, @@ -119,7 +118,7 @@ module Helpers = { mixtureWithGivenWeights(distributions, weights) } - let mixture = (args: array): DistributionOperation.outputType => { + let mixture = (args: array): DistributionOperation.outputType => switch E.A.last(args) { | Some(EvArray(b)) => { let weights = parseNumberArray(b) @@ -131,6 +130,7 @@ module Helpers = { | Error(err) => GenDistError(ArgumentError(err)) } } + | Some(EvNumber(_)) | Some(EvDistribution(_)) => switch parseDistributionArray(args) { | Ok(distributions) => mixtureWithDefaultWeights(distributions) @@ -138,7 +138,6 @@ module Helpers = { } | _ => GenDistError(ArgumentError("Last argument of mx must be array or distribution")) } - } } module SymbolicConstructors = { @@ -155,6 +154,7 @@ module SymbolicConstructors = { | "beta" => Ok(SymbolicDist.Beta.make) | "lognormal" => Ok(SymbolicDist.Lognormal.make) | "cauchy" => Ok(SymbolicDist.Cauchy.make) + | "gamma" => Ok(SymbolicDist.Gamma.make) | "to" => Ok(SymbolicDist.From90thPercentile.make) | _ => Error("Unreachable state") } @@ -174,17 +174,19 @@ module SymbolicConstructors = { } } -let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< +let dispatchToGenericOutput = (call: ExpressionValue.functionCall, _environment): option< DistributionOperation.outputType, > => { let (fnName, args) = call switch (fnName, args) { - | ("exponential" as fnName, [EvNumber(f1)]) => + | ("exponential" as fnName, [EvNumber(f)]) => SymbolicConstructors.oneFloat(fnName) - ->E.R.bind(r => r(f1)) + ->E.R.bind(r => r(f)) ->SymbolicConstructors.symbolicResultToOutput + | ("delta", [EvNumber(f)]) => + SymbolicDist.Float.makeSafe(f)->SymbolicConstructors.symbolicResultToOutput | ( - ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "to") as fnName, + ("normal" | "uniform" | "beta" | "lognormal" | "cauchy" | "gamma" | "to") as fnName, [EvNumber(f1), EvNumber(f2)], ) => SymbolicConstructors.twoFloat(fnName) @@ -196,6 +198,7 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< ->SymbolicConstructors.symbolicResultToOutput | ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist) | ("mean", [EvDistribution(dist)]) => Helpers.toFloatFn(#Mean, dist) + | ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist) | ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist) | ("toSparkline", [EvDistribution(dist)]) => Helpers.toStringFn(ToSparkline(20), dist) | ("toSparkline", [EvDistribution(dist), EvNumber(n)]) => @@ -211,6 +214,15 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< | ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist) | ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist) | ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist) + | ("scaleLog", [EvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Logarithm, MagicNumbers.Math.e), dist) + | ("scaleLog10", [EvDistribution(dist)]) => Helpers.toDistFn(Scale(#Logarithm, 10.0), dist) + | ("scaleLog", [EvDistribution(dist), EvNumber(float)]) => + Helpers.toDistFn(Scale(#Logarithm, float), dist) + | ("scalePow", [EvDistribution(dist), EvNumber(float)]) => + Helpers.toDistFn(Scale(#Power, float), dist) + | ("scaleExp", [EvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Power, MagicNumbers.Math.e), dist) | ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist) | ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist) | ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist) @@ -218,6 +230,14 @@ let dispatchToGenericOutput = (call: ExpressionValue.functionCall): option< Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist) | ("toSampleSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToSampleSet(MagicNumbers.Environment.defaultSampleCount), dist) + | ("fromSamples", [EvArray(inputArray)]) => { + let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x) + let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors) + switch parsedArray { + | Ok(array) => runGenericOperation(FromSamples(array)) + | Error(e) => GenDistError(SampleSetError(e)) + }->Some + } | ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist) | ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) => Helpers.toDistFn(Truncate(Some(float), None), dist) @@ -275,6 +295,6 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< | GenDistError(err) => Error(REDistributionError(err)) } -let dispatch = call => { - dispatchToGenericOutput(call)->E.O2.fmap(genericOutputToReducerValue) +let dispatch = (call, environment) => { + dispatchToGenericOutput(call, environment)->E.O2.fmap(genericOutputToReducerValue) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi index fc7ebabc..038f4479 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi @@ -1,3 +1,5 @@ -let dispatch: ReducerInterface_ExpressionValue.functionCall => option< - result, -> +let defaultEnv: DistributionOperation.env +let dispatch: ( + ReducerInterface_ExpressionValue.functionCall, + ReducerInterface_ExpressionValue.environment, +) => option> diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index fc381729..6ebb8377 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -13,6 +13,12 @@ type samplingParams = DistributionOperation.env @genType type genericDist = DistributionTypes.genericDist +@genType +type sampleSetDist = SampleSetDist.t + +@genType +type symbolicDist = SymbolicDistTypes.symbolicDist + @genType type distributionError = DistributionTypes.error @@ -32,11 +38,20 @@ let makeSampleSetDist = SampleSetDist.make let evaluate = Reducer.evaluate @genType -let evaluateUsingExternalBindings = Reducer.evaluateUsingExternalBindings +let evaluateUsingOptions = Reducer.evaluateUsingOptions + +@genType +let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings + +@genType +type externalBindings = Reducer.externalBindings @genType type expressionValue = ReducerInterface_ExpressionValue.expressionValue +@genType +type recordEV = ReducerInterface_ExpressionValue.record + @genType type errorValue = Reducer_ErrorValue.errorValue @@ -57,3 +72,15 @@ let errorValueToString = Reducer_ErrorValue.errorToString @genType let distributionErrorToString = DistributionTypes.Error.toString + +@genType +type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue + +@genType +let defaultSamplingEnv = ReducerInterface_GenericDistribution.defaultEnv + +@genType +type environment = ReducerInterface_ExpressionValue.environment + +@genType +let defaultEnvironment = ReducerInterface_ExpressionValue.defaultEnvironment diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index a110f1b7..1445a80c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -198,6 +198,7 @@ module Float = { let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) let toFixed = Js.Float.toFixed let toString = Js.Float.toString + let isFinite = Js.Float.isFinite } module I = { @@ -217,6 +218,12 @@ module R = { | Error(err) => errF(err) } let id = e => e |> result(U.id, U.id) + let isOk = Belt.Result.isOk + let getError = (r: result<'a, 'b>) => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } let fmap = (f: 'a => 'b, r: result<'a, 'c>): result<'b, 'c> => { switch r { | Ok(r') => Ok(f(r')) @@ -283,6 +290,13 @@ module R = { | Ok(r) => r->Ok | Error(x) => x->f->Error } + + //I'm not sure what to call this. + let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => + switch a { + | Ok(x) => x + | Error(x) => c(x) + } } module R2 = { @@ -301,6 +315,8 @@ module R2 = { | Ok(x) => x->Ok | Error(x) => x->f->Error } + + let toExn = (a, b) => R.toExn(b, a) } let safe_fn_of_string = (fn, s: string): option<'a> => @@ -344,7 +360,7 @@ module JsDate = { /* List */ module L = { module Util = { - let eq = (a, b) => a == b + let eq = \"==" } let fmap = List.map let get = Belt.List.get @@ -645,42 +661,81 @@ module A = { } } - module Sorted = { - let min = first - let max = last - let range = (~min=min, ~max=max, a) => - switch (min(a), max(a)) { - | (Some(min), Some(max)) => Some(max -. min) - | _ => None - } + module Floats = { + type t = array + let mean = Jstat.mean + let geomean = Jstat.geomean + let mode = Jstat.mode + let variance = Jstat.variance + let stdev = Jstat.stdev + let sum = Jstat.sum + let random = Js.Math.random_int let floatCompare: (float, float) => int = compare + let sort = t => { + let r = t + r |> Array.fast_sort(floatCompare) + r + } - let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { - let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) - let el = el < 0 ? el * -1 - 1 : el - switch el { - | e if e >= length(ar) => #overMax - | e if e == 0 => #underMin - | e => #firstHigher(e) + let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) + let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) + + let isSorted = (t: t): bool => + if Array.length(t) < 1 { + true + } else { + reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) } - } - let concat = (t1: array<'a>, t2: array<'a>) => { - let ts = Belt.Array.concat(t1, t2) - ts |> Array.fast_sort(floatCompare) - ts - } + //Passing true for the exclusive parameter excludes both endpoints of the range. + //https://jstat.github.io/all.html + let percentile = (a, b) => Jstat.percentile(a, b, false) - let concatMany = (t1: array>) => { - let ts = Belt.Array.concatMany(t1) - ts |> Array.fast_sort(floatCompare) - ts - } + // Gives an array with all the differences between values + // diff([1,5,3,7]) = [4,-2,4] + let diff = (t: t): array => + Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) - module Floats = { - let isSorted = (ar: array): bool => - reduce(zip(ar, tail(ar)), true, (acc, (first, second)) => acc && first < second) + exception RangeError(string) + let range = (min: float, max: float, n: int): array => + switch n { + | 0 => [] + | 1 => [min] + | 2 => [min, max] + | _ if min == max => Belt.Array.make(n, min) + | _ if n < 0 => raise(RangeError("n must be greater than 0")) + | _ if min > max => raise(RangeError("Min value is less then max value")) + | _ => + let diff = (max -. min) /. Belt.Float.fromInt(n - 1) + Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) + } + + let min = Js.Math.minMany_float + let max = Js.Math.maxMany_float + + module Sorted = { + let min = first + let max = last + let range = (~min=min, ~max=max, a) => + switch (min(a), max(a)) { + | (Some(min), Some(max)) => Some(max -. min) + | _ => None + } + + let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { + let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) + let el = el < 0 ? el * -1 - 1 : el + switch el { + | e if e >= length(ar) => #overMax + | e if e == 0 => #underMin + | e => #firstHigher(e) + } + } + + let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort + + let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort let makeIncrementalUp = (a, b) => Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) @@ -743,47 +798,13 @@ module A = { } } } - - module Floats = { - let mean = Jstat.mean - let geomean = Jstat.geomean - let mode = Jstat.mode - let variance = Jstat.variance - let stdev = Jstat.stdev - let sum = Jstat.sum - let random = Js.Math.random_int - - //Passing true for the exclusive parameter excludes both endpoints of the range. - //https://jstat.github.io/all.html - let percentile = (a, b) => Jstat.percentile(a, b, false) - - // Gives an array with all the differences between values - // diff([1,5,3,7]) = [4,-2,4] - let diff = (arr: array): array => - Belt.Array.zipBy(arr, Belt.Array.sliceToEnd(arr, 1), (left, right) => right -. left) - - exception RangeError(string) - let range = (min: float, max: float, n: int): array => - switch n { - | 0 => [] - | 1 => [min] - | 2 => [min, max] - | _ if min == max => Belt.Array.make(n, min) - | _ if n < 0 => raise(RangeError("n must be greater than 0")) - | _ if min > max => raise(RangeError("Min value is less then max value")) - | _ => - let diff = (max -. min) /. Belt.Float.fromInt(n - 1) - Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) - } - - let min = Js.Math.minMany_float - let max = Js.Math.maxMany_float - } + module Sorted = Floats.Sorted } module A2 = { let fmap = (a, b) => A.fmap(b, a) let joinWith = (a, b) => A.joinWith(b, a) + let filter = (a, b) => A.filter(b, a) } module JsArray = { diff --git a/packages/squiggle-lang/src/rescript/Utility/Jstat.res b/packages/squiggle-lang/src/rescript/Utility/Jstat.res index 03c43174..1de2e8ed 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Jstat.res +++ b/packages/squiggle-lang/src/rescript/Utility/Jstat.res @@ -81,6 +81,14 @@ module Binomial = { @module("jstat") @scope("binomial") external cdf: (float, float, float) => float = "cdf" } +module Gamma = { + @module("jstat") @scope("gamma") external pdf: (float, float, float) => float = "pdf" + @module("jstat") @scope("gamma") external cdf: (float, float, float) => float = "cdf" + @module("jstat") @scope("gamma") external inv: (float, float, float) => float = "inv" + @module("jstat") @scope("gamma") external mean: (float, float) => float = "mean" + @module("jstat") @scope("gamma") external sample: (float, float) => float = "sample" +} + @module("jstat") external sum: array => float = "sum" @module("jstat") external product: array => float = "product" @module("jstat") external min: array => float = "min" diff --git a/packages/squiggle-lang/src/rescript/Utility/XYShape.res b/packages/squiggle-lang/src/rescript/Utility/XYShape.res index 97974884..1f1e87ca 100644 --- a/packages/squiggle-lang/src/rescript/Utility/XYShape.res +++ b/packages/squiggle-lang/src/rescript/Utility/XYShape.res @@ -4,6 +4,42 @@ type xyShape = { ys: array, } +type propertyName = string + +@genType +type rec error = + | NotSorted(propertyName) + | IsEmpty(propertyName) + | NotFinite(propertyName, float) + | DifferentLengths({p1Name: string, p2Name: string, p1Length: int, p2Length: int}) + | MultipleErrors(array) + +@genType +module Error = { + let mapErrorArrayToError = (errors: array): option => { + switch errors { + | [] => None + | [error] => Some(error) + | _ => Some(MultipleErrors(errors)) + } + } + + let rec toString = (t: error) => + switch t { + | NotSorted(propertyName) => `${propertyName} is not sorted` + | IsEmpty(propertyName) => `${propertyName} is empty` + | NotFinite(propertyName, exampleValue) => + `${propertyName} is not finite. Example value: ${E.Float.toString(exampleValue)}` + | DifferentLengths({p1Name, p2Name, p1Length, p2Length}) => + `${p1Name} and ${p2Name} have different lengths. ${p1Name} has length ${E.I.toString( + p1Length, + )} and ${p2Name} has length ${E.I.toString(p2Length)}` + | MultipleErrors(errors) => + `Multiple Errors: ${E.A2.fmap(errors, toString)->E.A2.fmap(r => `[${r}]`) + |> E.A.joinWith(", ")}` + } +} + @genType type interpolationStrategy = [ | #Stepwise @@ -60,6 +96,44 @@ module T = { let fromZippedArray = (pairs: array<(float, float)>): t => pairs |> Belt.Array.unzip |> fromArray let equallyDividedXs = (t: t, newLength) => E.A.Floats.range(minX(t), maxX(t), newLength) let toJs = (t: t) => {"xs": t.xs, "ys": t.ys} + + module Validator = { + let fnName = "XYShape validate" + let notSortedError = (p: string): error => NotSorted(p) + let notFiniteError = (p, exampleValue): error => NotFinite(p, exampleValue) + let isEmptyError = (propertyName): error => IsEmpty(propertyName) + let differentLengthsError = (t): error => DifferentLengths({ + p1Name: "Xs", + p2Name: "Ys", + p1Length: E.A.length(xs(t)), + p2Length: E.A.length(ys(t)), + }) + + let areXsSorted = (t: t) => E.A.Floats.isSorted(xs(t)) + let areXsEmpty = (t: t) => E.A.length(xs(t)) == 0 + let getNonFiniteXs = (t: t) => t->xs->E.A.Floats.getNonFinite + let getNonFiniteYs = (t: t) => t->ys->E.A.Floats.getNonFinite + + let validate = (t: t) => { + let xsNotSorted = areXsSorted(t) ? None : Some(notSortedError("Xs")) + let xsEmpty = areXsEmpty(t) ? Some(isEmptyError("Xs")) : None + let differentLengths = + E.A.length(xs(t)) !== E.A.length(ys(t)) ? Some(differentLengthsError(t)) : None + let xsNotFinite = getNonFiniteXs(t)->E.O2.fmap(notFiniteError("Xs")) + let ysNotFinite = getNonFiniteYs(t)->E.O2.fmap(notFiniteError("Ys")) + [xsNotSorted, xsEmpty, differentLengths, xsNotFinite, ysNotFinite] + ->E.A.O.concatSomes + ->Error.mapErrorArrayToError + } + } + + let make = (~xs: array, ~ys: array) => { + let attempt: t = {xs: xs, ys: ys} + switch Validator.validate(attempt) { + | Some(error) => Error(error) + | None => Ok(attempt) + } + } } module Ts = { diff --git a/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md b/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md index 8ec5b88d..405bc97c 100644 --- a/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md +++ b/packages/website/docs/Discussions/Three-Formats-Of-Distributions.md @@ -11,7 +11,7 @@ _Symbolic_ formats are just the math equations. `normal(5,3)` is the symbolic re When you sample distributions (usually starting with symbolic formats), you get lists of samples. Monte Carlo techniques return lists of samples. Let’s call this the “_Sample Set_” format. -Lastly is what I’ll refer to as the _Graph_ format. It describes the coordinates, or the shape, of the distribution. You can save these formats in JSON, for instance, like, `{xs: [1, 2, 3, 4…], ys: [.0001, .0003, .002, …]}`. +Lastly is what I’ll refer to as the _Graph_ format. It describes the coordinates, or the shape, of the distribution. You can save these formats in JSON, for instance, like, `{xs: [1, 2, 3, 4, …], ys: [.0001, .0003, .002, …]}`. Symbolic, Sample Set, and Graph formats all have very different advantages and disadvantages. @@ -19,7 +19,7 @@ Note that the name "Symbolic" is fairly standard, but I haven't found common nam ## Symbolic Formats -**TLDR** +**TL;DR** Mathematical representations. Require analytic solutions. These are often ideal where they can be applied, but apply to very few actual functions. Typically used sparsely, except for the starting distributions (before any computation is performed). **Examples** @@ -29,9 +29,6 @@ Mathematical representations. Require analytic solutions. These are often ideal **How to Do Computation** To perform calculations of symbolic systems, you need to find analytical solutions. For example, there are equations to find the pdf or cdf of most distribution shapes at any point. There are also lots of simplifications that could be done in particular situations. For example, there’s an analytical solution for combining normal distributions. -**Special: The Metalog Distribution** -The Metalog distribution seems like it can represent almost any reasonable distribution. It’s symbolic. This is great for storage, but it’s not clear if it helps with calculation. My impression is that we don’t have symbolic ways of doing most functions (addition, multiplication, etc) on metalog distributions. Also, note that it can take a fair bit of computation to fit a shape to the Metalog distribution. - **Advantages** - Maximally compressed; i.e. very easy to store. @@ -54,10 +51,14 @@ The Metalog distribution seems like it can represent almost any reasonable distr **How to Visualize** Convert to graph, then display that. (Optionally, you can also convert to samples, then display those using a histogram, but this is often worse you have both options.) +**Bonus: The Metalog Distribution** + +The Metalog distribution seems like it can represent almost any reasonable distribution. It’s symbolic. This is great for storage, but it’s not clear if it helps with calculation. My impression is that we don’t have symbolic ways of doing most functions (addition, multiplication, etc) on metalog distributions. Also, note that it can take a fair bit of computation to fit a shape to the Metalog distribution. + ## Graph Formats -**TLDR** -Lists of the x-y coordinates of the shape of a distribution. (Usually the pdf, which is more compressed than the cdf). Some key functions (like pdf, cdf) and manipulations can work on almost any graphally-described distribution. +**TL;DR** +Lists of the x-y coordinates of the shape of a distribution. (Usually the pdf, which is more compressed than the cdf). Some key functions (like pdf, cdf) and manipulations can work on almost any graphically-described distribution. **Alternative Names:** Grid, Mesh, Graph, Vector, Pdf, PdfCoords/PdfPoints, Discretised, Bezier, Curve @@ -77,7 +78,7 @@ Use graph techniques. These can be fairly computationally-intensive (particularl **Disadvantages** -- Most calculations are infeasible/impossible to perform graphally. In these cases, you need to use sampling. +- Most calculations are infeasible/impossible to perform graphically. In these cases, you need to use sampling. - Not as accurate or fast as symbolic methods, where the symbolic methods are applicable. - The tails get cut off, which is subideal. It’s assumed that the value of the pdf outside of the bounded range is exactly 0, which is not correct. (Note: If you have ideas on how to store graph formats that don’t cut off tails, let me know) @@ -108,7 +109,7 @@ Use graph techniques. These can be fairly computationally-intensive (particularl ## Sample Set Formats -**TLDR** +**TL;DR** Random samples. Use Monte Carlo simulation to perform calculations. This is the predominant technique using Monte Carlo methods; in these cases, most nodes are essentially represented as sample sets. [Guesstimate](https://www.getguesstimate.com/) works this way. **How to Do Computation** diff --git a/packages/website/docs/Features/Distributions.mdx b/packages/website/docs/Features/Distributions.mdx new file mode 100644 index 00000000..28e1db01 --- /dev/null +++ b/packages/website/docs/Features/Distributions.mdx @@ -0,0 +1,360 @@ +--- +title: "Distribution Creation" +sidebar_position: 8 +--- + +import TOCInline from "@theme/TOCInline"; +import { SquiggleEditor } from "../../src/components/SquiggleEditor"; +import Admonition from "@theme/Admonition"; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; + + + +## To + +`(5thPercentile: number) to (95thPercentile: number)` +`to(5thPercentile: number, 95thPercentile: number)` + +The `to` function is an easy way to generate simple distributions using predicted _5th_ and _95th_ percentiles. + +If both values are above zero, a `lognormal` distribution is used. If not, a `normal` distribution is used. + + + + When 5 to 10 is entered, both numbers are positive, so it + generates a lognormal distribution with 5th and 95th percentiles at 5 and + 10. + + + + 5 to 10 does the same thing as to(5,10). + + + + When -5 to 5 is entered, there's negative values, so it + generates a normal distribution. This has 5th and 95th percentiles at 5 and + 10. + + + + It's very easy to generate distributions with very long tails. If this + happens, you can click the "log x scale" box to view this using a log scale. + + + + +### Arguments + +- `5thPercentile`: number +- `95thPercentile`: number, greater than `5thPercentile` + + +

+ "To" is a great way to generate probability distributions very + quickly from your intuitions. It's easy to write and easy to read. It's + often a good place to begin an estimate. +

+
+ + +

+ If you haven't tried{" "} + + calibration training + + , you're likely to be overconfident. We recommend doing calibration training + to get a feel for what a 90 percent confident interval feels like. +

+
+ +## Mixture + +`mixture(...distributions: Distribution[], weights?: number[])` +`mx(...distributions: Distribution[], weights?: number[])` + +The `mixture` mixes combines multiple distributions to create a mixture. You can optionally pass in a list of proportional weights. + + + + + + + + + + + + + +### Arguments + +- `distributions`: A set of distributions or numbers, each passed as a paramater. Numbers will be converted into Delta distributions. +- `weights`: An optional array of numbers, each representing the weight of its corresponding distribution. The weights will be re-scaled to add to `1.0`. If a weights array is provided, it must be the same length as the distribution paramaters. + +### Aliases + +- `mx` + +### Special Use Cases of Mixtures + +
+ 🕐 Zero or Continuous +

+ One common reason to have mixtures of continous and discrete distributions is to handle the special case of 0. + Say I want to model the time I will spend on some upcoming project. I think I have an 80% chance of doing it. +

+ +

+ In this case, I have a 20% chance of spending 0 time with it. I might estimate my hours with, +

+ +
+ +
+ 🔒 Model Uncertainty Safeguarding +

+ One technique several Foretold.io users used is to combine their main guess, with a + "just-in-case distribution". This latter distribution would have very low weight, but would be + very wide, just in case they were dramatically off for some weird reason. +

+ + +
+ +## Normal + +`normal(mean:number, standardDeviation:number)` + +Creates a [normal distribution](https://en.wikipedia.org/wiki/Normal_distribution) with the given mean and standard deviation. + + + + + + + + + + +### Arguments + +- `mean`: Number +- `standard deviation`: Number greater than zero + +[Wikipedia](https://en.wikipedia.org/wiki/Normal_distribution) + +## Log-normal + +`lognormal(mu: number, sigma: number)` + +Creates a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution) with the given mu and sigma. + +`Mu` and `sigma` represent the mean and standard deviation of the normal which results when +you take the log of our lognormal distribution. They can be difficult to directly reason about. +Because of this complexity, we recommend typically using the to syntax instead of estimating `mu` and `sigma` directly. + + + +### Arguments + +- `mu`: Number +- `sigma`: Number greater than zero + +[Wikipedia](https://en.wikipedia.org/wiki/Log-normal_distribution) + +
+ + ❓ Understanding mu and sigma + +

+ The log of lognormal(mu, sigma) is a normal distribution with + mean mu + and standard deviation sigma. For example, these two distributions + are identical: +

+ +
+ +## Uniform + +`uniform(low:number, high:number)` + +Creates a [uniform distribution]() with the given low and high values. + + + +### Arguments + +- `low`: Number +- `high`: Number greater than `low` + + +

+ While uniform distributions are very simple to understand, we find it rare + to find uncertainties that actually look like this. Before using a uniform + distribution, think hard about if you are really 100% confident that the + paramater will not wind up being just outside the stated boundaries. +

+ +

+ One good example of a uniform distribution uncertainty would be clear + physical limitations. You might have complete complete uncertainty on what + time of day an event will occur, but can say with 100% confidence it will + happen between the hours of 0:00 and 24:00. +

+
+ +## Delta + +`delta(value:number)` + +Creates a discrete distribution with all of its probability mass at point `value`. + +Few Squiggle users call the function `delta()` directly. Numbers are converted into delta distributions automatically, when it is appropriate. + +For example, in the function `mixture(1,2,normal(5,2))`, the first two arguments will get converted into delta distributions +with values at 1 and 2. Therefore, this is the same as `mixture(delta(1),delta(2),normal(5,2))`. + +`Delta()` distributions are currently the only discrete distributions accessible in Squiggle. + + + + + + + + + + + + + + + + + + + +### Arguments + +- `value`: Number + +## Beta + +`beta(alpha:number, beta:number)` + +Creates a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) with the given `alpha` and `beta` values. For a good summary of the beta distribution, see [this explanation](https://stats.stackexchange.com/a/47782) on Stack Overflow. + + + + + + + + + + + + + + + + + + + +### Arguments + +- `alpha`: Number greater than zero +- `beta`: Number greater than zero + + +

+ Squiggle struggles to show beta distributions when either alpha or beta are + below 1.0. This is because the tails at ~0.0 and ~1.0 are very high. Using a + log scale for the y-axis helps here. +

+
+ Examples + + + + + + + + + + + + + + +
+
+ +## Exponential + +`exponential(rate:number)` + +Creates an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) with the given rate. + + + +### Arguments + +- `rate`: Number greater than zero + +## Triangular distribution + +`triangular(low:number, mode:number, high:number)` + +Creates a [triangular distribution](https://en.wikipedia.org/wiki/Triangular_distribution) with the given low, mode, and high values. + +### Arguments + +- `low`: Number +- `mode`: Number greater than `low` +- `high`: Number greater than `mode` + + + +## FromSamples + +`fromSamples(samples:number[])` + +Creates a sample set distribution using an array of samples. + + + +### Arguments + +- `samples`: An array of at least 5 numbers. + + +

+ Samples are converted into{" "} + PDF{" "} + shapes automatically using{" "} + + kernel density estimation + {" "} + and an approximated bandwidth. Eventually Squiggle will allow for more + specificity. +

+
diff --git a/packages/website/docs/Features/Functions.mdx b/packages/website/docs/Features/Functions.mdx index e37ea315..46bc4e39 100644 --- a/packages/website/docs/Features/Functions.mdx +++ b/packages/website/docs/Features/Functions.mdx @@ -5,131 +5,15 @@ sidebar_position: 7 import { SquiggleEditor } from "../../src/components/SquiggleEditor"; -_The source of truth for this document is [this file of code](https://github.com/quantified-uncertainty/squiggle/blob/develop/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res)_ - -## Inventory distributions - -We provide starter distributions, computed symbolically. - -### Normal distribution - -The `normal(mean, sd)` function creates a normal distribution with the given mean -and standard deviation. - - - -#### Validity - -- `sd > 0` - -### Uniform distribution - -The `uniform(low, high)` function creates a uniform distribution between the -two given numbers. - - - -#### Validity - -- `low < high` - -### Lognormal distribution - -The `lognormal(mu, sigma)` returns the log of a normal distribution with parameters -`mu` and `sigma`. The log of `lognormal(mu, sigma)` is a normal distribution with mean `mu` and standard deviation `sigma`. - - - -An alternative format is also available. The `to` notation creates a lognormal -distribution with a 90% confidence interval between the two numbers. We add -this convenience as lognormal distributions are commonly used in practice. - - - -#### Future feature: - -Furthermore, it's also possible to create a lognormal from it's actual mean -and standard deviation, using `lognormalFromMeanAndStdDev`. - -TODO: interpreter/parser doesn't provide this in current `develop` branch - - - -#### Validity - -- `sigma > 0` -- In `x to y` notation, `x < y` - -### Beta distribution - -The `beta(a, b)` function creates a beta distribution with parameters `a` and `b`: - - - -#### Validity - -- `a > 0` -- `b > 0` -- Empirically, we have noticed that numerical instability arises when `a < 1` or `b < 1` - -### Exponential distribution - -The `exponential(rate)` function creates an exponential distribution with the given -rate. - - - -#### Validity - -- `rate > 0` - -### Triangular distribution - -The `triangular(a,b,c)` function creates a triangular distribution with lower -bound `a`, mode `b` and upper bound `c`. - -#### Validity - -- `a < b < c` - - - -### Scalar (constant dist) - -Squiggle, when the context is right, automatically casts a float to a constant distribution. - ## Operating on distributions Here are the ways we combine distributions. -### Mixture of distributions - -The `mixture` function combines 2 or more other distributions to create a weighted -combination of the two. The first positional arguments represent the distributions -to be combined, and the last argument is how much to weigh every distribution in the -combination. - - - -It's possible to create discrete distributions using this method. - - - -As well as mixed distributions: - - - -An alias of `mixture` is `mx` - -#### Validity - -Using javascript's variable arguments notation, consider `mx(...dists, weights)`: - -- `dists.length == weights.length` - ### Addition -A horizontal right shift +A horizontal right shift. The addition operation represents the distribution of the sum of +the value of one random sample chosen from the first distribution and the value one random sample +chosen from the second distribution. @@ -186,6 +80,8 @@ exp(dist)`} ### Taking logarithms +A projection over a stretched x-axis. + @@ -284,7 +182,8 @@ or all values lower than x. It is the inverse of `inv`. ### Inverse CDF The `inv(dist, prob)` gives the value x or which the probability for all values -lower than x is equal to prob. It is the inverse of `cdf`. +lower than x is equal to prob. It is the inverse of `cdf`. In the literature, it +is also known as the quantiles function. @@ -315,6 +214,16 @@ Or `PointSet` format +### `toSampleSet` has two signatures + +Above, we saw the unary `toSampleSet`, which uses an internal hardcoded number of samples. If you'd like to provide the number of samples, it has a binary signature as well (floored) + + + +#### Validity + +- Second argument to `toSampleSet` must be a number. + ## Normalization Some distribution operations (like horizontal shift) return an unnormalized distriibution. @@ -333,18 +242,6 @@ We provide a predicate `isNormalized`, for when we have simple control flow - Input to `isNormalized` must be a dist -## Convert any distribution to a sample set distribution - -`toSampleSet` has two signatures - -It is unary when you use an internal hardcoded number of samples - - - -And binary when you provide a number of samples (floored) - - - ## `inspect` You may like to debug by right clicking your browser and using the _inspect_ functionality on the webpage, and viewing the _console_ tab. Then, wrap your squiggle output with `inspect` to log an internal representation. @@ -361,7 +258,7 @@ You can cut off from the left You can cut off from the right - + You can cut off from both sides diff --git a/packages/website/docs/Features/Language.mdx b/packages/website/docs/Features/Language.mdx index 5b66d2e2..74c703ae 100644 --- a/packages/website/docs/Features/Language.mdx +++ b/packages/website/docs/Features/Language.mdx @@ -7,21 +7,21 @@ import { SquiggleEditor } from "../../src/components/SquiggleEditor"; ## Expressions -A distribution +### Distributions -A number +### Numbers - + -Arrays +### Arrays -Records +### Records = We can define functions ## See more diff --git a/packages/website/docs/Features/Node-Packages.md b/packages/website/docs/Features/Node-Packages.md index ab590c32..381cef1f 100644 --- a/packages/website/docs/Features/Node-Packages.md +++ b/packages/website/docs/Features/Node-Packages.md @@ -30,7 +30,7 @@ this library to help navigate the return type. The `@quri/squiggle-components` package offers several components and utilities for people who want to embed Squiggle components into websites. This documentation -relies on `@quri/squiggle-components` frequently. +uses `@quri/squiggle-components` frequently. We host [a storybook](https://squiggle-components.netlify.app/) with details and usage of each of the components made available. diff --git a/yarn.lock b/yarn.lock index 283b1121..4dc8caf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -131,11 +131,12 @@ "@algolia/requester-common" "4.13.0" "@ampproject/remapping@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" - integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== dependencies: - "@jridgewell/trace-mapping" "^0.3.0" + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" "@ant-design/colors@^6.0.0": version "6.0.0" @@ -1351,7 +1352,7 @@ resolved "https://registry.yarnpkg.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz#a9583a75c3f150667771f30b60d9f059473e62c4" integrity sha512-M0qqxAcwCsIVfpFQSlGN5XjXWu8l5JDZN+fPt1LeW5SZexQTgnaEvgXAY+CeygRw0EeppWHi12JxESWiWrB0Sg== -"@csstools/postcss-color-function@^1.0.3": +"@csstools/postcss-color-function@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.0.tgz#229966327747f58fbe586de35daa139db3ce1e5d" integrity sha512-5D5ND/mZWcQoSfYnSPsXtuiFxhzmhxt6pcjrFLJyldj+p0ZN2vvRpYNX+lahFTtMhAYOa2WmkdGINr0yP0CvGA== @@ -1381,7 +1382,7 @@ "@csstools/postcss-progressive-custom-properties" "^1.1.0" postcss-value-parser "^4.2.0" -"@csstools/postcss-is-pseudo-class@^2.0.1": +"@csstools/postcss-is-pseudo-class@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.2.tgz#a834ca11a43d6ed9bc9e3ff53c80d490a4b1aaad" integrity sha512-L9h1yxXMj7KpgNzlMrw3isvHJYkikZgZE4ASwssTnGEH8tm50L6QsM9QQT5wR4/eO5mU0rN5axH7UzNxEYg5CA== @@ -1395,7 +1396,7 @@ dependencies: postcss-value-parser "^4.2.0" -"@csstools/postcss-oklab-function@^1.0.2": +"@csstools/postcss-oklab-function@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.0.tgz#e9a269487a292e0930760948e923e1d46b638ee6" integrity sha512-e/Q5HopQzmnQgqimG9v3w2IG4VRABsBq3itOcn4bnm+j4enTgQZ0nWsaH/m9GV2otWGQ0nwccYL5vmLKyvP1ww== @@ -1920,10 +1921,10 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@eslint/eslintrc@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.1.tgz#8b5e1c49f4077235516bc9ec7d41378c0f69b8c6" - integrity sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ== +"@eslint/eslintrc@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.2.tgz#4989b9e8c0216747ee7cca314ae73791bb281aae" + integrity sha512-lTVWHs7O2hjBFZunXTZYnYqtB9GakA1lnxIf+gKq2nY5gxkkNi/lQvveW6t8gFdOHTg6nG50Xs95PrLqVpcaLg== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1992,7 +1993,7 @@ dependencies: "@istanbuljs/schema" "^0.1.2" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== @@ -2009,6 +2010,18 @@ jest-util "^27.5.1" slash "^3.0.0" +"@jest/console@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.0.2.tgz#d11e8b43ae431ae9b3112656848417ae4008fcad" + integrity sha512-tiRpnMeeyQuuzgL5UNSeiqMwF8UOWPbAE5rzcu/1zyq4oPG2Ox6xm4YCOruwbp10F8odWc+XwVxTyGzMSLMqxA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.0.2" + jest-util "^28.0.2" + slash "^3.0.0" + "@jest/core@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" @@ -2105,6 +2118,13 @@ terminal-link "^2.0.0" v8-to-istanbul "^8.1.0" +"@jest/schemas@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.0.2.tgz#08c30df6a8d07eafea0aef9fb222c5e26d72e613" + integrity sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA== + dependencies: + "@sinclair/typebox" "^0.23.3" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -2124,6 +2144,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.0.2.tgz#bc8e15a95347e3c2149572ae06a5a6fed939c522" + integrity sha512-4EUqgjq9VzyUiVTvZfI9IRJD6t3NYBNP4f+Eq8Zr93+hkJ0RrGU4OBTw8tfNzidKX+bmuYzn8FxqpxOPIGGCMA== + dependencies: + "@jest/console" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-sequencer@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" @@ -2198,20 +2228,45 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^28.0.2": + version "28.0.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.0.2.tgz#70b9538c1863fb060b2f438ca008b5563d00c5b4" + integrity sha512-hi3jUdm9iht7I2yrV5C4s3ucCJHUP8Eh3W6rQ1s4n/Qw9rQgsda4eqCt+r3BKRi7klVmZfQlMx1nGlzNMP2d8A== + dependencies: + "@jest/schemas" "^28.0.2" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/resolve-uri@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" - integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.6.tgz#4ac237f4dabc8dd93330386907b97591801f7352" + integrity sha512-R7xHtBSNm+9SyvpJkdQl+qrM3Hm2fea3Ef197M3mUug+v+yR+Rhfbs7PBtcBUVnIWJ4JcAdjvij+c8hXS9p5aw== + +"@jridgewell/set-array@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.0.tgz#1179863356ac8fbea64a5a4bcde93a4871012c01" + integrity sha512-SfJxIxNVYLTsKwzB3MoOQ1yxf4w/E6MdkvTgrgAt1bfxjSrLUoHMKrDOykwN14q65waezZIdqDneUIPh4/sKxg== "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.11" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== -"@jridgewell/trace-mapping@^0.3.0": - version "0.3.4" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" - integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== +"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -2345,6 +2400,18 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64" integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw== +"@quri/squiggle-components@0.2.9": + version "0.2.9" + resolved "https://registry.yarnpkg.com/@quri/squiggle-components/-/squiggle-components-0.2.9.tgz#9a2c7ce824ad59f980dc73e465676bd2563d409c" + integrity sha512-RpMTCzf7vBY+fatdjD+iFWkleMYOkJQN7kknZlLBriSo8Fy5KjhKghR+DotU+HE/2Yq1jUIveaIDF0XRBg+SVA== + dependencies: + "@react-hook/size" "^2.1.2" + antd "^4.20.0" + react "^18.0.0" + react-ace "10.0.0" + react-dom "^18.0.0" + styled-components "^5.3.5" + "@react-hook/latest@^1.0.2": version "1.0.3" resolved "https://registry.yarnpkg.com/@react-hook/latest/-/latest-1.0.3.tgz#c2d1d0b0af8b69ec6e2b3a2412ba0768ac82db80" @@ -2412,9 +2479,9 @@ picomatch "^2.2.2" "@rushstack/eslint-patch@^1.1.0": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.2.tgz#7a26e63b1bdaf654bcce2176a38b83f7f576327e" - integrity sha512-oe5WJEDaVsW8fBlGT7udrSCgOwWfoYHQOmSpnh8X+0GXpqqcRCP8k4y+Dxb0taWJDPpB+rdDUtumIiBwkY9qGA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.3.tgz#6801033be7ff87a6b7cadaf5b337c9f366a3c4b0" + integrity sha512-WiBSI6JBIhC6LRIsB2Kwh8DsGTlbBU+mLRxJmAe3LjHTdkDpwIbEOZgoXBbZilk/vlfjK8i6nKRAvIRn1XaIMw== "@ryyppy/rescript-promise@^2.1.0": version "2.1.0" @@ -2438,6 +2505,11 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== +"@sinclair/typebox@^0.23.3": + version "0.23.5" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.23.5.tgz#93f7b9f4e3285a7a9ade7557d9a8d36809cbc47d" + integrity sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3682,10 +3754,10 @@ lodash "^4.17.15" redent "^3.0.0" -"@testing-library/react@^13.1.1": - version "13.1.1" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.1.1.tgz#6c1635e25acca8ca5be8ee3b19ad1391681c5846" - integrity sha512-8mirlAa0OKaUvnqnZF6MdAh2tReYA2KtWVw1PKvaF5EcCZqgK5pl8iF+3uW90JdG5Ua2c2c2E2wtLdaug3dsVg== +"@testing-library/react@^13.2.0": + version "13.2.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.2.0.tgz#2db00bc94d71c4e90e5c25582e90a650ae2925bf" + integrity sha512-Bprbz/SZVONCJy5f7hcihNCv313IJXdYiv0nSJklIs1SQCIHHNlnGNkosSXnGZTmesyGIcBGNppYhXcc11pb7g== dependencies: "@babel/runtime" "^7.12.5" "@testing-library/dom" "^8.5.0" @@ -3758,9 +3830,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.17.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" - integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== + version "7.17.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.1.tgz#1a0e73e8c28c7e832656db372b779bfd2ef37314" + integrity sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA== dependencies: "@babel/types" "^7.3.0" @@ -3945,14 +4017,19 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@^27.4.0": - version "27.4.1" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.4.1.tgz#185cbe2926eaaf9662d340cc02e548ce9e11ab6d" - integrity sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw== +"@types/jest@*", "@types/jest@^27.5.0": + version "27.5.0" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.0.tgz#e04ed1824ca6b1dd0438997ba60f99a7405d4c7b" + integrity sha512-9RBFx7r4k+msyj/arpfaa0WOOEcaAZNmN+j80KFbFCoSqCJGHTz7YMAMGQW9Xmqm5w6l5c25vbSjMwlikJi5+g== dependencies: jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" +"@types/js-cookie@^2.2.6": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.7.tgz#226a9e31680835a6188e887f3988e60c04d3f6a3" + integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== + "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" @@ -3998,15 +4075,15 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@^17.0.29", "@types/node@^17.0.5": - version "17.0.29" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.29.tgz#7f2e1159231d4a077bb660edab0fde373e375a3d" - integrity sha512-tx5jMmMFwx7wBwq/V7OohKDVb/JwJU5qCVkeLMh1//xycAJ/ESuw9aJ9SEtlCZDYi2pBfe4JkisSoAtbOsBNAA== +"@types/node@*", "@types/node@^17.0.31", "@types/node@^17.0.5": + version "17.0.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d" + integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== "@types/node@^14.0.10": - version "14.18.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.13.tgz#6ad4d9db59e6b3faf98dcfe4ca9d2aec84443277" - integrity sha512-Z6/KzgyWOga3pJNS42A+zayjhPbf2zM3hegRQaOPnLOzEi86VV++6FLDWgR1LGrVCRufP/ph2daa3tEa5br1zA== + version "14.18.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.16.tgz#878f670ba3f00482bf859b6550b6010610fc54b5" + integrity sha512-X3bUMdK/VmvrWdoTkz+VCn6nwKwrKCFTHtqwBIaQJNx4RUIBBUFXM00bqPz/DsDd+Icjmzm6/tyYZzeGVqb6/Q== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -4068,17 +4145,10 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-dom@^18.0.0": - version "18.0.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.0.tgz#b13f8d098e4b0c45df4f1ed123833143b0c71141" - integrity sha512-49897Y0UiCGmxZqpC8Blrf6meL8QUla6eb+BBhn69dTXlmuOlzkfr7HHY/O8J25e1lTUMs+YYxSlVDAaGHCOLg== - dependencies: - "@types/react" "*" - -"@types/react-dom@^18.0.2": - version "18.0.2" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.2.tgz#2d6b46557aa30257e87e67a6d952146d15979d79" - integrity sha512-UxeS+Wtj5bvLRREz9tIgsK4ntCuLDo0EcAcACgw3E+9wE8ePDr9uQpq53MfcyxyIS55xJ+0B6mDS8c4qkkHLBg== +"@types/react-dom@^18.0.0", "@types/react-dom@^18.0.2": + version "18.0.3" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.3.tgz#a022ea08c75a476fe5e96b675c3e673363853831" + integrity sha512-1RRW9kst+67gveJRYPxGmVy8eVJ05O43hg77G2j5m76/RFJtMbcfAs2viQ2UNsvvDg8F7OfQZx8qQcl6ymygaQ== dependencies: "@types/react" "*" @@ -4131,10 +4201,10 @@ dependencies: "@types/node" "*" -"@types/retry@^0.12.0": - version "0.12.1" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" - integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/sax@^1.2.1": version "1.2.4" @@ -4219,9 +4289,9 @@ integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== "@types/webpack-env@^1.16.0": - version "1.16.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.3.tgz#b776327a73e561b71e7881d0cd6d34a1424db86a" - integrity sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw== + version "1.16.4" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.4.tgz#1f4969042bf76d7ef7b5914f59b3b60073f4e1f4" + integrity sha512-llS8qveOUX3wxHnSykP5hlYFFuMfJ9p5JvIyCiBgp7WTfl6K5ZcyHj8r8JsN/J6QODkAsRRCLIcTuOCu8etkUw== "@types/webpack-sources@*": version "3.2.0" @@ -4279,14 +4349,21 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^5.5.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.19.0.tgz#9608a4b6d0427104bccf132f058cba629a6553c0" - integrity sha512-w59GpFqDYGnWFim9p6TGJz7a3qWeENJuAKCqjGSx+Hq/bwq3RZwXYqy98KIfN85yDqz9mq6QXiY5h0FjGQLyEg== +"@types/yargs@^17.0.8": + version "17.0.10" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.10.tgz#591522fce85d8739bca7b8bb90d048e4478d186a" + integrity sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA== dependencies: - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/type-utils" "5.19.0" - "@typescript-eslint/utils" "5.19.0" + "@types/yargs-parser" "*" + +"@typescript-eslint/eslint-plugin@^5.5.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.21.0.tgz#bfc22e0191e6404ab1192973b3b4ea0461c1e878" + integrity sha512-fTU85q8v5ZLpoZEyn/u1S2qrFOhi33Edo2CZ0+q1gDaWWm0JuPh3bgOyU8lM0edIEYgKLDkPFiZX2MOupgjlyg== + dependencies: + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/type-utils" "5.21.0" + "@typescript-eslint/utils" "5.21.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -4295,75 +4372,75 @@ tsutils "^3.21.0" "@typescript-eslint/experimental-utils@^5.0.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.19.0.tgz#b7c8f1e22624d4f3d1b3683438530f5636086cb7" - integrity sha512-F+X/TTzmb2UXbghY1LrNLNDjMcGZMhKzXuzvu0xD+YEB77EamLM7zMOLuz2kP5807IJRDLBoAFFPYa7HT62sYg== + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.21.0.tgz#489275ca792f5de7e0d1f4be1f15576ea56b6ca2" + integrity sha512-mzF6ert/6iQoESV0z9v5/mEaJRKL4fv68rHoZ6exM38xjxkw4MNx54B7ferrnMTM/GIRKLDaJ3JPRi+Dxa5Hlg== dependencies: - "@typescript-eslint/utils" "5.19.0" + "@typescript-eslint/utils" "5.21.0" "@typescript-eslint/parser@^5.5.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.19.0.tgz#05e587c1492868929b931afa0cb5579b0f728e75" - integrity sha512-yhktJjMCJX8BSBczh1F/uY8wGRYrBeyn84kH6oyqdIJwTGKmzX5Qiq49LRQ0Jh0LXnWijEziSo6BRqny8nqLVQ== + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.21.0.tgz#6cb72673dbf3e1905b9c432175a3c86cdaf2071f" + integrity sha512-8RUwTO77hstXUr3pZoWZbRQUxXcSXafZ8/5gpnQCfXvgmP9gpNlRGlWzvfbEQ14TLjmtU8eGnONkff8U2ui2Eg== dependencies: - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/typescript-estree" "5.19.0" + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/typescript-estree" "5.21.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.19.0.tgz#97e59b0bcbcb54dbcdfba96fc103b9020bbe9cb4" - integrity sha512-Fz+VrjLmwq5fbQn5W7cIJZ066HxLMKvDEmf4eu1tZ8O956aoX45jAuBB76miAECMTODyUxH61AQM7q4/GOMQ5g== +"@typescript-eslint/scope-manager@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.21.0.tgz#a4b7ed1618f09f95e3d17d1c0ff7a341dac7862e" + integrity sha512-XTX0g0IhvzcH/e3393SvjRCfYQxgxtYzL3UREteUneo72EFlt7UNoiYnikUtmGVobTbhUDByhJ4xRBNe+34kOQ== dependencies: - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/visitor-keys" "5.19.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/visitor-keys" "5.21.0" -"@typescript-eslint/type-utils@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.19.0.tgz#80f2125b0dfe82494bbae1ea99f1c0186d420282" - integrity sha512-O6XQ4RI4rQcBGshTQAYBUIGsKqrKeuIOz9v8bckXZnSeXjn/1+BDZndHLe10UplQeJLXDNbaZYrAytKNQO2T4Q== +"@typescript-eslint/type-utils@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.21.0.tgz#ff89668786ad596d904c21b215e5285da1b6262e" + integrity sha512-MxmLZj0tkGlkcZCSE17ORaHl8Th3JQwBzyXL/uvC6sNmu128LsgjTX0NIzy+wdH2J7Pd02GN8FaoudJntFvSOw== dependencies: - "@typescript-eslint/utils" "5.19.0" + "@typescript-eslint/utils" "5.21.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.19.0.tgz#12d3d600d754259da771806ee8b2c842d3be8d12" - integrity sha512-zR1ithF4Iyq1wLwkDcT+qFnhs8L5VUtjgac212ftiOP/ZZUOCuuF2DeGiZZGQXGoHA50OreZqLH5NjDcDqn34w== +"@typescript-eslint/types@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.21.0.tgz#8cdb9253c0dfce3f2ab655b9d36c03f72e684017" + integrity sha512-XnOOo5Wc2cBlq8Lh5WNvAgHzpjnEzxn4CJBwGkcau7b/tZ556qrWXQz4DJyChYg8JZAD06kczrdgFPpEQZfDsA== -"@typescript-eslint/typescript-estree@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.19.0.tgz#fc987b8f62883f9ea6a5b488bdbcd20d33c0025f" - integrity sha512-dRPuD4ocXdaE1BM/dNR21elSEUPKaWgowCA0bqJ6YbYkvtrPVEvZ+zqcX5a8ECYn3q5iBSSUcBBD42ubaOp0Hw== +"@typescript-eslint/typescript-estree@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.21.0.tgz#9f0c233e28be2540eaed3df050f0d54fb5aa52de" + integrity sha512-Y8Y2T2FNvm08qlcoSMoNchh9y2Uj3QmjtwNMdRQkcFG7Muz//wfJBGBxh8R7HAGQFpgYpdHqUpEoPQk+q9Kjfg== dependencies: - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/visitor-keys" "5.19.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/visitor-keys" "5.21.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.19.0", "@typescript-eslint/utils@^5.13.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.19.0.tgz#fe87f1e3003d9973ec361ed10d36b4342f1ded1e" - integrity sha512-ZuEckdupXpXamKvFz/Ql8YnePh2ZWcwz7APICzJL985Rp5C2AYcHO62oJzIqNhAMtMK6XvrlBTZeNG8n7gS3lQ== +"@typescript-eslint/utils@5.21.0", "@typescript-eslint/utils@^5.13.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.21.0.tgz#51d7886a6f0575e23706e5548c7e87bce42d7c18" + integrity sha512-q/emogbND9wry7zxy7VYri+7ydawo2HDZhRZ5k6yggIvXa7PvBbAAZ4PFH/oZLem72ezC4Pr63rJvDK/sTlL8Q== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.19.0" - "@typescript-eslint/types" "5.19.0" - "@typescript-eslint/typescript-estree" "5.19.0" + "@typescript-eslint/scope-manager" "5.21.0" + "@typescript-eslint/types" "5.21.0" + "@typescript-eslint/typescript-estree" "5.21.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.19.0": - version "5.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.19.0.tgz#c84ebc7f6c744707a361ca5ec7f7f64cd85b8af6" - integrity sha512-Ym7zZoMDZcAKWsULi2s7UMLREdVQdScPQ/fKWMYefarCztWlHPFVJo8racf8R0Gc8FAEJ2eD4of8As1oFtnQlQ== +"@typescript-eslint/visitor-keys@5.21.0": + version "5.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.21.0.tgz#453fb3662409abaf2f8b1f65d515699c888dd8ae" + integrity sha512-SX8jNN+iHqAF0riZQMkm7e8+POXa/fXw5cxL+gjpyP+FI+JVNhii53EmQgDAfDcBpFekYSlO0fGytMQwRiMQCA== dependencies: - "@typescript-eslint/types" "5.19.0" + "@typescript-eslint/types" "5.21.0" eslint-visitor-keys "^3.0.0" "@webassemblyjs/ast@1.11.1": @@ -4649,6 +4726,11 @@ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe" integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw== +"@xobotyi/scrollbar-width@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d" + integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -4660,9 +4742,9 @@ integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== abab@^2.0.3, abab@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" - integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" @@ -4725,14 +4807,14 @@ acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.0.4, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== address@^1.0.1, address@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" + integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== adjust-sourcemap-loader@^4.0.0: version "4.0.0" @@ -4926,7 +5008,7 @@ ansi-to-html@^0.6.11: dependencies: entities "^2.0.0" -antd@^4.20.1: +antd@^4.20.0: version "4.20.1" resolved "https://registry.yarnpkg.com/antd/-/antd-4.20.1.tgz#6cd5a406c7172d61a5d0693ea52ee908650cf674" integrity sha512-asKxOV0a6AijqonbcXkO08/q+XvqS/HmGfaRIS6ZH1ALR3FS2q+kTW52rJZO9rfoOb/ldPhEBVSWiNrbiB+uCQ== @@ -5221,10 +5303,10 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-validator@^4.0.2: - version "4.0.7" - resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.0.7.tgz#034a0fd2103a6b2ebf010da75183bec299247afe" - integrity sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ== +async-validator@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/async-validator/-/async-validator-4.1.1.tgz#3cd1437faa2de64743f7d56649dd904c946a18fe" + integrity sha512-p4DO/JXwjs8klJyJL8Q2oM4ks5fUTze/h5k10oPPKMiLe1fj3G1QMzPHNmN1Py4ycOk7WlO2DcGXv1qiESJCZA== async@^2.6.2: version "2.6.4" @@ -5253,13 +5335,13 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^10.3.7, autoprefixer@^10.4.4: - version "10.4.4" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.4.tgz#3e85a245b32da876a893d3ac2ea19f01e7ea5a1e" - integrity sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA== +autoprefixer@^10.3.7, autoprefixer@^10.4.4, autoprefixer@^10.4.5: + version "10.4.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.5.tgz#662193c744094b53d3637f39be477e07bd904998" + integrity sha512-Fvd8yCoA7lNX/OUllvS+aS1I7WRBclGXsepbvT8ZaPgrH24rgXpZzF0/6Hh3ZEkwg+0AES/Osd196VZmYoEFtw== dependencies: browserslist "^4.20.2" - caniuse-lite "^1.0.30001317" + caniuse-lite "^1.0.30001332" fraction.js "^4.2.0" normalize-range "^0.1.2" picocolors "^1.0.0" @@ -5319,9 +5401,9 @@ babel-jest@^27.4.2, babel-jest@^27.5.1: slash "^3.0.0" babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.2.4: - version "8.2.4" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.4.tgz#95f5023c791b2e9e2ca6f67b0984f39c82ff384b" - integrity sha512-8dytA3gcvPPPv4Grjhnt8b5IIiTcq/zeXOPk4iTYI0SVXcsmuGg7JtBRDp8S9X+gJfhQ8ektjXZlDu1Bb33U8A== + version "8.2.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" + integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== dependencies: find-cache-dir "^3.3.1" loader-utils "^2.0.0" @@ -5708,26 +5790,28 @@ bn.js@^5.0.0, bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -body-parser@1.19.2: - version "1.19.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.2.tgz#4714ccd9c157d44797b8b5607d72c0b89952f26e" - integrity sha512-SAAwOxgoCKMGs9uUAUFHygfLAyaniaoun6I8mFY9pRAJL9+Kec34aU+oIjDhTycub1jozEfEwx1W1IuOYxVSFw== +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== dependencies: bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.8.1" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.9.7" - raw-body "2.4.3" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" type-is "~1.6.18" + unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.11.tgz#5418e5c1ac91c89a406f853a942e7892829c0d89" - integrity sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA== + version "1.0.12" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.12.tgz#28fbd4683f5f2e36feedb833e24ba661cac960c3" + integrity sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw== dependencies: array-flatten "^2.1.2" dns-equal "^1.0.0" @@ -5876,15 +5960,15 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1, browserslist@^4.20.2: - version "4.20.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88" - integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.20.2, browserslist@^4.20.3: + version "4.20.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" + integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== dependencies: - caniuse-lite "^1.0.30001317" - electron-to-chromium "^1.4.84" + caniuse-lite "^1.0.30001332" + electron-to-chromium "^1.4.118" escalade "^3.1.1" - node-releases "^2.0.2" + node-releases "^2.0.3" picocolors "^1.0.0" bs-logger@0.x: @@ -5941,22 +6025,22 @@ bytes@3.1.2: integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== c8@^7.6.0: - version "7.11.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.0.tgz#b3ab4e9e03295a102c47ce11d4ef6d735d9a9ac9" - integrity sha512-XqPyj1uvlHMr+Y1IeRndC2X5P7iJzJlEJwBpCdBbq2JocXOgJfr+JVfJkyNMGROke5LfKrhSFXGFXnwnRJAUJw== + version "7.11.2" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.11.2.tgz#2f2103e39079899041e612999a16b31d7ea6d463" + integrity sha512-6ahJSrhS6TqSghHm+HnWt/8Y2+z0hM/FQyB1ybKhAR30+NYL9CTQ1uwHxuWw6U7BHlHv6wvhgOrH81I+lfCkxg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.2" + "@istanbuljs/schema" "^0.1.3" find-up "^5.0.0" foreground-child "^2.0.0" - istanbul-lib-coverage "^3.0.1" + istanbul-lib-coverage "^3.2.0" istanbul-lib-report "^3.0.0" - istanbul-reports "^3.0.2" - rimraf "^3.0.0" + istanbul-reports "^3.1.4" + rimraf "^3.0.2" test-exclude "^6.0.0" - v8-to-istanbul "^8.0.0" + v8-to-istanbul "^9.0.0" yargs "^16.2.0" - yargs-parser "^20.2.7" + yargs-parser "^20.2.9" cacache@^12.0.2: version "12.0.4" @@ -6097,10 +6181,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001317: - version "1.0.30001332" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" - integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001332: + version "1.0.30001334" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001334.tgz#892e9965b35285033fc2b8a8eff499fe02f13d8b" + integrity sha512-kbaCEBRRVSoeNs74sCuq92MJyGrMtjWVfhltoHUCW4t4pXFvGjUBrfo47weBRViHkiV3eBYyIsfl956NtHGazw== capture-exit@^2.0.0: version "2.0.0" @@ -6424,7 +6508,7 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" -codecov@3.8.3: +codecov@^3.8.3: version "3.8.3" resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.3.tgz#9c3e364b8a700c597346ae98418d09880a3fdbe7" integrity sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA== @@ -6680,10 +6764,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== copy-concurrently@^1.0.0: version "1.0.5" @@ -6727,17 +6811,17 @@ copy-webpack-plugin@^10.2.4: serialize-javascript "^6.0.0" core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.8.1: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" - integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.3.tgz#9b10d786052d042bc97ee8df9c0d1fb6a49c2005" + integrity sha512-wliMbvPI2idgFWpFe7UEyHMvu6HWgW8WA+HnDRtgzoSDYvXFMpoGX1H3tPDDXrcfUSyXafCLDd7hOeMQHEZxGw== dependencies: - browserslist "^4.19.1" + browserslist "^4.20.3" semver "7.0.0" core-js-pure@^3.20.2, core-js-pure@^3.8.1, core-js-pure@^3.8.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" - integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.22.3.tgz#181d1b6321fb29fe99c16a1f28beb840ab84ad36" + integrity sha512-oN88zz7nmKROMy8GOjs+LN+0LedIvbMdnB5XsTlhcOg1WGARt9l0LFg0zohdoFmCsEZ1h2ZbSQ6azj3M+vhzwQ== core-js@^2.4.0: version "2.6.12" @@ -6745,9 +6829,9 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.0.4, core-js@^3.19.2, core-js@^3.21.1, core-js@^3.6.5, core-js@^3.8.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.21.1.tgz#f2e0ddc1fc43da6f904706e8e955bc19d06a0d94" - integrity sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig== + version "3.22.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.22.3.tgz#498c41d997654cb00e81c7a54b44f0ab21ab01d5" + integrity sha512-1t+2a/d2lppW1gkLXx3pKPVGbBdxXAkqztvWb1EJ8oF8O2gIGiytzflNiFEehYwVK/t2ryUsGBoOFFvNx95mbg== core-util-is@~1.0.0: version "1.0.3" @@ -6917,6 +7001,14 @@ css-has-pseudo@^3.0.4: dependencies: postcss-selector-parser "^6.0.9" +css-in-js-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99" + integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA== + dependencies: + hyphenate-style-name "^1.0.2" + isobject "^3.0.1" + css-loader@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" @@ -7173,7 +7265,7 @@ csstype@^2.5.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== -csstype@^3.0.2: +csstype@^3.0.2, csstype@^3.0.6: version "3.0.11" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33" integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw== @@ -7332,9 +7424,9 @@ date-fns@2.x: integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== dayjs@1.x: - version "1.11.0" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.0.tgz#009bf7ef2e2ea2d5db2e6583d2d39a4b5061e805" - integrity sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug== + version "1.11.1" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.1.tgz#90b33a3dda3417258d48ad2771b415def6545eb0" + integrity sha512-ER7EjqVAMkRRsxNCC5YqJ9d9VQYuWdGt7aiH2qA5R5wt8ZmWaP2dLUSIK6y/kVzLMlmh1Tvu5xUf4M/wdGJ5KA== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -7429,11 +7521,12 @@ define-lazy-prop@^2.0.0: integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== dependencies: - object-keys "^1.0.12" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" define-property@^0.2.5: version "0.2.5" @@ -7638,14 +7731,14 @@ doctrine@^3.0.0: esutils "^2.0.2" dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: - version "0.5.13" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz#102ee5f25eacce09bdf1cfa5a298f86da473be4b" - integrity sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw== + version "0.5.14" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" + integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== dom-align@^1.7.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b" - integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg== + version "1.12.3" + resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.3.tgz#a36d02531dae0eefa2abb0c4db6595250526f103" + integrity sha512-Gj9hZN3a07cbR6zviMUBOMPdWxYhbMI+x+WS0NAIu2zFZmbK8ys9R79g+iG9qLnlCwpFoaB+fKy8Pdv470GsPA== dom-converter@^0.2.0: version "0.2.0" @@ -7823,10 +7916,10 @@ ejs@^3.1.6: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.84: - version "1.4.107" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.107.tgz#564257014ab14033b4403a309c813123c58a3fb9" - integrity sha512-Huen6taaVrUrSy8o7mGStByba8PfOWWluHNxSHGBrCgEdFVLtvdQDBr9LBCF9Uci8SYxh28QNNMO0oC17wbGAg== +electron-to-chromium@^1.4.118: + version "1.4.127" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.127.tgz#4ef19d5d920abe2676d938f4170729b44f7f423a" + integrity sha512-nhD6S8nKI0O2MueC6blNOEZio+/PWppE/pevnf3LOlQA/fKPCrDp2Ao4wx4LFwmIkJpVdFdn2763YWLy9ENIZg== element-resize-detector@^1.2.2: version "1.2.4" @@ -7848,6 +7941,11 @@ elliptic@^6.5.3: minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -8028,9 +8126,9 @@ es-to-primitive@^1.2.1: is-symbol "^1.0.2" es5-shim@^4.5.13: - version "4.6.5" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.5.tgz#2124bb073b7cede2ed23b122a1fd87bb7b0bb724" - integrity sha512-vfQ4UAai8szn0sAubCy97xnZ4sJVDD1gt/Grn736hg8D7540wemIb1YPrYZSTqlM2H69EQX1or4HU/tSwRTI3w== + version "4.6.6" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.6.tgz#1e0e95bedfdcd933a2d4931a3ac6c79164f18de6" + integrity sha512-Ay5QQE78I2WKUoZVZjL0AIuiIjsmXwZGkyCTH9+n6J1anPbb0ymDA27ASa2Lt0rhOpAlEKy2W0d17gJ1XOQ5eQ== es6-error@^4.0.1: version "4.1.1" @@ -8178,9 +8276,9 @@ eslint-plugin-jsx-a11y@^6.5.1: minimatch "^3.0.4" eslint-plugin-react-hooks@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.4.0.tgz#71c39e528764c848d8253e1aa2c7024ed505f6c4" - integrity sha512-U3RVIfdzJaeKDQKEJbz5p3NW8/L80PCATJAfuojwbaEL+gBjfGdhUcGde+WGUW46Q5sr/NgxevsIiDtNXrvZaQ== + version "4.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.5.0.tgz#5f762dfedf8b2cf431c689f533c9d3fa5dcf25ad" + integrity sha512-8k1gRt7D7h03kd+SAAlzXkQwWK22BnK6GKZG+FJA6BAGy22CFvl8kCIXKpVux0cCxMWDQUPqSok0LKaZ0aOcCw== eslint-plugin-react@^7.27.1: version "7.29.4" @@ -8262,11 +8360,11 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^3.1.1" eslint@^8.3.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.13.0.tgz#6fcea43b6811e655410f5626cfcf328016badcd7" - integrity sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ== + version "8.14.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.14.0.tgz#62741f159d9eb4a79695b28ec4989fcdec623239" + integrity sha512-3/CE4aJX7LNEiE3i6FeodHmI/38GZtWCsAtsymScmzYapx8q1nVVb+eLcLSzATmCPXw5pT4TqVs1E0OmxAd9tw== dependencies: - "@eslint/eslintrc" "^1.2.1" + "@eslint/eslintrc" "^1.2.2" "@humanwhocodes/config-array" "^0.9.2" ajv "^6.10.0" chalk "^4.0.0" @@ -8457,37 +8555,38 @@ expect@^27.5.1: jest-message-util "^27.5.1" express@^4.17.1, express@^4.17.3: - version "4.17.3" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.3.tgz#f6c7302194a4fb54271b73a1fe7a06478c8f85a1" - integrity sha512-yuSQpz5I+Ch7gFrPCk4/c+dIBKlQUxtgwqzph132bsT6qhuzss6I8cLJQz7B3rFblzd6wtcI0ZbGltH/C4LjUg== + version "4.18.0" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.0.tgz#7a426773325d0dd5406395220614c0db10b6e8e2" + integrity sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.2" + body-parser "1.20.0" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.2" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" proxy-addr "~2.0.7" - qs "6.9.7" + qs "6.10.3" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.17.2" - serve-static "1.14.2" + send "0.18.0" + serve-static "1.15.0" setprototypeof "1.2.0" - statuses "~1.5.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -8526,7 +8625,7 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" -fast-check@2.25.0, fast-check@^2.17.0: +fast-check@^2.17.0, fast-check@^2.25.0: version "2.25.0" resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-2.25.0.tgz#5146601851bf3be0953bd17eb2b7d547936c6561" integrity sha512-wRUT2KD2lAmT75WNIJIHECawoUUMHM0I5jrlLXGtGeqmPL8jl/EldUDjY1VCp6fDY8yflyfUeIOsOBrIbIiArg== @@ -8581,6 +8680,11 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-shallow-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b" + integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== + fast-url-parser@1.1.3, fast-url-parser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" @@ -8593,6 +8697,11 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz#9990f7d3a88cc5a9ffd1f1745745251700d497e2" integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow== +fastest-stable-stringify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76" + integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q== + fastq@^1.6.0: version "1.13.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" @@ -8716,17 +8825,17 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~1.5.0" + statuses "2.0.1" unpipe "~1.0.0" find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: @@ -8843,9 +8952,9 @@ fork-ts-checker-webpack-plugin@^4.1.6: worker-rpc "^0.1.0" fork-ts-checker-webpack-plugin@^6.0.4, fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.1" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.1.tgz#fd689e2d9de6ac76abb620909eea56438cd0f232" - integrity sha512-x1wumpHOEf4gDROmKTaB6i4/Q6H3LwmjVO7fIX47vBwlZbtPjU33hgoMuD/Q/y6SU8bnuYSoN6ZQOLshGp0T/g== + version "6.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" + integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== dependencies: "@babel/code-frame" "^7.8.3" "@types/json-schema" "^7.0.5" @@ -8922,9 +9031,9 @@ fs-extra@^0.30.0: rimraf "^2.2.8" fs-extra@^10.0.0, fs-extra@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.1.tgz#27de43b4320e833f6867cc044bfce29fdf0ef3b8" - integrity sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag== + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -9001,9 +9110,9 @@ functional-red-black-tree@^1.0.1: integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= functions-have-names@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" - integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== fuse.js@^3.6.1: version "3.6.1" @@ -9308,10 +9417,10 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: version "3.0.0" @@ -9330,6 +9439,13 @@ has-glob@^1.0.0: dependencies: is-glob "^3.0.0" +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" @@ -9756,9 +9872,9 @@ http-proxy-agent@^4.0.0, http-proxy-agent@^4.0.1: debug "4" http-proxy-middleware@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz#03af0f4676d172ae775cb5c33f592f40e1a4e07a" - integrity sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg== + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -9793,6 +9909,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +hyphenate-style-name@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -9949,6 +10070,13 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== +inline-style-prefixer@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.1.tgz#c5c0e43ba8831707afc5f5bbfd97edf45c1fa7ae" + integrity sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ== + dependencies: + css-in-js-utils "^2.0.0" + internal-slot@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" @@ -10092,9 +10220,9 @@ is-ci@^2.0.0: ci-info "^2.0.0" is-core-module@^2.2.0, is-core-module@^2.8.1: - version "2.8.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" - integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" @@ -10445,7 +10573,7 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.0.1, istanbul-lib-coverage@^3.2.0: +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.0.0-alpha.1, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== @@ -10468,9 +10596,9 @@ istanbul-lib-instrument@^4.0.0: semver "^6.3.0" istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" - integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== + version "5.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: "@babel/core" "^7.12.3" "@babel/parser" "^7.14.7" @@ -10509,7 +10637,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: version "3.1.4" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== @@ -10782,6 +10910,21 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.0.2.tgz#f3cf36be72be4c4c4058cb34bd6673996d26dee3" + integrity sha512-knK7XyojvwYh1XiF2wmVdskgM/uN11KsjcEWWHfnMZNEdwXCrqB4sCBO94F4cfiAwCS8WFV6CDixDwPlMh/wdA== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.0.2" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.0.2" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" @@ -10800,11 +10943,16 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-regex-util@^27.0.0, jest-regex-util@^27.5.1: +jest-regex-util@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== +jest-regex-util@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + jest-resolve-dependencies@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" @@ -10953,6 +11101,18 @@ jest-util@^27.0.0, jest-util@^27.5.1: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.0.2.tgz#8e22cdd6e0549e0a393055f0e2da7eacc334b143" + integrity sha512-EVdpIRCC8lzqhp9A0u0aAKlsFIzufK6xKxNK7awsnebTdOP4hpyQW5o6Ox2qPl8gbeUKYF+POLyItaND53kpGA== + dependencies: + "@jest/types" "^28.0.2" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" @@ -10966,19 +11126,19 @@ jest-validate@^27.5.1: pretty-format "^27.5.1" jest-watch-typeahead@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.0.0.tgz#4de2ca1eb596acb1889752afbab84b74fcd99173" - integrity sha512-jxoszalAb394WElmiJTFBMzie/RDCF+W7Q29n5LzOPtcoQoHWfdUtHFkbhgf5NwWe8uMOxvKb/g7ea7CshfkTw== + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-watch-typeahead/-/jest-watch-typeahead-1.1.0.tgz#b4a6826dfb9c9420da2f7bc900de59dad11266a9" + integrity sha512-Va5nLSJTN7YFtC2jd+7wsoe1pNe5K4ShLux/E5iHEwlB9AxaxmggY7to9KUqKojhaJw3aXqt5WAb4jGPOolpEw== dependencies: ansi-escapes "^4.3.1" chalk "^4.0.0" - jest-regex-util "^27.0.0" - jest-watcher "^27.0.0" + jest-regex-util "^28.0.0" + jest-watcher "^28.0.0" slash "^4.0.0" string-length "^5.0.1" strip-ansi "^7.0.1" -jest-watcher@^27.0.0, jest-watcher@^27.5.1: +jest-watcher@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== @@ -10991,6 +11151,20 @@ jest-watcher@^27.0.0, jest-watcher@^27.5.1: jest-util "^27.5.1" string-length "^4.0.1" +jest-watcher@^28.0.0: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.0.2.tgz#649fa24df531d4071be5784b6274d494d788c88b" + integrity sha512-uIVJLpQ/5VTGQWBiBatHsi7jrCqHjHl0e0dFHMWzwuIfUbdW/muk0DtSr0fteY2T7QTFylv+7a5Rm8sBKrE12Q== + dependencies: + "@jest/test-result" "^28.0.2" + "@jest/types" "^28.0.2" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.0.2" + string-length "^4.0.1" + jest-worker@^26.2.1, jest-worker@^26.5.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" @@ -11029,6 +11203,11 @@ joi@^17.6.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -11493,7 +11672,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.21, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -11617,7 +11796,7 @@ markdown-to-jsx@^7.1.3: resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.7.tgz#a5f22102fb12241c8cea1ca6a4050bb76b23a25d" integrity sha512-VI3TyyHlGkO8uFle0IOibzpO1c1iJDcXcS/zBrQrXQQvJ2tpdwVzVZ7XdKsyRz1NdRmre4dqQkMZzUHaKIG/1w== -mathjs@10.5.0: +mathjs@^10.5.0: version "10.5.0" resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-10.5.0.tgz#f81d0518fe7b4b2a0b85e1125b8ecfc364fb0292" integrity sha512-gRnSY9psN9zgiB2QV9F4XbuX5hwjxY5Ou7qoTFWDbn2vZ3UEs+sjfK/SRg2WP30TNfZWpwlGdp8H1knFJnpFdA== @@ -11986,7 +12165,7 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -moduleserve@0.9.1: +moduleserve@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/moduleserve/-/moduleserve-0.9.1.tgz#11bad4337ea248d7eaf10d2c7f8649a8c3b9c1f8" integrity sha512-WF2BeGnM2Ko7bdICgJO+Ibu+ZD33ExJHzOzTDsCUzfZnvnFfheEIYBTWyIqSRU0tXh4UTQ1krDOCglFTJPBMow== @@ -12049,10 +12228,24 @@ nan@^2.12.1: resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== +nano-css@^5.3.1: + version "5.3.4" + resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.4.tgz#40af6a83a76f84204f346e8ccaa9169cdae9167b" + integrity sha512-wfcviJB6NOxDIDfr7RFn/GlaN7I/Bhe4d39ZRCJ3xvZX60LVe2qZ+rDqM49nm4YT81gAjzS+ZklhKP/Gnfnubg== + dependencies: + css-tree "^1.1.2" + csstype "^3.0.6" + fastest-stable-stringify "^2.0.2" + inline-style-prefixer "^6.0.0" + rtl-css-js "^1.14.0" + sourcemap-codec "^1.4.8" + stacktrace-js "^2.0.2" + stylis "^4.0.6" + nanoid@^3.1.23, nanoid@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557" - integrity sha512-CuHBogktKwpm5g2sRgv83jEy2ijFzBwMoYA60orPDR7ynsLijJDqgsi4RDGj3OJpy3Ieb+LYwiRmIOGyytgITA== + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanomatch@^1.2.9: version "1.2.13" @@ -12171,10 +12364,10 @@ node-preload@^0.2.1: dependencies: process-on-spawn "^1.0.0" -node-releases@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96" - integrity sha512-maHFz6OLqYxz+VQyCAtA3PTX4UP/53pa05fyDNc9CwjvJ0yEh6+xBwKsgCxMNhS8taUKBFYxfuiaD9U/55iFaw== +node-releases@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.4.tgz#f38252370c43854dc48aa431c766c6c398f40476" + integrity sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ== normalize-package-data@^2.5.0: version "2.5.0" @@ -12323,7 +12516,7 @@ object-inspect@^1.12.0, object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -12600,11 +12793,11 @@ p-map@^4.0.0: aggregate-error "^3.0.0" p-retry@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" - integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== dependencies: - "@types/retry" "^0.12.0" + "@types/retry" "0.12.0" retry "^0.13.1" p-timeout@^3.1.0: @@ -13009,7 +13202,7 @@ postcss-custom-media@^8.0.0: resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== -postcss-custom-properties@^12.1.5: +postcss-custom-properties@^12.1.7: version "12.1.7" resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.7.tgz#ca470fd4bbac5a87fd868636dafc084bc2a78b41" integrity sha512-N/hYP5gSoFhaqxi2DPCmvto/ZcRDVjE3T1LiAMzc/bg53hvhcHOLpXOHb526LzBBp5ZlAUhkuot/bfpmpgStJg== @@ -13127,7 +13320,7 @@ postcss-js@^4.0.0: dependencies: camelcase-css "^2.0.1" -postcss-lab-function@^4.1.2: +postcss-lab-function@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.0.tgz#e054e662c6480202f5760887ec1ae0d153357123" integrity sha512-Zb1EO9DGYfa3CP8LhINHCcTTCTLI+R3t7AX2mKsDzdgVQ/GkCpHOTgOr6HBHslP7XDdVbqgHW5vvRPMdVANQ8w== @@ -13299,7 +13492,7 @@ postcss-nested@5.0.6: dependencies: postcss-selector-parser "^6.0.6" -postcss-nesting@^10.1.3: +postcss-nesting@^10.1.4: version "10.1.4" resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.4.tgz#80de9d1c2717bc44df918dd7f118929300192a7a" integrity sha512-2ixdQ59ik/Gt1+oPHiI1kHdwEI8lLKEmui9B1nl6163ANLC+GewQn7fXMxJF2JSb4i2MKL96GU8fIiQztK4TTA== @@ -13409,20 +13602,20 @@ postcss-place@^7.0.4: postcss-value-parser "^4.2.0" postcss-preset-env@^7.0.1: - version "7.4.3" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.4.3.tgz#fb1c8b4cb405da042da0ddb8c5eda7842c08a449" - integrity sha512-dlPA65g9KuGv7YsmGyCKtFkZKCPLkoVMUE3omOl6yM+qrynVHxFvf0tMuippIrXB/sB/MyhL1FgTIbrO+qMERg== + version "7.4.4" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.4.4.tgz#069e34e31e2a7345154da7936b9fc1fcbdbd6d43" + integrity sha512-MqzSEx/QsvOk562iV9mLTgIvLFEOq1os9QBQfkgnq8TW6yKhVFPGh0gdXSK5ZlmjuNQEga6/x833e86XZF/lug== dependencies: - "@csstools/postcss-color-function" "^1.0.3" + "@csstools/postcss-color-function" "^1.1.0" "@csstools/postcss-font-format-keywords" "^1.0.0" "@csstools/postcss-hwb-function" "^1.0.0" "@csstools/postcss-ic-unit" "^1.0.0" - "@csstools/postcss-is-pseudo-class" "^2.0.1" + "@csstools/postcss-is-pseudo-class" "^2.0.2" "@csstools/postcss-normalize-display-values" "^1.0.0" - "@csstools/postcss-oklab-function" "^1.0.2" + "@csstools/postcss-oklab-function" "^1.1.0" "@csstools/postcss-progressive-custom-properties" "^1.3.0" - autoprefixer "^10.4.4" - browserslist "^4.20.2" + autoprefixer "^10.4.5" + browserslist "^4.20.3" css-blank-pseudo "^3.0.3" css-has-pseudo "^3.0.4" css-prefers-color-scheme "^6.0.3" @@ -13433,7 +13626,7 @@ postcss-preset-env@^7.0.1: postcss-color-hex-alpha "^8.0.3" postcss-color-rebeccapurple "^7.0.2" postcss-custom-media "^8.0.0" - postcss-custom-properties "^12.1.5" + postcss-custom-properties "^12.1.7" postcss-custom-selectors "^6.0.0" postcss-dir-pseudo-class "^6.0.4" postcss-double-position-gradients "^3.1.1" @@ -13444,20 +13637,20 @@ postcss-preset-env@^7.0.1: postcss-gap-properties "^3.0.3" postcss-image-set-function "^4.0.6" postcss-initial "^4.0.1" - postcss-lab-function "^4.1.2" + postcss-lab-function "^4.2.0" postcss-logical "^5.0.4" postcss-media-minmax "^5.0.0" - postcss-nesting "^10.1.3" + postcss-nesting "^10.1.4" postcss-opacity-percentage "^1.1.2" postcss-overflow-shorthand "^3.0.3" postcss-page-break "^3.0.4" postcss-place "^7.0.4" - postcss-pseudo-class-any-link "^7.1.1" + postcss-pseudo-class-any-link "^7.1.2" postcss-replace-overflow-wrap "^4.0.0" postcss-selector-not "^5.0.0" postcss-value-parser "^4.2.0" -postcss-pseudo-class-any-link@^7.1.1: +postcss-pseudo-class-any-link@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.2.tgz#81ec491aa43f97f9015e998b7a14263b4630bdf0" integrity sha512-76XzEQv3g+Vgnz3tmqh3pqQyRojkcJ+pjaePsyhcyf164p9aZsu3t+NWxkZYbcHLK1ju5Qmalti2jPI5IWCe5w== @@ -13610,6 +13803,16 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.0.2.tgz#6a24d71cbb61a5e5794ba7513fe22101675481bc" + integrity sha512-UmGZ1IERwS3yY35LDMTaBUYI1w4udZDdJGGT/DqQeKG9ZLDn7/K2Jf/JtYSRiHCCKMHvUA+zsEGSmHdpaVp1yw== + dependencies: + "@jest/schemas" "^28.0.2" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -13625,7 +13828,12 @@ prism-react-renderer@^1.2.1, prism-react-renderer@^1.3.1: resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.1.tgz#88fc9d0df6bed06ca2b9097421349f8c2f24e30d" integrity sha512-xUeDMEz074d0zc5y6rxiMp/dlC7C+5IDDlaEUlcBOFE2wddz7hz5PNupb087mPwTt7T9BrFmewObfCBuf/LKwQ== -prismjs@^1.21.0, prismjs@^1.27.0, prismjs@~1.27.0: +prismjs@^1.21.0, prismjs@^1.27.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + +prismjs@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== @@ -13695,7 +13903,7 @@ prompts@^2.0.1, prompts@^2.4.0, prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -13803,12 +14011,7 @@ q@^1.1.2: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.9.7: - version "6.9.7" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.7.tgz#4610846871485e1e048f44ae3b94033f0e675afe" - integrity sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw== - -qs@^6.10.0: +qs@6.10.3, qs@^6.10.0: version "6.10.3" resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== @@ -13889,13 +14092,13 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.3.tgz#8f80305d11c2a0a545c2d9d89d7a0286fcead43c" - integrity sha512-UlTNLIcu0uzb4D2f4WltY6cVjLi+/jEN4lgEUj3E04tpMDpUlkBo/eSn6zou9hum2VMNpCCUone0O0WeJim07g== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: bytes "3.1.2" - http-errors "1.8.1" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" @@ -13908,9 +14111,9 @@ raw-loader@^4.0.2: schema-utils "^3.0.0" rc-align@^4.0.0: - version "4.0.11" - resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.11.tgz#8198c62db266bc1b8ef05e56c13275bf72628a5e" - integrity sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A== + version "4.0.12" + resolved "https://registry.yarnpkg.com/rc-align/-/rc-align-4.0.12.tgz#065b5c68a1cc92a00800c9239320d9fdf5f16207" + integrity sha512-3DuwSJp8iC/dgHzwreOQl52soj40LchlfUHtgACOUtwGuoFIOVh6n/sCpfqCU8kO5+iz6qR0YKvjgB8iPdE3aQ== dependencies: "@babel/runtime" "^7.10.1" classnames "2.x" @@ -13970,9 +14173,9 @@ rc-drawer@~4.4.2: rc-util "^5.7.0" rc-dropdown@~3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.5.0.tgz#6ff2e6aaacd3641aa4040cfa941ab9634ad5f1ed" - integrity sha512-HHMpzO6AJt3I2jBG8fFK9LqFMQhHn/V09AzQnqCCV8Fp22tNCS98Obelcc4C8T6ZlZR+/w01im0BQVP3o1Y+Cw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/rc-dropdown/-/rc-dropdown-3.5.2.tgz#2f1f4eeb36c07fb67cd599c0cb8e861da3de5527" + integrity sha512-Ty4LsXjkspZuFJSRx3blCLLCDicXM5qds6F1odgEa+jcjC+OJKHQGnvE4FqtoljPaqWm4wG78pbgXH6Ddh2DkA== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.6" @@ -13980,18 +14183,18 @@ rc-dropdown@~3.5.0: rc-util "^5.17.0" rc-field-form@~1.26.1: - version "1.26.2" - resolved "https://registry.yarnpkg.com/rc-field-form/-/rc-field-form-1.26.2.tgz#69d92811eed09f9e1f74704695b13253bb2ae534" - integrity sha512-Q1QdpLAt/kxd119kJwGfFvn/ZIzjzTBJsCscy5k0z3g+eRMHkI0Exij6SE2D42N7FAzVkvuXTvzqWSiFGeer7g== + version "1.26.3" + resolved "https://registry.yarnpkg.com/rc-field-form/-/rc-field-form-1.26.3.tgz#4050000eae0d879fde85672a965c9558ed6ff04b" + integrity sha512-wzQToAwdr8fiq/Nb1KFq+9WYFeALJXKwNGk5/MaCu1AUS7PpVQaN2anzVfWdVBFiiM2N+3DOh64JSOH8s1w3FQ== dependencies: "@babel/runtime" "^7.8.4" - async-validator "^4.0.2" + async-validator "^4.1.0" rc-util "^5.8.0" rc-image@~5.6.0: - version "5.6.1" - resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.6.1.tgz#60662a8fc0fe91d7ebd7fd5ee972d5b6226850e2" - integrity sha512-nmcobNCfmeevsep6eL7KNHVwFdLz4As4Vx0o90nnUFNzZ9Pqost1s10gOf4Wl6XW2iMR9LU6ztm5EazM7yA4Gg== + version "5.6.2" + resolved "https://registry.yarnpkg.com/rc-image/-/rc-image-5.6.2.tgz#31892b0b22aa5122fd9b1a067e9a4ba627004214" + integrity sha512-qhKOVvivCZkd6CrzS/4ST2+Auu16mtPSFVqVzwE7sELWfuvzcLGTzGv8UsVvm6qRNIz6SeaueUetqi4Ii16XQA== dependencies: "@babel/runtime" "^7.11.2" classnames "^2.2.6" @@ -14061,9 +14264,9 @@ rc-notification@~4.6.0: rc-util "^5.20.1" rc-overflow@^1.0.0, rc-overflow@^1.2.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.4.tgz#e25cd3c4a98b4f8233a8dab7172ab2dbcc83b45e" - integrity sha512-nIeelyYfdS+mQBK1++FisLZEvZ8xVAzC+duG+TC4TmqNN+kTHraiGntV9/zxDGA1ruyQ91YRJ549JjFodCBnsw== + version "1.2.5" + resolved "https://registry.yarnpkg.com/rc-overflow/-/rc-overflow-1.2.5.tgz#d0fe3f9fa99edec70f4fe20e38119e8c1c5ae3ca" + integrity sha512-5HJKZ4nPe9e7AFdCkflgpRydvH6lJ4i2iFF06q/T1G9lL/XBeuoPLRrTBU8ao/Vo/yARW6WfEHnC2951lVgX5Q== dependencies: "@babel/runtime" "^7.11.1" classnames "^2.2.1" @@ -14071,17 +14274,17 @@ rc-overflow@^1.0.0, rc-overflow@^1.2.0: rc-util "^5.19.2" rc-pagination@~3.1.9: - version "3.1.15" - resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.15.tgz#e05eddf4c15717a5858290bed0857e27e2f957ff" - integrity sha512-4L3fot8g4E+PjWEgoVGX0noFCg+8ZFZmeLH4vsnZpB3O2T2zThtakjNxG+YvSaYtyMVT4B+GLayjKrKbXQpdAg== + version "3.1.16" + resolved "https://registry.yarnpkg.com/rc-pagination/-/rc-pagination-3.1.16.tgz#b0082108cf027eded18ed61d818d31897c343e81" + integrity sha512-GFcHXJ7XxeJDf9B+ndP4PRDt46maSSgYhiwofBMiIGKIlBhJ0wfu8DMCEvaWJJLpI2u4Gb6zF1dHpiqPFrosPg== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.1" rc-picker@~2.6.4: - version "2.6.7" - resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.7.tgz#bdde4156e219ef36b0006b7d4d72020373f21229" - integrity sha512-+P2Grt0r2kmCkw2XTp9ew3zTCwBCFEOQLd5BYs+hFaGDSSZwEWJtlbGXAGqWnAUMFx6JrCsKYkDKXDxAWlRz3A== + version "2.6.8" + resolved "https://registry.yarnpkg.com/rc-picker/-/rc-picker-2.6.8.tgz#eff71e13d836953a4c7439c958228b5108f92c22" + integrity sha512-j14N2nxcx4PAw7LviwLKIJG4cEAlCFhcHI/7pz+Ps43Df7UrSIWt/QGJgPAWz38Z6jrjsgMcyVHVccpL09gDDA== dependencies: "@babel/runtime" "^7.10.1" classnames "^2.2.1" @@ -14237,9 +14440,9 @@ rc-tree@~5.5.0: rc-virtual-list "^3.4.2" rc-trigger@^5.0.0, rc-trigger@^5.0.4, rc-trigger@^5.1.2, rc-trigger@^5.2.10: - version "5.2.15" - resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.2.15.tgz#f6bfed418e602513cc3e07853ddaf37e5c5339f4" - integrity sha512-VxZWqCObtUOzs9V9Be0dDA2JGchriDpvQaJpsCI2EQ4+KWHIvjFz6Ziina4uxK5drRsn0RnBi7nngmTl9j/F7Q== + version "5.2.18" + resolved "https://registry.yarnpkg.com/rc-trigger/-/rc-trigger-5.2.18.tgz#adab51918e4569b174d4fc5044186200d97a542c" + integrity sha512-hi2yZ7umtbAGLxgSph1az9BR9i4Pb4fiQa4pdvFQuKN7U//3nwwygHQKHfexnM+0APBnzZwVlEHA5I8BpWrygw== dependencies: "@babel/runtime" "^7.11.2" classnames "^2.2.6" @@ -14266,9 +14469,9 @@ rc-util@^5.0.1, rc-util@^5.0.6, rc-util@^5.12.0, rc-util@^5.14.0, rc-util@^5.15. shallowequal "^1.1.0" rc-virtual-list@^3.2.0, rc-virtual-list@^3.4.2: - version "3.4.6" - resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.6.tgz#af34235915221173dd42d9f25b32e95d4c0f5698" - integrity sha512-wMJ7Bl+AxgIDojp0VxuQxjpNulKodwxGXSsTyxA9Mwzwemj5vKAgTbkPT64ZW5ORf8FOQAaPRlMiTADrPEo3sQ== + version "3.4.7" + resolved "https://registry.yarnpkg.com/rc-virtual-list/-/rc-virtual-list-3.4.7.tgz#ca0ba5ecddff686cd3833562d07c2678d1c9cb2e" + integrity sha512-PhV8a8g/L9sCmWcmXizzwW7QdqsxK4ebHU6fA9OsUIR7isFdx2bTGU2iAUdRV4teiIF1ZHF3gSQh8NtAxrXh6A== dependencies: classnames "^2.2.6" rc-resize-observer "^1.0.0" @@ -14284,7 +14487,18 @@ rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -react-ace@10.1.0: +react-ace@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.0.0.tgz#1760e302604cff35ba40963db43eb027513b6572" + integrity sha512-AUoA2OsKOCv8fXLqcFM232dF/Z8w14bwPUZ9z5I2zjBfqfZOZLqxnhXN+qKL6VrQXs1DLUvalGOuM5TABAFOCA== + dependencies: + ace-builds "^1.4.14" + diff-match-patch "^1.0.5" + lodash.get "^4.4.2" + lodash.isequal "^4.5.0" + prop-types "^15.7.2" + +react-ace@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/react-ace/-/react-ace-10.1.0.tgz#d348eac2b16475231779070b6cd16768deed565f" integrity sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA== @@ -14373,7 +14587,7 @@ react-docgen@^5.0.0: node-dir "^0.1.10" strip-indent "^3.0.0" -react-dom@^18.1.0: +react-dom@^18.0.0, react-dom@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f" integrity sha512-fU1Txz7Budmvamp7bshe4Zi32d0ll7ect+ccxNu9FlObT605GOEB8BfO4tmRJ39R5Zj831VCpvQ05QPBW5yb+w== @@ -14382,12 +14596,12 @@ react-dom@^18.1.0: scheduler "^0.22.0" react-draggable@^4.4.3: - version "4.4.4" - resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.4.tgz#5b26d9996be63d32d285a426f41055de87e59b2f" - integrity sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA== + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.5.tgz#9e37fe7ce1a4cf843030f521a0a4cc41886d7e7c" + integrity sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g== dependencies: clsx "^1.1.1" - prop-types "^15.6.0" + prop-types "^15.8.1" react-element-to-jsx-string@^14.3.4: version "14.3.4" @@ -14438,6 +14652,11 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^18.0.0: + version "18.1.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.1.0.tgz#61aaed3096d30eacf2a2127118b5b41387d32a67" + integrity sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg== + react-json-view@^1.21.3: version "1.21.3" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" @@ -14470,9 +14689,9 @@ react-popper-tooltip@^3.1.1: react-popper "^2.2.4" react-popper@^2.2.4: - version "2.2.5" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96" - integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw== + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.3.0.tgz#17891c620e1320dce318bad9fede46a5f71c70ba" + integrity sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q== dependencies: react-fast-compare "^3.0.1" warning "^4.0.2" @@ -14490,15 +14709,15 @@ react-router-config@^5.1.1: "@babel/runtime" "^7.1.2" react-router-dom@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.0.tgz#da1bfb535a0e89a712a93b97dd76f47ad1f32363" - integrity sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.1.tgz#0151baf2365c5fcd8493f6ec9b9b31f34d0f8ae1" + integrity sha512-f0pj/gMAbv9e8gahTmCEY20oFhxhrmHwYeIwH5EO5xu0qme+wXtsdB8YfUOAZzUz4VaXmb58m3ceiLtjMhqYmQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.2.1" + react-router "5.3.1" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" @@ -14510,10 +14729,10 @@ react-router-dom@^6.0.0: history "^5.2.0" react-router "6.3.0" -react-router@5.2.1, react-router@^5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.1.tgz#4d2e4e9d5ae9425091845b8dbc6d9d276239774d" - integrity sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ== +react-router@5.3.1, react-router@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.1.tgz#b13e84a016c79b9e80dde123ca4112c4f117e3cf" + integrity sha512-v+zwjqb7bakqgF+wMVKlAPTca/cEmPOvQ9zt7gpSNyPXau1+0qvuYZ5BWzzNDP1y6s15zDwgb9rPN63+SIniRQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" @@ -14533,7 +14752,7 @@ react-router@6.3.0, react-router@^6.0.0: dependencies: history "^5.2.0" -react-scripts@5.0.1: +react-scripts@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-5.0.1.tgz#6285dbd65a8ba6e49ca8d651ce30645a6d980003" integrity sha512-8VAmEm/ZAwQzJ+GOMLbBsTdDKOpuZh7RPs0UymvBR2vRk4iZWCskjbFnxqjrzoIvlNNRZ3QJFx6/qDSi6zSnaQ== @@ -14618,6 +14837,31 @@ react-textarea-autosize@^8.3.0, react-textarea-autosize@^8.3.2: use-composed-ref "^1.0.0" use-latest "^1.0.0" +react-universal-interface@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" + integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== + +react-use@^17.3.2: + version "17.3.2" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.3.2.tgz#448abf515f47c41c32455024db28167cb6e53be8" + integrity sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw== + dependencies: + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" + react-vega@^7.5.0: version "7.5.0" resolved "https://registry.yarnpkg.com/react-vega/-/react-vega-7.5.0.tgz#b9726d4fd7f35299d417d340935e093bf4bed558" @@ -14782,12 +15026,13 @@ regex-parser@^2.2.11: integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== regexp.prototype.flags@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.2.tgz#bf635117a2f4b755595ebb0c0ee2d2a49b2084db" - integrity sha512-Ynz8fTQW5/1elh+jWU2EDDzeoNbD0OQ0R+D1VJU5ATOkUaro4A9YEkdN2ODQl/8UQFPPpZNw91fOcLFamM7Pww== + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" + functions-have-names "^1.2.2" regexpp@^3.2.0: version "3.2.0" @@ -15163,9 +15408,9 @@ rollup-plugin-terser@^7.0.0: terser "^5.0.0" rollup@^2.43.1: - version "2.70.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.1.tgz#824b1f1f879ea396db30b0fc3ae8d2fead93523e" - integrity sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA== + version "2.70.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.2.tgz#808d206a8851628a065097b7ba2053bd83ba0c0d" + integrity sha512-EitogNZnfku65I1DD5Mxe8JYRUCy0hkK5X84IlDtUs+O6JRMpRciXTzyCUuX11b5L5pvjH+OmFXiQ3XjabcXgg== optionalDependencies: fsevents "~2.3.2" @@ -15174,6 +15419,13 @@ rsvp@^4.8.4: resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== +rtl-css-js@^1.14.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.15.0.tgz#680ed816e570a9ebccba9e1cd0f202c6a8bb2dc0" + integrity sha512-99Cu4wNNIhrI10xxUaABHsdDqzalrSRTie4GeCmbGVuehm4oj+fIy8fTzB+16pmKe8Bv9rl+hxIBez6KxExTew== + dependencies: + "@babel/runtime" "^7.1.2" + rtl-detect@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.4.tgz#40ae0ea7302a150b96bc75af7d749607392ecac6" @@ -15335,6 +15587,11 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +screenfull@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.2.0.tgz#6533d524d30621fc1283b9692146f3f13a93d1ba" + integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== + scroll-into-view-if-needed@^2.2.25: version "2.2.29" resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.29.tgz#551791a84b7e2287706511f8c68161e4990ab885" @@ -15396,25 +15653,6 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -send@0.17.2, send@^0.17.1: - version "0.17.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" - integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== - dependencies: - 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.8.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -15434,6 +15672,25 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +send@^0.17.1: + version "0.17.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.17.2.tgz#926622f76601c41808012c8bf1688fe3906f7820" + integrity sha512-UJYB6wFSJE3G00nEivR5rgWp8c2xXvJ3OPWPhmuteU0IKj8nKbG3DrjiOmLwpnHGYWAVwA69zmTm++YG0Hmwww== + dependencies: + 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.8.1" + mime "1.6.0" + ms "2.1.3" + on-finished "~2.3.0" + range-parser "~1.2.1" + statuses "~1.5.0" + serialize-javascript@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" @@ -15493,17 +15750,7 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.14.2: - version "1.14.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.2.tgz#722d6294b1d62626d41b43a013ece4598d292bfa" - integrity sha512-+TMNA9AFxUEGuC0z2mevogSnn9MXKb4fa7ngeRMJaaGv8vTwnIEkKi+QGvPt33HSnf8pRS+WGM0EbMtCJLKMBQ== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.2" - -serve-static@^1.14.1: +serve-static@1.15.0, serve-static@^1.14.1: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== @@ -15518,6 +15765,11 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= +set-harmonic-interval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249" + integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g== + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -15749,6 +16001,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -15759,12 +16016,12 @@ source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.7.3, source-map@~0.7.2: +source-map@^0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -source-map@^0.8.0-beta.0: +source-map@^0.8.0-beta.0, source-map@~0.8.0-beta.0: version "0.8.0-beta.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== @@ -15873,6 +16130,13 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + dependencies: + stackframe "^1.1.1" + stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -15885,6 +16149,23 @@ stackframe@^1.1.1: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.1.tgz#1033a3473ee67f08e2f2fc8eba6aef4f845124e1" integrity sha512-h88QkzREN/hy8eRdyNhhsO7RSJ5oyTqxxmmn0dzBIMUclZsjpfmrsg81vp8mjjAs2vAZ72nyWxRUwSwmh0e4xg== +stacktrace-gps@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + dependencies: + source-map "0.5.6" + stackframe "^1.1.1" + +stacktrace-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" + integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== + dependencies: + error-stack-parser "^2.0.6" + stack-generator "^2.0.5" + stacktrace-gps "^3.0.4" + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -15909,9 +16190,9 @@ statuses@2.0.1: integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= std-env@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.0.1.tgz#bc4cbc0e438610197e34c2d79c3df30b491f5182" - integrity sha512-mC1Ps9l77/97qeOZc+HrOL7TIaOboHqMZ24dGVQrlxFcpPpfCHpH+qfUT7Dz+6mlG8+JPA1KfBQo19iC/+Ngcw== + version "3.1.1" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.1.1.tgz#1f19c4d3f6278c52efd08a94574a2a8d32b7d092" + integrity sha512-/c645XdExBypL01TpFKiG/3RAa/Qmu+zRi0MwAmrdEkwHNuN0ebo8ccAXBBDa5Z0QOJgBskUIbuCK91x0sCVEw== store2@^2.12.0: version "2.13.2" @@ -16197,6 +16478,11 @@ stylehacks@^5.1.0: browserslist "^4.16.6" postcss-selector-parser "^6.0.4" +stylis@^4.0.6: + version "4.1.1" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.1.1.tgz#e46c6a9bbf7c58db1e65bb730be157311ae1fe12" + integrity sha512-lVrM/bNdhVX2OgBFNa2YJ9Lxj7kPzylieHd3TNjuGE0Re9JB7joL5VUKOVH1kdNNJTgGPpT8hmwIAPLaSyEVFQ== + supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -16441,13 +16727,13 @@ terser@^4.1.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.0.0, terser@^5.10.0, terser@^5.3.4, terser@^5.7.2: - version "5.12.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c" - integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ== + version "5.13.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" + integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== dependencies: acorn "^8.5.0" commander "^2.20.0" - source-map "~0.7.2" + source-map "~0.8.0-beta.0" source-map-support "~0.5.20" test-exclude@^6.0.0: @@ -16641,6 +16927,11 @@ ts-dedent@^2.0.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== +ts-easing@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec" + integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ== + ts-jest@^27.1.4: version "27.1.4" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.4.tgz#84d42cf0f4e7157a52e7c64b1492c46330943e00" @@ -16655,10 +16946,10 @@ ts-jest@^27.1.4: semver "7.x" yargs-parser "20.x" -ts-loader@^9.2.8, ts-loader@^9.2.9: - version "9.2.9" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.2.9.tgz#0653e07fa1b4f225d0ca57a84fddbfd43d930f9e" - integrity sha512-b0+vUY2/enb0qYtDQuNlDnJ9900NTiPiJcDJ6sY7ax1CCCwXfYIqPOMm/BwW7jsF1km+Oz8W9s31HLuD+FLIMg== +ts-loader@^9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.3.0.tgz#980f4dbfb60e517179e15e10ed98e454b132159f" + integrity sha512-2kLLAdAD+FCKijvGKi9sS0OzoqxLCF3CxHpok7rVgCZ5UldRzH0TkbwG9XECKjBzHsAewntC5oDaI/FwKzEUog== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -16713,7 +17004,12 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1, tslib@~2.3.1: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.0, tslib@^2.3.1: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@~2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== @@ -16805,9 +17101,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^4.6.3: - version "4.6.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.3.tgz#eefeafa6afdd31d725584c67a0eaba80f6fc6c6c" - integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== + version "4.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" + integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== ua-parser-js@^0.7.30: version "0.7.31" @@ -16820,13 +17116,13 @@ uglify-js@^3.1.4: integrity sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA== unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" unfetch@^4.2.0: @@ -17093,21 +17389,21 @@ urlgrey@1.0.0: fast-url-parser "^1.1.3" use-composed-ref@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.2.1.tgz#9bdcb5ccd894289105da2325e1210079f56bf849" - integrity sha512-6+X1FLlIcjvFMAeAD/hcxDT8tmyrWnbSPMU0EnxQuDLIxokuFzWliXBiYZuGIx+mrAMLBw0WFfCkaPw8ebzAhw== + version "1.3.0" + resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" + integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== -use-isomorphic-layout-effect@^1.0.0: +use-isomorphic-layout-effect@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== use-latest@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" - integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== + version "1.2.1" + resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.1.tgz#d13dfb4b08c28e3e33991546a2cee53e14038cf2" + integrity sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw== dependencies: - use-isomorphic-layout-effect "^1.0.0" + use-isomorphic-layout-effect "^1.1.1" use@^3.1.0: version "3.1.1" @@ -17191,7 +17487,7 @@ v8-compile-cache@^2.0.3: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^8.0.0, v8-to-istanbul@^8.1.0: +v8-to-istanbul@^8.1.0: version "8.1.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== @@ -17200,6 +17496,15 @@ v8-to-istanbul@^8.0.0, v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +v8-to-istanbul@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz#be0dae58719fc53cb97e5c7ac1d7e6d4f5b19511" + integrity sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -18368,7 +18673,7 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.7: +yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.9: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==