Add prettier and format
This commit is contained in:
		
							parent
							
								
									f122b5fd7f
								
							
						
					
					
						commit
						15c9fbd13b
					
				
							
								
								
									
										5
									
								
								packages/components/.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								packages/components/.prettierignore
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| dist | ||||
| build | ||||
| node_modules | ||||
| storybook-static | ||||
| .storybook | ||||
							
								
								
									
										1
									
								
								packages/components/.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								packages/components/.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {} | ||||
							
								
								
									
										57037
									
								
								packages/components/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										57037
									
								
								packages/components/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -69,6 +69,7 @@ | |||
|     "@storybook/preset-create-react-app": "^4.0.0", | ||||
|     "@storybook/react": "^6.4.18", | ||||
|     "@types/webpack": "^5.28.0", | ||||
|     "prettier": "^2.6.0", | ||||
|     "react-codejar": "^1.1.2", | ||||
|     "ts-loader": "^9.2.8", | ||||
|     "webpack": "^5.70.0", | ||||
|  |  | |||
|  | @ -5,10 +5,7 @@ | |||
|     <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> | ||||
|     <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||||
|     <meta name="theme-color" content="#000000" /> | ||||
|     <meta | ||||
|       name="description" | ||||
|       content="Squiggle components" | ||||
|     /> | ||||
|     <meta name="description" content="Squiggle components" /> | ||||
|     <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> | ||||
|     <title>Squiggle Components</title> | ||||
|   </head> | ||||
|  |  | |||
|  | @ -1,92 +1,96 @@ | |||
| import * as React  from 'react'; | ||||
| import _ from 'lodash'; | ||||
| import type { Spec } from 'vega'; | ||||
| import { run } from '@quri/squiggle-lang'; | ||||
| import type { DistPlus, SamplingInputs, exportEnv, exportDistribution } from '@quri/squiggle-lang'; | ||||
| import { createClassFromSpec } from 'react-vega'; | ||||
| import * as chartSpecification from './spec-distributions.json' | ||||
| import * as percentilesSpec from './spec-pertentiles.json' | ||||
| import * as React from "react"; | ||||
| import _ from "lodash"; | ||||
| import type { Spec } from "vega"; | ||||
| import { run } from "@quri/squiggle-lang"; | ||||
| import type { | ||||
|   DistPlus, | ||||
|   SamplingInputs, | ||||
|   exportEnv, | ||||
|   exportDistribution, | ||||
| } from "@quri/squiggle-lang"; | ||||
| import { createClassFromSpec } from "react-vega"; | ||||
| import * as chartSpecification from "./spec-distributions.json"; | ||||
| import * as percentilesSpec from "./spec-pertentiles.json"; | ||||
| 
 | ||||
| let SquiggleVegaChart = createClassFromSpec({'spec': chartSpecification as Spec}); | ||||
| let SquiggleVegaChart = createClassFromSpec({ | ||||
|   spec: chartSpecification as Spec, | ||||
| }); | ||||
| 
 | ||||
| let SquigglePercentilesChart = createClassFromSpec({'spec': percentilesSpec as Spec}); | ||||
| let SquigglePercentilesChart = createClassFromSpec({ | ||||
|   spec: percentilesSpec as Spec, | ||||
| }); | ||||
| 
 | ||||
| export interface SquiggleChartProps { | ||||
|   /** The input string for squiggle */ | ||||
|   squiggleString : string, | ||||
|   squiggleString: string; | ||||
| 
 | ||||
|   /** If the output requires monte carlo sampling, the amount of samples */ | ||||
|   sampleCount? : number, | ||||
|   sampleCount?: number; | ||||
|   /** The amount of points returned to draw the distribution */ | ||||
|   outputXYPoints? : number, | ||||
|   kernelWidth? : number, | ||||
|   pointDistLength? : number, | ||||
|   outputXYPoints?: number; | ||||
|   kernelWidth?: number; | ||||
|   pointDistLength?: number; | ||||
|   /** If the result is a function, where the function starts */ | ||||
|   diagramStart? : number, | ||||
|   diagramStart?: number; | ||||
|   /** If the result is a function, where the function ends */ | ||||
|   diagramStop? : number, | ||||
|   diagramStop?: number; | ||||
|   /** If the result is a function, how many points along the function it samples */ | ||||
|   diagramCount? : number, | ||||
|   diagramCount?: number; | ||||
|   /** variables declared before this expression */ | ||||
|   environment? : exportEnv, | ||||
|   environment?: exportEnv; | ||||
|   /** When the environment changes */ | ||||
|   onEnvChange?(env: exportEnv): void | ||||
|   onEnvChange?(env: exportEnv): void; | ||||
| } | ||||
| 
 | ||||
| export const SquiggleChart : React.FC<SquiggleChartProps> = props => { | ||||
|   let samplingInputs : SamplingInputs = { | ||||
|     sampleCount : props.sampleCount, | ||||
|     outputXYPoints : props.outputXYPoints, | ||||
|     kernelWidth : props.kernelWidth, | ||||
|     pointDistLength : props.pointDistLength | ||||
|   } | ||||
|   | ||||
| export const SquiggleChart: React.FC<SquiggleChartProps> = (props) => { | ||||
|   let samplingInputs: SamplingInputs = { | ||||
|     sampleCount: props.sampleCount, | ||||
|     outputXYPoints: props.outputXYPoints, | ||||
|     kernelWidth: props.kernelWidth, | ||||
|     pointDistLength: props.pointDistLength, | ||||
|   }; | ||||
| 
 | ||||
|   let result = run(props.squiggleString, samplingInputs, props.environment); | ||||
|   if (result.tag === "Ok") { | ||||
|     let environment = result.value.environment | ||||
|     let exports = result.value.exports | ||||
|     if(props.onEnvChange) | ||||
|       props.onEnvChange(environment) | ||||
|     let chartResults = exports.map((chartResult:exportDistribution )=> { | ||||
|       if(chartResult["NAME"] === "Float"){ | ||||
|     let environment = result.value.environment; | ||||
|     let exports = result.value.exports; | ||||
|     if (props.onEnvChange) props.onEnvChange(environment); | ||||
|     let chartResults = exports.map((chartResult: exportDistribution) => { | ||||
|       if (chartResult["NAME"] === "Float") { | ||||
|         return <MakeNumberShower precision={3} number={chartResult["VAL"]} />; | ||||
|       } | ||||
|       else if(chartResult["NAME"] === "DistPlus"){ | ||||
|       } else if (chartResult["NAME"] === "DistPlus") { | ||||
|         let shape = chartResult.VAL.pointSetDist; | ||||
|         if(shape.tag === "Continuous"){ | ||||
|         if (shape.tag === "Continuous") { | ||||
|           let xyShape = shape.value.xyShape; | ||||
|           let totalY = xyShape.ys.reduce((a, b) => a + b); | ||||
|           let total = 0; | ||||
|           let cdf = xyShape.ys.map(y => { | ||||
|           let cdf = xyShape.ys.map((y) => { | ||||
|             total += y; | ||||
|             return total / totalY; | ||||
|           }) | ||||
|           let values = _.zip(cdf, xyShape.xs, xyShape.ys).map(([c, x, y ]) => ({cdf: (c * 100).toFixed(2) + "%", x: x, y: y})); | ||||
|           }); | ||||
|           let values = _.zip(cdf, xyShape.xs, xyShape.ys).map(([c, x, y]) => ({ | ||||
|             cdf: (c * 100).toFixed(2) + "%", | ||||
|             x: x, | ||||
|             y: y, | ||||
|           })); | ||||
| 
 | ||||
|           return ( | ||||
|             <SquiggleVegaChart  | ||||
|               data={{"con": values}} | ||||
|               /> | ||||
|           ); | ||||
|         } | ||||
|         else if(shape.tag === "Discrete"){ | ||||
|           return <SquiggleVegaChart data={{ con: values }} />; | ||||
|         } else if (shape.tag === "Discrete") { | ||||
|           let xyShape = shape.value.xyShape; | ||||
|           let totalY = xyShape.ys.reduce((a, b) => a + b); | ||||
|           let total = 0; | ||||
|           let cdf = xyShape.ys.map(y => { | ||||
|           let cdf = xyShape.ys.map((y) => { | ||||
|             total += y; | ||||
|             return total / totalY; | ||||
|           }) | ||||
|           let values = _.zip(cdf, xyShape.xs, xyShape.ys).map(([c, x,y]) => ({cdf: (c * 100).toFixed(2) + "%", x: x, y: y})); | ||||
|           }); | ||||
|           let values = _.zip(cdf, xyShape.xs, xyShape.ys).map(([c, x, y]) => ({ | ||||
|             cdf: (c * 100).toFixed(2) + "%", | ||||
|             x: x, | ||||
|             y: y, | ||||
|           })); | ||||
| 
 | ||||
|           return ( | ||||
|             <SquiggleVegaChart  | ||||
|               data={{"dis": values}} | ||||
|               /> | ||||
|           ); | ||||
|         } | ||||
|         else if(shape.tag === "Mixed"){ | ||||
|           return <SquiggleVegaChart data={{ dis: values }} />; | ||||
|         } else if (shape.tag === "Mixed") { | ||||
|           let discreteShape = shape.value.discrete.xyShape; | ||||
|           let totalDiscrete = discreteShape.ys.reduce((a, b) => a + b); | ||||
| 
 | ||||
|  | @ -95,141 +99,150 @@ export const SquiggleChart : React.FC<SquiggleChartProps> = props => { | |||
|           let continuousPoints = _.zip(continuousShape.xs, continuousShape.ys); | ||||
| 
 | ||||
|           interface labeledPoint { | ||||
|             x: number, | ||||
|             y: number, | ||||
|             type: "discrete" | "continuous" | ||||
|           }; | ||||
|             x: number; | ||||
|             y: number; | ||||
|             type: "discrete" | "continuous"; | ||||
|           } | ||||
| 
 | ||||
|           let markedDisPoints : labeledPoint[] = discretePoints.map(([x,y]) => ({x: x, y: y, type: "discrete"})) | ||||
|           let markedConPoints : labeledPoint[] = continuousPoints.map(([x,y]) => ({x: x, y: y, type: "continuous"})) | ||||
|           let markedDisPoints: labeledPoint[] = discretePoints.map( | ||||
|             ([x, y]) => ({ x: x, y: y, type: "discrete" }) | ||||
|           ); | ||||
|           let markedConPoints: labeledPoint[] = continuousPoints.map( | ||||
|             ([x, y]) => ({ x: x, y: y, type: "continuous" }) | ||||
|           ); | ||||
| 
 | ||||
|           let sortedPoints = _.sortBy(markedDisPoints.concat(markedConPoints), 'x') | ||||
|           let sortedPoints = _.sortBy( | ||||
|             markedDisPoints.concat(markedConPoints), | ||||
|             "x" | ||||
|           ); | ||||
| 
 | ||||
|           let totalContinuous = 1 - totalDiscrete; | ||||
|           let totalY = continuousShape.ys.reduce((a:number, b:number) => a + b); | ||||
|           let totalY = continuousShape.ys.reduce( | ||||
|             (a: number, b: number) => a + b | ||||
|           ); | ||||
| 
 | ||||
|           let total = 0; | ||||
|           let cdf = sortedPoints.map((point: labeledPoint) => { | ||||
|             if(point.type == "discrete") { | ||||
|             if (point.type == "discrete") { | ||||
|               total += point.y; | ||||
|               return total; | ||||
|             } | ||||
|             else if (point.type == "continuous") { | ||||
|               total += point.y / totalY * totalContinuous; | ||||
|             } else if (point.type == "continuous") { | ||||
|               total += (point.y / totalY) * totalContinuous; | ||||
|               return total; | ||||
|             } | ||||
|           }); | ||||
| 
 | ||||
|           interface cdfLabeledPoint { | ||||
|             cdf: string, | ||||
|             x: number, | ||||
|             y: number, | ||||
|             type: "discrete" | "continuous" | ||||
|             cdf: string; | ||||
|             x: number; | ||||
|             y: number; | ||||
|             type: "discrete" | "continuous"; | ||||
|           } | ||||
|           let cdfLabeledPoint : cdfLabeledPoint[] = _.zipWith(cdf, sortedPoints, (c: number, point: labeledPoint) => ({...point, cdf: (c * 100).toFixed(2) + "%"})) | ||||
|           let continuousValues = cdfLabeledPoint.filter(x => x.type == "continuous") | ||||
|           let discreteValues = cdfLabeledPoint.filter(x => x.type == "discrete") | ||||
|           let cdfLabeledPoint: cdfLabeledPoint[] = _.zipWith( | ||||
|             cdf, | ||||
|             sortedPoints, | ||||
|             (c: number, point: labeledPoint) => ({ | ||||
|               ...point, | ||||
|               cdf: (c * 100).toFixed(2) + "%", | ||||
|             }) | ||||
|           ); | ||||
|           let continuousValues = cdfLabeledPoint.filter( | ||||
|             (x) => x.type == "continuous" | ||||
|           ); | ||||
|           let discreteValues = cdfLabeledPoint.filter( | ||||
|             (x) => x.type == "discrete" | ||||
|           ); | ||||
| 
 | ||||
|           return ( | ||||
|             <SquiggleVegaChart | ||||
|               data={{"con": continuousValues, "dis": discreteValues}} | ||||
|               /> | ||||
|               data={{ con: continuousValues, dis: discreteValues }} | ||||
|             /> | ||||
|           ); | ||||
|           } | ||||
|       } | ||||
|       else if(chartResult.NAME === "Function"){ | ||||
|         // We are looking at a function. In this case, we draw a Percentiles chart
 | ||||
|           let start = props.diagramStart ? props.diagramStart : 0 | ||||
|           let stop = props.diagramStop ? props.diagramStop : 10 | ||||
|           let count = props.diagramCount ? props.diagramCount : 0.1 | ||||
|           let step = (stop - start)/ count | ||||
|           let data = _.range(start, stop, step).map(x => { | ||||
|             if(chartResult.NAME=="Function"){ | ||||
|               let result = chartResult.VAL(x); | ||||
|               if(result.tag == "Ok"){ | ||||
|                 let percentileArray = [ | ||||
|                   0.01, | ||||
|                   0.05, | ||||
|                   0.1, | ||||
|                   0.2, | ||||
|                   0.3, | ||||
|                   0.4, | ||||
|                   0.5, | ||||
|                   0.6, | ||||
|                   0.7, | ||||
|                   0.8, | ||||
|                   0.9, | ||||
|                   0.95, | ||||
|                   0.99 | ||||
|                 ] | ||||
|                    | ||||
|                 let percentiles = getPercentiles(percentileArray, result.value); | ||||
|                 return { | ||||
|                   "x": x, | ||||
|                   "p1": percentiles[0], | ||||
|                   "p5": percentiles[1], | ||||
|                   "p10": percentiles[2], | ||||
|                   "p20": percentiles[3], | ||||
|                   "p30": percentiles[4], | ||||
|                   "p40": percentiles[5], | ||||
|                   "p50": percentiles[6], | ||||
|                   "p60": percentiles[7], | ||||
|                   "p70": percentiles[8], | ||||
|                   "p80": percentiles[9], | ||||
|                   "p90": percentiles[10], | ||||
|                   "p95": percentiles[11], | ||||
|                   "p99": percentiles[12] | ||||
|                 } | ||||
| 
 | ||||
|                 } | ||||
| 
 | ||||
|               } | ||||
|               return 0; | ||||
|           }) | ||||
|           return <SquigglePercentilesChart data={{"facet": data}} /> | ||||
|         } | ||||
|       }) | ||||
|     return <>{chartResults}</>; | ||||
|   } | ||||
|   else if(result.tag == "Error") { | ||||
|     // At this point, we came across an error. What was our error?
 | ||||
|     return (<p>{"Error parsing Squiggle: " + result.value}</p>) | ||||
|       } else if (chartResult.NAME === "Function") { | ||||
|         // We are looking at a function. In this case, we draw a Percentiles chart
 | ||||
|         let start = props.diagramStart ? props.diagramStart : 0; | ||||
|         let stop = props.diagramStop ? props.diagramStop : 10; | ||||
|         let count = props.diagramCount ? props.diagramCount : 0.1; | ||||
|         let step = (stop - start) / count; | ||||
|         let data = _.range(start, stop, step).map((x) => { | ||||
|           if (chartResult.NAME == "Function") { | ||||
|             let result = chartResult.VAL(x); | ||||
|             if (result.tag == "Ok") { | ||||
|               let percentileArray = [ | ||||
|                 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95, | ||||
|                 0.99, | ||||
|               ]; | ||||
| 
 | ||||
|               let percentiles = getPercentiles(percentileArray, result.value); | ||||
|               return { | ||||
|                 x: x, | ||||
|                 p1: percentiles[0], | ||||
|                 p5: percentiles[1], | ||||
|                 p10: percentiles[2], | ||||
|                 p20: percentiles[3], | ||||
|                 p30: percentiles[4], | ||||
|                 p40: percentiles[5], | ||||
|                 p50: percentiles[6], | ||||
|                 p60: percentiles[7], | ||||
|                 p70: percentiles[8], | ||||
|                 p80: percentiles[9], | ||||
|                 p90: percentiles[10], | ||||
|                 p95: percentiles[11], | ||||
|                 p99: percentiles[12], | ||||
|               }; | ||||
|             } | ||||
|           } | ||||
|           return 0; | ||||
|         }); | ||||
|         return <SquigglePercentilesChart data={{ facet: data }} />; | ||||
|       } | ||||
|     }); | ||||
|     return <>{chartResults}</>; | ||||
|   } else if (result.tag == "Error") { | ||||
|     // At this point, we came across an error. What was our error?
 | ||||
|     return <p>{"Error parsing Squiggle: " + result.value}</p>; | ||||
|   } | ||||
|   return (<p>{"Invalid Response"}</p>) | ||||
|   return <p>{"Invalid Response"}</p>; | ||||
| }; | ||||
| 
 | ||||
| function getPercentiles(percentiles:number[], t : DistPlus) { | ||||
|   if(t.pointSetDist.tag == "Discrete") { | ||||
| function getPercentiles(percentiles: number[], t: DistPlus) { | ||||
|   if (t.pointSetDist.tag == "Discrete") { | ||||
|     let total = 0; | ||||
|     let maxX = _.max(t.pointSetDist.value.xyShape.xs) | ||||
|     let bounds = percentiles.map(_ => maxX); | ||||
|      _.zipWith(t.pointSetDist.value.xyShape.xs,t.pointSetDist.value.xyShape.ys, (x,y) => { | ||||
|         total += y | ||||
|     let maxX = _.max(t.pointSetDist.value.xyShape.xs); | ||||
|     let bounds = percentiles.map((_) => maxX); | ||||
|     _.zipWith( | ||||
|       t.pointSetDist.value.xyShape.xs, | ||||
|       t.pointSetDist.value.xyShape.ys, | ||||
|       (x, y) => { | ||||
|         total += y; | ||||
|         percentiles.forEach((v, i) => { | ||||
|         if(total > v && bounds[i] == maxX){ | ||||
|         bounds[i] = x | ||||
|         } | ||||
|         }) | ||||
|      }); | ||||
|      return bounds; | ||||
|   } | ||||
|   else if(t.pointSetDist.tag == "Continuous"){ | ||||
|           if (total > v && bounds[i] == maxX) { | ||||
|             bounds[i] = x; | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     ); | ||||
|     return bounds; | ||||
|   } else if (t.pointSetDist.tag == "Continuous") { | ||||
|     let total = 0; | ||||
|     let maxX = _.max(t.pointSetDist.value.xyShape.xs) | ||||
|     let totalY = _.sum(t.pointSetDist.value.xyShape.ys) | ||||
|     let bounds = percentiles.map(_ => maxX); | ||||
|      _.zipWith(t.pointSetDist.value.xyShape.xs,t.pointSetDist.value.xyShape.ys, (x,y) => { | ||||
|     let maxX = _.max(t.pointSetDist.value.xyShape.xs); | ||||
|     let totalY = _.sum(t.pointSetDist.value.xyShape.ys); | ||||
|     let bounds = percentiles.map((_) => maxX); | ||||
|     _.zipWith( | ||||
|       t.pointSetDist.value.xyShape.xs, | ||||
|       t.pointSetDist.value.xyShape.ys, | ||||
|       (x, y) => { | ||||
|         total += y / totalY; | ||||
|         percentiles.forEach((v, i) => { | ||||
|         if(total > v && bounds[i] == maxX){ | ||||
|         bounds[i] = x | ||||
|         } | ||||
|         }) | ||||
|      }); | ||||
|      return bounds; | ||||
|   } | ||||
|   else if(t.pointSetDist.tag == "Mixed"){ | ||||
|           if (total > v && bounds[i] == maxX) { | ||||
|             bounds[i] = x; | ||||
|           } | ||||
|         }); | ||||
|       } | ||||
|     ); | ||||
|     return bounds; | ||||
|   } else if (t.pointSetDist.tag == "Mixed") { | ||||
|     let discreteShape = t.pointSetDist.value.discrete.xyShape; | ||||
|     let totalDiscrete = discreteShape.ys.reduce((a, b) => a + b); | ||||
| 
 | ||||
|  | @ -238,80 +251,87 @@ function getPercentiles(percentiles:number[], t : DistPlus) { | |||
|     let continuousPoints = _.zip(continuousShape.xs, continuousShape.ys); | ||||
| 
 | ||||
|     interface labeledPoint { | ||||
|       x: number, | ||||
|       y: number, | ||||
|       type: "discrete" | "continuous" | ||||
|     }; | ||||
|       x: number; | ||||
|       y: number; | ||||
|       type: "discrete" | "continuous"; | ||||
|     } | ||||
| 
 | ||||
|     let markedDisPoints : labeledPoint[] = discretePoints.map(([x,y]) => ({x: x, y: y, type: "discrete"})) | ||||
|     let markedConPoints : labeledPoint[] = continuousPoints.map(([x,y]) => ({x: x, y: y, type: "continuous"})) | ||||
|     let markedDisPoints: labeledPoint[] = discretePoints.map(([x, y]) => ({ | ||||
|       x: x, | ||||
|       y: y, | ||||
|       type: "discrete", | ||||
|     })); | ||||
|     let markedConPoints: labeledPoint[] = continuousPoints.map(([x, y]) => ({ | ||||
|       x: x, | ||||
|       y: y, | ||||
|       type: "continuous", | ||||
|     })); | ||||
| 
 | ||||
|     let sortedPoints = _.sortBy(markedDisPoints.concat(markedConPoints), 'x') | ||||
|     let sortedPoints = _.sortBy(markedDisPoints.concat(markedConPoints), "x"); | ||||
| 
 | ||||
|     let totalContinuous = 1 - totalDiscrete; | ||||
|     let totalY = continuousShape.ys.reduce((a:number, b:number) => a + b); | ||||
|     let totalY = continuousShape.ys.reduce((a: number, b: number) => a + b); | ||||
| 
 | ||||
|     let total = 0; | ||||
|     let maxX = _.max(sortedPoints.map(x => x.x)); | ||||
|     let bounds = percentiles.map(_ => maxX); | ||||
|     let maxX = _.max(sortedPoints.map((x) => x.x)); | ||||
|     let bounds = percentiles.map((_) => maxX); | ||||
|     sortedPoints.map((point: labeledPoint) => { | ||||
|       if(point.type == "discrete") { | ||||
|       if (point.type == "discrete") { | ||||
|         total += point.y; | ||||
|       } else if (point.type == "continuous") { | ||||
|         total += (point.y / totalY) * totalContinuous; | ||||
|       } | ||||
|       else if (point.type == "continuous") { | ||||
|         total += point.y / totalY * totalContinuous; | ||||
|       } | ||||
|       percentiles.forEach((v,i) => { | ||||
|         if(total > v && bounds[i] == maxX){ | ||||
|       percentiles.forEach((v, i) => { | ||||
|         if (total > v && bounds[i] == maxX) { | ||||
|           bounds[i] = total; | ||||
|         } | ||||
|       }) | ||||
|       }); | ||||
|       return total; | ||||
|     }); | ||||
|     return bounds; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function MakeNumberShower(props: {number: number, precision :number}){ | ||||
| function MakeNumberShower(props: { number: number; precision: number }) { | ||||
|   let numberWithPresentation = numberShow(props.number, props.precision); | ||||
|   return ( | ||||
|     <span> | ||||
|       {numberWithPresentation.value} | ||||
|       {numberWithPresentation.symbol} | ||||
|       {numberWithPresentation.power ?  | ||||
|       <span> | ||||
|         {'\u00b710'} | ||||
|         <span style={{fontSize: "0.6em", verticalAlign: "super"}}> | ||||
|           {numberWithPresentation.power} | ||||
|       {numberWithPresentation.power ? ( | ||||
|         <span> | ||||
|           {"\u00b710"} | ||||
|           <span style={{ fontSize: "0.6em", verticalAlign: "super" }}> | ||||
|             {numberWithPresentation.power} | ||||
|           </span> | ||||
|         </span> | ||||
|       </span> | ||||
|       : <></>} | ||||
|       ) : ( | ||||
|         <></> | ||||
|       )} | ||||
|     </span> | ||||
| 
 | ||||
|     ); | ||||
| 
 | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| const orderOfMagnitudeNum = (n:number) => { | ||||
| const orderOfMagnitudeNum = (n: number) => { | ||||
|   return Math.pow(10, n); | ||||
| }; | ||||
| 
 | ||||
| // 105 -> 3
 | ||||
| const orderOfMagnitude = (n:number) => { | ||||
| const orderOfMagnitude = (n: number) => { | ||||
|   return Math.floor(Math.log(n) / Math.LN10 + 0.000000001); | ||||
| }; | ||||
| 
 | ||||
| function withXSigFigs(number:number, sigFigs:number) { | ||||
| function withXSigFigs(number: number, sigFigs: number) { | ||||
|   const withPrecision = number.toPrecision(sigFigs); | ||||
|   const formatted = Number(withPrecision); | ||||
|   return `${formatted}`; | ||||
| } | ||||
| 
 | ||||
| class NumberShower { | ||||
|   number: number | ||||
|   precision: number | ||||
|   number: number; | ||||
|   precision: number; | ||||
| 
 | ||||
|   constructor(number:number, precision = 2) { | ||||
|   constructor(number: number, precision = 2) { | ||||
|     this.number = number; | ||||
|     this.precision = precision; | ||||
|   } | ||||
|  | @ -320,9 +340,9 @@ class NumberShower { | |||
|     const number = Math.abs(this.number); | ||||
|     const response = this.evaluate(number); | ||||
|     if (this.number < 0) { | ||||
|       response.value = '-' + response.value; | ||||
|       response.value = "-" + response.value; | ||||
|     } | ||||
|     return response | ||||
|     return response; | ||||
|   } | ||||
| 
 | ||||
|   metricSystem(number: number, order: number) { | ||||
|  | @ -333,7 +353,7 @@ class NumberShower { | |||
| 
 | ||||
|   evaluate(number: number) { | ||||
|     if (number === 0) { | ||||
|       return { value: this.metricSystem(0, 0) } | ||||
|       return { value: this.metricSystem(0, 0) }; | ||||
|     } | ||||
| 
 | ||||
|     const order = orderOfMagnitude(number); | ||||
|  | @ -342,13 +362,13 @@ class NumberShower { | |||
|     } else if (order < 4) { | ||||
|       return { value: this.metricSystem(number, 0) }; | ||||
|     } else if (order < 6) { | ||||
|       return { value: this.metricSystem(number, 3), symbol: 'K' }; | ||||
|       return { value: this.metricSystem(number, 3), symbol: "K" }; | ||||
|     } else if (order < 9) { | ||||
|       return { value: this.metricSystem(number, 6), symbol: 'M' }; | ||||
|       return { value: this.metricSystem(number, 6), symbol: "M" }; | ||||
|     } else if (order < 12) { | ||||
|       return { value: this.metricSystem(number, 9), symbol: 'B' }; | ||||
|       return { value: this.metricSystem(number, 9), symbol: "B" }; | ||||
|     } else if (order < 15) { | ||||
|       return { value: this.metricSystem(number, 12), symbol: 'T' }; | ||||
|       return { value: this.metricSystem(number, 12), symbol: "T" }; | ||||
|     } else { | ||||
|       return { value: this.metricSystem(number, order), power: order }; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,30 +1,28 @@ | |||
| import * as React  from 'react'; | ||||
| import * as ReactDOM  from 'react-dom'; | ||||
| import { SquiggleChart } from './SquiggleChart' | ||||
| import * as React from "react"; | ||||
| import * as ReactDOM from "react-dom"; | ||||
| import { SquiggleChart } from "./SquiggleChart"; | ||||
| import { ReactCodeJar } from "react-codejar"; | ||||
| import type { exportEnv } from '@quri/squiggle-lang' | ||||
| 
 | ||||
| import type { exportEnv } from "@quri/squiggle-lang"; | ||||
| 
 | ||||
| export interface SquiggleEditorProps { | ||||
|   /** The input string for squiggle */ | ||||
|   initialSquiggleString? : string, | ||||
|    | ||||
|   initialSquiggleString?: string; | ||||
|   /** If the output requires monte carlo sampling, the amount of samples */ | ||||
|   sampleCount? : number, | ||||
|   sampleCount?: number; | ||||
|   /** The amount of points returned to draw the distribution */ | ||||
|   outputXYPoints? : number, | ||||
|   kernelWidth? : number, | ||||
|   pointDistLength? : number, | ||||
|   outputXYPoints?: number; | ||||
|   kernelWidth?: number; | ||||
|   pointDistLength?: number; | ||||
|   /** If the result is a function, where the function starts */ | ||||
|   diagramStart? : number, | ||||
|   diagramStart?: number; | ||||
|   /** If the result is a function, where the function ends */ | ||||
|   diagramStop? : number, | ||||
|   diagramStop?: number; | ||||
|   /** If the result is a function, how many points along the function it samples */ | ||||
|   diagramCount? : number, | ||||
|   diagramCount?: number; | ||||
|   /** The environment, other variables that were already declared */ | ||||
|   environment?: exportEnv, | ||||
|   environment?: exportEnv; | ||||
|   /** when the environment changes. Used again for notebook magic*/ | ||||
|   onEnvChange?(env: exportEnv) : void | ||||
|   onEnvChange?(env: exportEnv): void; | ||||
| } | ||||
| 
 | ||||
| const highlight = (editor: HTMLInputElement) => { | ||||
|  | @ -34,28 +32,30 @@ const highlight = (editor: HTMLInputElement) => { | |||
| }; | ||||
| 
 | ||||
| interface SquiggleEditorState { | ||||
|   expression: string, | ||||
|   env: exportEnv | ||||
|   expression: string; | ||||
|   env: exportEnv; | ||||
| } | ||||
| 
 | ||||
| export class SquiggleEditor extends React.Component<SquiggleEditorProps, SquiggleEditorState>{ | ||||
| export class SquiggleEditor extends React.Component< | ||||
|   SquiggleEditorProps, | ||||
|   SquiggleEditorState | ||||
| > { | ||||
|   constructor(props: SquiggleEditorProps) { | ||||
|     super(props) | ||||
|     let code = props.initialSquiggleString ? props.initialSquiggleString : "" | ||||
|     this.state = {expression: code, env: props.environment } | ||||
| 
 | ||||
|     super(props); | ||||
|     let code = props.initialSquiggleString ? props.initialSquiggleString : ""; | ||||
|     this.state = { expression: code, env: props.environment }; | ||||
|   } | ||||
|   render() { | ||||
|     let {expression, env} = this.state | ||||
|     let props = this.props | ||||
|     let { expression, env } = this.state; | ||||
|     let props = this.props; | ||||
|     return ( | ||||
|      <div> | ||||
|       <ReactCodeJar  | ||||
|         code={expression}  | ||||
|         onUpdate={e => { | ||||
|           this.setState({expression: e}) | ||||
|       <div> | ||||
|         <ReactCodeJar | ||||
|           code={expression} | ||||
|           onUpdate={(e) => { | ||||
|             this.setState({ expression: e }); | ||||
|           }} | ||||
|         style={{ | ||||
|           style={{ | ||||
|             borderRadius: "6px", | ||||
|             width: "530px", | ||||
|             border: "1px solid grey", | ||||
|  | @ -65,39 +65,43 @@ export class SquiggleEditor extends React.Component<SquiggleEditorProps, Squiggl | |||
|             letterSpacing: "normal", | ||||
|             lineHeight: "20px", | ||||
|             padding: "10px", | ||||
|             tabSize: "4" | ||||
|         }} | ||||
|         highlight={highlight} | ||||
|         lineNumbers={false} | ||||
|             tabSize: "4", | ||||
|           }} | ||||
|           highlight={highlight} | ||||
|           lineNumbers={false} | ||||
|         /> | ||||
|       <SquiggleChart  | ||||
|         squiggleString={expression} | ||||
|         sampleCount={props.sampleCount} | ||||
|         outputXYPoints={props.outputXYPoints} | ||||
|         kernelWidth={props.kernelWidth} | ||||
|         pointDistLength={props.pointDistLength} | ||||
|         diagramStart={props.diagramStart} | ||||
|         diagramStop={props.diagramStop} | ||||
|         diagramCount={props.diagramCount} | ||||
|         environment={env} | ||||
|         onEnvChange={props.onEnvChange} | ||||
|         <SquiggleChart | ||||
|           squiggleString={expression} | ||||
|           sampleCount={props.sampleCount} | ||||
|           outputXYPoints={props.outputXYPoints} | ||||
|           kernelWidth={props.kernelWidth} | ||||
|           pointDistLength={props.pointDistLength} | ||||
|           diagramStart={props.diagramStart} | ||||
|           diagramStop={props.diagramStop} | ||||
|           diagramCount={props.diagramCount} | ||||
|           environment={env} | ||||
|           onEnvChange={props.onEnvChange} | ||||
|         /> | ||||
|     </div> | ||||
|     ) | ||||
|       </div> | ||||
|     ); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function renderSquiggleEditor(props : SquiggleEditorProps) { | ||||
|   let parent = document.createElement("div") | ||||
|   ReactDOM.render(<SquiggleEditor {...props} onEnvChange={env => { | ||||
| export function renderSquiggleEditor(props: SquiggleEditorProps) { | ||||
|   let parent = document.createElement("div"); | ||||
|   ReactDOM.render( | ||||
|     <SquiggleEditor | ||||
|       {...props} | ||||
|       onEnvChange={(env) => { | ||||
|         // I can set the value here because I need it for creating notebooks
 | ||||
|         // @ts-ignore
 | ||||
|         parent.value = env; | ||||
| 
 | ||||
|     // I can set the value here because I need it for creating notebooks
 | ||||
|     // @ts-ignore
 | ||||
|     parent.value = env | ||||
| 
 | ||||
|     parent.dispatchEvent(new CustomEvent("input")) | ||||
|     if(props.onEnvChange) | ||||
|       props.onEnvChange(env) | ||||
|     }} /> , parent) | ||||
|   return parent | ||||
|         parent.dispatchEvent(new CustomEvent("input")); | ||||
|         if (props.onEnvChange) props.onEnvChange(env); | ||||
|       }} | ||||
|     />, | ||||
|     parent | ||||
|   ); | ||||
|   return parent; | ||||
| } | ||||
|  |  | |||
|  | @ -1,2 +1,2 @@ | |||
| export { SquiggleChart } from './SquiggleChart'; | ||||
| export { SquiggleEditor, renderSquiggleEditor } from './SquiggleEditor'; | ||||
| export { SquiggleChart } from "./SquiggleChart"; | ||||
| export { SquiggleEditor, renderSquiggleEditor } from "./SquiggleEditor"; | ||||
|  |  | |||
|  | @ -4,14 +4,14 @@ | |||
|   "width": 500, | ||||
|   "height": 200, | ||||
|   "padding": 5, | ||||
|   "data": [{"name": "con"}, {"name": "dis"}], | ||||
|   "data": [{ "name": "con" }, { "name": "dis" }], | ||||
| 
 | ||||
|   "signals": [ | ||||
|     { | ||||
|       "name": "mousex", | ||||
|       "description": "x position of mouse", | ||||
|       "update": "0", | ||||
|       "on": [{"events": "mousemove", "update": "1-x()/width"}] | ||||
|       "on": [{ "events": "mousemove", "update": "1-x()/width" }] | ||||
|     }, | ||||
|     { | ||||
|       "name": "xscale", | ||||
|  | @ -21,7 +21,7 @@ | |||
|         "input": "range", | ||||
|         "min": 0.1, | ||||
|         "max": 1 | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "name": "yscale", | ||||
|  | @ -31,90 +31,92 @@ | |||
|         "input": "range", | ||||
|         "min": 0.1, | ||||
|         "max": 1 | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   ], | ||||
| 
 | ||||
|   "scales": [{ | ||||
|     "name": "xscale", | ||||
|     "type": "pow", | ||||
|     "exponent": {"signal": "xscale"}, | ||||
|     "range": "width", | ||||
|     "zero": false, | ||||
|     "nice": false, | ||||
|     "domain": { | ||||
|       "fields": [ | ||||
|         { "data": "con", "field": "x"}, | ||||
|         { "data": "dis", "field": "x"} | ||||
|   "scales": [ | ||||
|     { | ||||
|       "name": "xscale", | ||||
|       "type": "pow", | ||||
|       "exponent": { "signal": "xscale" }, | ||||
|       "range": "width", | ||||
|       "zero": false, | ||||
|       "nice": false, | ||||
|       "domain": { | ||||
|         "fields": [ | ||||
|           { "data": "con", "field": "x" }, | ||||
|           { "data": "dis", "field": "x" } | ||||
|         ] | ||||
|       } | ||||
|   }, { | ||||
|     "name": "yscale", | ||||
|     "type": "pow", | ||||
|     "exponent": {"signal": "yscale"}, | ||||
|     "range": "height", | ||||
|     "nice": true, | ||||
|     "zero": true, | ||||
|     "domain": { | ||||
|       "fields": [ | ||||
|         { "data": "con", "field": "y"}, | ||||
|         { "data": "dis", "field": "y"} | ||||
|     }, | ||||
|     { | ||||
|       "name": "yscale", | ||||
|       "type": "pow", | ||||
|       "exponent": { "signal": "yscale" }, | ||||
|       "range": "height", | ||||
|       "nice": true, | ||||
|       "zero": true, | ||||
|       "domain": { | ||||
|         "fields": [ | ||||
|           { "data": "con", "field": "y" }, | ||||
|           { "data": "dis", "field": "y" } | ||||
|         ] | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   ], | ||||
| 
 | ||||
|   "axes": [ | ||||
|     {"orient": "bottom", "scale": "xscale", "tickCount": 20}, | ||||
|     {"orient": "left", "scale": "yscale"} | ||||
|     { "orient": "bottom", "scale": "xscale", "tickCount": 20 }, | ||||
|     { "orient": "left", "scale": "yscale" } | ||||
|   ], | ||||
| 
 | ||||
|   "marks": [ | ||||
|     { | ||||
|       "type": "area", | ||||
|       "from": {"data": "con"}, | ||||
|       "from": { "data": "con" }, | ||||
|       "encode": { | ||||
|         "enter": { | ||||
|           "tooltip": {"signal": "datum.cdf"} | ||||
|           "tooltip": { "signal": "datum.cdf" } | ||||
|         }, | ||||
|         "update": { | ||||
|           "x": {"scale": "xscale", "field": "x"}, | ||||
|           "y": {"scale": "yscale", "field": "y"}, | ||||
|           "y2": {"scale": "yscale", "value": 0}, | ||||
|           "x": { "scale": "xscale", "field": "x" }, | ||||
|           "y": { "scale": "yscale", "field": "y" }, | ||||
|           "y2": { "scale": "yscale", "value": 0 }, | ||||
|           "fill": { | ||||
|               "signal": "{gradient: 'linear', x1: 1, y1: 1, x2: 0, y2: 1, stops: [ {offset: 0.0, color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'blue'}, {offset: 1.0, color: 'blue'} ] }" | ||||
|             }, | ||||
|           "interpolate": {"value": "monotone"}, | ||||
|           "fillOpacity": {"value": 1} | ||||
|             "signal": "{gradient: 'linear', x1: 1, y1: 1, x2: 0, y2: 1, stops: [ {offset: 0.0, color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'steelblue'}, {offset: clamp(mousex, 0, 1), color: 'blue'}, {offset: 1.0, color: 'blue'} ] }" | ||||
|           }, | ||||
|           "interpolate": { "value": "monotone" }, | ||||
|           "fillOpacity": { "value": 1 } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "type": "rect", | ||||
|       "from": {"data": "dis"}, | ||||
|       "from": { "data": "dis" }, | ||||
|       "encode": { | ||||
|         "enter": { | ||||
|           "y2": {"scale": "yscale", "value": 0}, | ||||
|           "width": {"value": 1} | ||||
|           "y2": { "scale": "yscale", "value": 0 }, | ||||
|           "width": { "value": 1 } | ||||
|         }, | ||||
|         "update": { | ||||
|           "x": {"scale": "xscale", "field": "x"}, | ||||
|           "y": {"scale": "yscale", "field": "y"} | ||||
|           "x": { "scale": "xscale", "field": "x" }, | ||||
|           "y": { "scale": "yscale", "field": "y" } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     { | ||||
|       "type": "symbol", | ||||
|       "from": {"data": "dis"}, | ||||
|       "from": { "data": "dis" }, | ||||
|       "encode": { | ||||
|         "enter": { | ||||
|           "shape": {"value": "circle"}, | ||||
|           "width": {"value": 5}, | ||||
|           "tooltip": {"signal": "datum.y"} | ||||
|           "shape": { "value": "circle" }, | ||||
|           "width": { "value": 5 }, | ||||
|           "tooltip": { "signal": "datum.y" } | ||||
|         }, | ||||
|         "update": { | ||||
|           "x": {"scale": "xscale", "field": "x"}, | ||||
|           "y": {"scale": "yscale", "field": "y"} | ||||
|           "x": { "scale": "xscale", "field": "x" }, | ||||
|           "y": { "scale": "yscale", "field": "y" } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import { Meta } from '@storybook/addon-docs'; | ||||
| import { Meta } from "@storybook/addon-docs"; | ||||
| 
 | ||||
| <Meta title="Squiggle/Introduction" /> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import { SquiggleChart } from '../SquiggleChart' | ||||
| import { Canvas, Meta, Story, Props } from '@storybook/addon-docs'; | ||||
| import { SquiggleChart } from "../SquiggleChart"; | ||||
| import { Canvas, Meta, Story, Props } from "@storybook/addon-docs"; | ||||
| 
 | ||||
| <Meta title="Squiggle/SquiggleChart" component={ SquiggleChart } /> | ||||
| <Meta title="Squiggle/SquiggleChart" component={SquiggleChart} /> | ||||
| 
 | ||||
| export const Template = SquiggleChart | ||||
| export const Template = SquiggleChart; | ||||
| 
 | ||||
| # Squiggle Chart | ||||
| 
 | ||||
|  | @ -19,53 +19,62 @@ could be continuous, discrete or mixed. | |||
| ## Distributions | ||||
| 
 | ||||
| An example of a normal distribution is: | ||||
| 
 | ||||
| <Canvas> | ||||
|   <Story | ||||
|     name="Normal" | ||||
|     args={{ | ||||
|       squiggleString: "normal(5,2)" | ||||
|     }}>  | ||||
|       squiggleString: "normal(5,2)", | ||||
|     }} | ||||
|   > | ||||
|     {Template.bind({})} | ||||
|   </Story> | ||||
| </Canvas> | ||||
| 
 | ||||
| 
 | ||||
| An example of a Discrete distribution is: | ||||
| 
 | ||||
| <Canvas> | ||||
|   <Story | ||||
|     name="Discrete" | ||||
|     args={{ | ||||
|       squiggleString: "mm(0, 1, [0.5, 0.5])" | ||||
|     }}> | ||||
|       squiggleString: "mm(0, 1, [0.5, 0.5])", | ||||
|     }} | ||||
|   > | ||||
|     {Template.bind({})} | ||||
|   </Story> | ||||
| </Canvas> | ||||
| 
 | ||||
| An example of a Mixed distribution is: | ||||
| 
 | ||||
| <Canvas> | ||||
|   <Story | ||||
|     name="Mixed" | ||||
|     args={{ | ||||
|       squiggleString: "mm(0, 5 to 10, [0.5, 0.5])" | ||||
|     }}>  | ||||
|       squiggleString: "mm(0, 5 to 10, [0.5, 0.5])", | ||||
|     }} | ||||
|   > | ||||
|     {Template.bind({})} | ||||
|   </Story> | ||||
| </Canvas> | ||||
| 
 | ||||
| ## Constants | ||||
| 
 | ||||
| A constant is a simple number as a result. This has special formatting rules | ||||
| to allow large and small numbers being printed cleanly. | ||||
| 
 | ||||
| <Canvas> | ||||
|   <Story | ||||
|     name="Constant" | ||||
|     args={{ | ||||
|       squiggleString: "500000 * 5000000" | ||||
|     }}>  | ||||
|       squiggleString: "500000 * 5000000", | ||||
|     }} | ||||
|   > | ||||
|     {Template.bind({})} | ||||
|   </Story> | ||||
| </Canvas> | ||||
| 
 | ||||
| ## Functions | ||||
| 
 | ||||
| Finally, a function can be returned, and this shows how the distribution changes | ||||
| over the axis between x = 0 and 10. | ||||
| 
 | ||||
|  | @ -73,8 +82,9 @@ over the axis between x = 0 and 10. | |||
|   <Story | ||||
|     name="Function" | ||||
|     args={{ | ||||
|       squiggleString: "f(x) = normal(x,x)\nf" | ||||
|     }}>  | ||||
|       squiggleString: "f(x) = normal(x,x)\nf", | ||||
|     }} | ||||
|   > | ||||
|     {Template.bind({})} | ||||
|   </Story> | ||||
| </Canvas> | ||||
|  |  | |||
|  | @ -1,32 +1,32 @@ | |||
| const path = require('path'); | ||||
| const path = require("path"); | ||||
| 
 | ||||
| module.exports = { | ||||
|   mode: 'production', | ||||
|   devtool: 'source-map', | ||||
|   entry: './src/index.ts', | ||||
|   mode: "production", | ||||
|   devtool: "source-map", | ||||
|   entry: "./src/index.ts", | ||||
|   module: { | ||||
|     rules: [ | ||||
|       { | ||||
|         test: /\.tsx?$/, | ||||
|         use: 'ts-loader', | ||||
|         use: "ts-loader", | ||||
|         exclude: /node_modules/, | ||||
|       }, | ||||
|     ], | ||||
|   }, | ||||
|   resolve: { | ||||
|     extensions: ['.js', '.tsx', '.ts'], | ||||
|     extensions: [".js", ".tsx", ".ts"], | ||||
|   }, | ||||
|   output: { | ||||
|     filename: 'bundle.js', | ||||
|     path: path.resolve(__dirname, 'dist'), | ||||
|     filename: "bundle.js", | ||||
|     path: path.resolve(__dirname, "dist"), | ||||
|     library: { | ||||
|       name: 'squiggle_components', | ||||
|       type: 'umd', | ||||
|       name: "squiggle_components", | ||||
|       type: "umd", | ||||
|     }, | ||||
|   }, | ||||
|   devServer: { | ||||
|     static: { | ||||
|       directory: path.join(__dirname, 'public'), | ||||
|       directory: path.join(__dirname, "public"), | ||||
|     }, | ||||
|     compress: true, | ||||
|     port: 9000, | ||||
|  |  | |||
|  | @ -14370,6 +14370,11 @@ prepend-http@^2.0.0: | |||
|   resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" | ||||
|   integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== | ||||
| 
 | ||||
| prettier@^2.6.0: | ||||
|   version "2.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.0.tgz#12f8f504c4d8ddb76475f441337542fa799207d4" | ||||
|   integrity sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A== | ||||
| 
 | ||||
| pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: | ||||
|   version "5.6.0" | ||||
|   resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user