├── js
└── index.js
├── .gitignore
├── docs
├── kp-chart.wasm
├── index.html
├── styles.css
└── kp-chart.js
├── src
├── web
│ ├── mod.rs
│ ├── root.rs
│ ├── chart.rs
│ └── people.rs
├── data
│ ├── mod.rs
│ ├── week.rs
│ ├── job.rs
│ ├── person.rs
│ └── day.rs
└── lib.rs
├── static
├── index.html
└── styles.css
├── README.md
├── package.json
├── Cargo.toml
├── webpack.config.js
├── Makefile
└── Cargo.lock
/js/index.js:
--------------------------------------------------------------------------------
1 | import("../pkg/index.js").catch(console.error);
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /pkg
3 | /node_modules
4 | .cache/
5 | dist/
6 | **/*.rs.bk
7 |
--------------------------------------------------------------------------------
/docs/kp-chart.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bluejekyll/kp-chart/HEAD/docs/kp-chart.wasm
--------------------------------------------------------------------------------
/src/web/mod.rs:
--------------------------------------------------------------------------------
1 | mod chart;
2 | mod people;
3 | mod root;
4 |
5 | pub use self::chart::Chart;
6 | pub use self::people::PeopleModel;
7 | pub use self::root::RootModel;
8 |
--------------------------------------------------------------------------------
/src/data/mod.rs:
--------------------------------------------------------------------------------
1 | mod day;
2 | mod job;
3 | mod person;
4 | mod week;
5 |
6 | pub use self::day::Day;
7 | pub use self::job::Job;
8 | pub use self::person::{Ability, Person};
9 | pub use self::week::Week;
10 |
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Kitchen Patrol
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/static/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Kitchen Patrol
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/data/week.rs:
--------------------------------------------------------------------------------
1 | use crate::data::{Day, Job};
2 |
3 | #[derive(Clone, Debug)]
4 | pub struct Week {
5 | week: Vec,
6 | }
7 |
8 | impl Week {
9 | pub fn new(week: Vec) -> Self {
10 | Self { week }
11 | }
12 |
13 | pub fn num_jobs(&self) -> usize {
14 | self.week[0].jobs().len()
15 | }
16 |
17 | pub fn days(&self) -> &[Day] {
18 | &self.week
19 | }
20 |
21 | pub fn jobs(&self) -> impl Iterator- {
22 | self.week[0].jobs().iter().map(|(job, _)| job)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Kitchen Patrol Charting Application
2 |
3 | An example application, written in Rust, by someone with little frontend experience
4 |
5 | ## Usage
6 |
7 | Browse to [https://bluejekyll.github.io/kp-chart/](https://bluejekyll.github.io/kp-chart/)
8 |
9 | ## Building
10 |
11 | - Initililize once
12 |
13 | ```console
14 | $> make init
15 | ```
16 |
17 | - Build
18 |
19 | ```console
20 | $> make build
21 | ```
22 |
23 | - Start a local appserver
24 |
25 | ```console
26 | $> make run
27 | ```
28 |
29 | ## Deploying
30 |
31 | ```console
32 | $> make deploy
33 | ```
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kp-chart",
3 | "version": "1.0.0",
4 | "description": "To keep up the contributions to the dollar jar.",
5 | "main": "index.js",
6 | "dependencies": {
7 | "webpack-dev-server": "^3.10.3"
8 | },
9 | "devDependencies": {
10 | "copy-webpack-plugin": "^5.1.1",
11 | "@wasm-tool/wasm-pack-plugin": "^1.2.0",
12 | "webpack": "^4.42.0",
13 | "webpack-cli": "^3.3.11",
14 | "base64-loader": "^1.0.0"
15 | },
16 | "scripts": {
17 | "start": "webpack-dev-server --open -d",
18 | "test": "wasm-pack test --headless",
19 | "build": "webpack"
20 | },
21 | "keywords": [],
22 | "author": "",
23 | "license": "ISC"
24 | }
25 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "kp-chart"
3 | version = "0.2.0"
4 | authors = ["Benjamin Fry "]
5 | edition = "2018"
6 |
7 | [lib]
8 | name = "kp_chart"
9 | crate-type = ["cdylib"]
10 |
11 | [dependencies]
12 | console_log = "0.1.2"
13 | futures = "0.3.4"
14 | log = "0.4.8"
15 | serde = "1.0"
16 | serde_derive = "1.0"
17 | serde_json = "1.0"
18 | web-sys = { version = "0.3.36", features = ['Document', 'Element', 'HtmlElement', 'Node', 'Window', 'RtcDataChannel', 'RtcDataChannelInit', 'RtcPeerConnection', 'RtcSessionDescription', 'RtcSessionDescriptionInit', 'RtcSdpType', 'RtcOfferOptions', 'RtcConfiguration', 'RtcIceTransportPolicy'] }
19 | wasm-bindgen = "0.2"
20 | wasm-bindgen-futures = "0.4.9"
21 | yew = { version = "0.13.0", features = ["web_sys"] }
22 |
--------------------------------------------------------------------------------
/src/data/job.rs:
--------------------------------------------------------------------------------
1 | use std::fmt::{self, Display, Formatter};
2 |
3 | use crate::data::Ability;
4 |
5 | #[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
6 | pub struct Job {
7 | name: String,
8 | people: Vec,
9 | }
10 |
11 | impl Job {
12 | pub fn new(name: &'static str, people: Vec) -> Self {
13 | Self {
14 | name: name.to_string(),
15 | people,
16 | }
17 | }
18 |
19 | pub fn name(&self) -> &str {
20 | &self.name
21 | }
22 |
23 | pub fn people(&self) -> &[Ability] {
24 | &self.people
25 | }
26 | }
27 |
28 | impl Display for Job {
29 | fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
30 | write!(fmt, "{}", self.name)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const CopyPlugin = require("copy-webpack-plugin");
3 | const WasmPackPlugin = require('@wasm-tool/wasm-pack-plugin')
4 |
5 | module.exports = {
6 | entry: './js/index.js',
7 | output: {
8 | filename: 'kp-chart.js',
9 | path: path.resolve(__dirname, 'dist'),
10 | },
11 | stats: "errors-only",
12 | plugins: [
13 | new CopyPlugin([
14 | {
15 | from: path.resolve(__dirname, "static"),
16 | to: path.resolve(__dirname, 'dist')
17 | }
18 | ],
19 | { logLevel: 'warn' }
20 | ),
21 | new WasmPackPlugin({
22 | crateDirectory: __dirname, // Define where the root of the rust code is located (where the cargo.toml file is located)
23 | }),
24 | ]
25 | };
--------------------------------------------------------------------------------
/src/web/root.rs:
--------------------------------------------------------------------------------
1 | use log::debug;
2 | use yew::prelude::*;
3 |
4 | use crate::web::*;
5 |
6 | pub struct RootModel {
7 | people_version: usize,
8 | link: ComponentLink,
9 | }
10 |
11 | pub enum RootMsg {
12 | PeopleUpdated(usize),
13 | }
14 |
15 | impl Component for RootModel {
16 | // Some details omitted. Explore the examples to get more.
17 |
18 | type Message = RootMsg;
19 | type Properties = ();
20 |
21 | fn create(_props: Self::Properties, link: ComponentLink) -> Self {
22 | RootModel {
23 | people_version: 0,
24 | link,
25 | }
26 | }
27 |
28 | fn update(&mut self, msg: Self::Message) -> ShouldRender {
29 | match msg {
30 | RootMsg::PeopleUpdated(version) => {
31 | debug!("root people version: {}", version);
32 | if self.people_version != version {
33 | self.people_version = version;
34 | true
35 | } else {
36 | false
37 | }
38 | }
39 | }
40 | }
41 |
42 | fn view(&self) -> Html {
43 | html! {
44 |
45 |
{"Kitchen Patrol Charts"}
46 |
47 |
48 |
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | TARGET_DIR ?= ./target
2 | CARGO_TARGET_DIR := ${TARGET_DIR}
3 | MODE ?= development
4 | RUSTFLAGS := -Ctarget-cpu=generic
5 | TMP_DIST_DIR := /tmp/kp-chart-dist
6 |
7 | .PHONY: init
8 | init:
9 | @echo "========> $@"
10 | @rustup --version || (curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh)
11 | rustup self update
12 | rustup update
13 | rustup target add wasm32-unknown-unknown
14 | cargo install wasm-pack
15 | npm --version
16 | npm install
17 |
18 | .PHONY: build
19 | wasm:
20 | @echo "========> $@"
21 | wasm-pack build
22 |
23 | .PHONY: build
24 | build:
25 | @echo "========> $@"
26 | npm run build -- --mode=${MODE}
27 |
28 | .PHONY: test
29 | test: build
30 | @echo "========> $@"
31 | cargo test
32 | npm run test
33 |
34 | .PHONY: run
35 | run: build
36 | @echo "========> $@"
37 | npm run start
38 |
39 | .PHONY: clean
40 | clean:
41 | @echo "========> $@"
42 | rm -rf ./pkg
43 | rm -rf ./dist
44 |
45 |
46 | .PHONY: deploy
47 | deploy: clean
48 | @echo "========> $@"
49 | @git --version
50 |
51 | # build the project
52 | $(MAKE) MODE=production WASM_MODE=--release build
53 |
54 | # deploy
55 | git worktree add ${TMP_DIST_DIR} gh-pages
56 | rm -rf ${TMP_DIST_DIR}/*
57 | cp -rp dist/* ${TMP_DIST_DIR}
58 | cd ${TMP_DIST_DIR} && \
59 | git add -A && \
60 | git diff --staged --quiet || \
61 | (git commit -m "deployed on $(shell date) by ${USER}" && \
62 | git push origin gh-pages)
63 | $(MAKE) clean_worktree
64 |
65 | .PHONY: clean_worktree
66 | clean_worktree:
67 | @echo "========> $@"
68 | rm -rf ${TMP_DIST_DIR}
69 | git worktree prune
70 |
--------------------------------------------------------------------------------
/docs/styles.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | text-align: center;
6 | font-family: Arial, Helvetica, sans-serif;
7 | }
8 |
9 | h1 {
10 | font-family: Georgia, serif;
11 | font-style: italic;
12 | }
13 |
14 | table {
15 | margin: 20px;
16 | background-color: cornsilk;
17 | box-shadow: 5px 5px 5px #aaaaaa;
18 | text-align: left;
19 | border-collapse: collapse;
20 | border: 1px solid #dddddd;
21 | }
22 |
23 | table th, table td {
24 | padding: 5px;
25 | }
26 |
27 | thead {
28 | padding: 10px;
29 | border: 1px;
30 | font-size: 12pt;
31 | font-style: normal;
32 | border-top-color: #c50d0d;
33 | border-top-width: 1px;
34 | border-top-style: solid;
35 | border-bottom-color: #290dc5;
36 | border-bottom-width: 5px;
37 | border-bottom-style: double;
38 | }
39 |
40 | tbody td {
41 | font-family: "Chalkboard", "ChalkboardSE-Regular", "Comic Sans", "Comic Sans MS", sans-serif;
42 | font-variant: small-caps;
43 | font-weight: bold;
44 | font-size: 16pt;
45 | color: crimson;
46 | }
47 |
48 | tbody th {
49 | border: 1px;
50 | font-size: 12pt;
51 | font-style: normal;
52 |
53 | }
54 |
55 | tbody th, tbody td {
56 | border-bottom-color: #000000;
57 | border-bottom-width: 1px;
58 | border-bottom-style: solid;
59 | border-right-color: #cacaca;
60 | border-right-width: 1px;
61 | border-right-style: solid;}
62 |
63 | tfoot td {
64 | border: none;
65 | }
66 |
67 | .edit_delete {
68 | color: black;
69 | }
70 |
71 | .disabled {
72 | color: lightgray;
73 | }
74 |
75 | i {
76 | cursor: pointer;
77 | }
78 |
79 | i:active {
80 | color: lightgray;
81 | }
--------------------------------------------------------------------------------
/static/styles.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | text-align: center;
6 | font-family: Arial, Helvetica, sans-serif;
7 | }
8 |
9 | h1 {
10 | font-family: Georgia, serif;
11 | font-style: italic;
12 | }
13 |
14 | table {
15 | margin: 20px;
16 | background-color: cornsilk;
17 | box-shadow: 5px 5px 5px #aaaaaa;
18 | text-align: left;
19 | border-collapse: collapse;
20 | border: 1px solid #dddddd;
21 | }
22 |
23 | table th, table td {
24 | padding: 5px;
25 | }
26 |
27 | thead {
28 | padding: 10px;
29 | border: 1px;
30 | font-size: 12pt;
31 | font-style: normal;
32 | border-top-color: #c50d0d;
33 | border-top-width: 1px;
34 | border-top-style: solid;
35 | border-bottom-color: #290dc5;
36 | border-bottom-width: 5px;
37 | border-bottom-style: double;
38 | }
39 |
40 | tbody td {
41 | font-family: "Chalkboard", "ChalkboardSE-Regular", "Comic Sans", "Comic Sans MS", sans-serif;
42 | font-variant: small-caps;
43 | font-weight: bold;
44 | font-size: 16pt;
45 | color: crimson;
46 | }
47 |
48 | tbody th {
49 | border: 1px;
50 | font-size: 12pt;
51 | font-style: normal;
52 |
53 | }
54 |
55 | tbody th, tbody td {
56 | border-bottom-color: #000000;
57 | border-bottom-width: 1px;
58 | border-bottom-style: solid;
59 | border-right-color: #cacaca;
60 | border-right-width: 1px;
61 | border-right-style: solid;}
62 |
63 | tfoot td {
64 | border: none;
65 | }
66 |
67 | .edit_delete {
68 | color: black;
69 | }
70 |
71 | .disabled {
72 | color: lightgray;
73 | }
74 |
75 | i {
76 | cursor: pointer;
77 | }
78 |
79 | i:active {
80 | color: lightgray;
81 | }
--------------------------------------------------------------------------------
/src/data/person.rs:
--------------------------------------------------------------------------------
1 | use serde::{Deserialize, Serialize};
2 | use std::fmt::{self, Display, Formatter};
3 |
4 | #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
5 | pub struct Person {
6 | name: String,
7 | ability: Ability,
8 | }
9 |
10 | impl Person {
11 | pub fn new(name: &'static str, ability: Ability) -> Self {
12 | Self {
13 | name: name.to_string(),
14 | ability,
15 | }
16 | }
17 |
18 | pub fn name(&self) -> &str {
19 | &self.name
20 | }
21 |
22 | pub fn ability(&self) -> Ability {
23 | self.ability
24 | }
25 |
26 | pub fn set_name(&mut self, name: String) {
27 | self.name = name;
28 | }
29 |
30 | pub fn set_ability(&mut self, ability: Ability) {
31 | self.ability = ability;
32 | }
33 | }
34 |
35 | impl Display for Person {
36 | fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
37 | write!(fmt, "{}", self.name)
38 | }
39 | }
40 |
41 | #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
42 | pub enum Ability {
43 | Adult = 0,
44 | Teen = 1,
45 | Child = 2,
46 | }
47 |
48 | impl Default for Ability {
49 | fn default() -> Self {
50 | Ability::Adult
51 | }
52 | }
53 |
54 | impl Ability {
55 | pub fn enumerate() -> &'static [Ability] {
56 | &[Ability::Adult, Ability::Teen, Ability::Child]
57 | }
58 |
59 | pub fn to_str(&self) -> &'static str {
60 | match self {
61 | Ability::Adult => "Adult",
62 | Ability::Teen => "Teen",
63 | Ability::Child => "Child",
64 | }
65 | }
66 |
67 | pub fn from_i32(prim: i32) -> Self {
68 | match prim {
69 | 0 => Ability::Adult,
70 | 1 => Ability::Teen,
71 | 2 => Ability::Child,
72 | _ => panic!("bad value for Ability: {}", prim),
73 | }
74 | }
75 | }
76 |
77 | impl From for i32 {
78 | fn from(ability: Ability) -> i32 {
79 | ability as i32
80 | }
81 | }
82 |
83 | impl Display for Ability {
84 | fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
85 | write!(fmt, "{}", self.to_str())
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/data/day.rs:
--------------------------------------------------------------------------------
1 | use std::fmt::{self, Display, Formatter};
2 | use std::iter::Cycle;
3 | use std::slice::Iter;
4 |
5 | use crate::data::{Ability, Job, Person};
6 |
7 | #[derive(Clone, Debug)]
8 | pub struct Day {
9 | name: String,
10 | jobs: Vec<(Job, Vec)>,
11 | }
12 |
13 | impl Day {
14 | pub fn new(
15 | name: String,
16 | jobs: Vec,
17 | children: &mut Cycle>,
18 | teens: &mut Cycle>,
19 | adults: &mut Cycle>,
20 | ) -> Self {
21 | let mut day_jobs = jobs
22 | .clone()
23 | .into_iter()
24 | .map(|j| (j, Vec::::new()))
25 | .collect::>();
26 |
27 | // pass through all children jobs first
28 | for (job, ref mut workers) in day_jobs.iter_mut() {
29 | for ability in job.people().iter() {
30 | match *ability {
31 | Ability::Child => workers.push(
32 | children
33 | .next()
34 | .cloned()
35 | .unwrap_or_else(|| Person::new("No Child Here", Ability::Child)),
36 | ),
37 | Ability::Teen => workers.push(
38 | teens
39 | .next()
40 | .cloned()
41 | .unwrap_or_else(|| Person::new("No Teen Here", Ability::Teen)),
42 | ),
43 | Ability::Adult => workers.push(
44 | adults
45 | .next()
46 | .cloned()
47 | .unwrap_or_else(|| Person::new("No Adult Here", Ability::Adult)),
48 | ),
49 | }
50 | }
51 | }
52 |
53 | Self {
54 | name,
55 | jobs: day_jobs,
56 | }
57 | }
58 |
59 | pub fn name(&self) -> &str {
60 | &self.name
61 | }
62 |
63 | pub fn jobs(&self) -> &[(Job, Vec)] {
64 | &self.jobs
65 | }
66 |
67 | pub fn get_job_people(&self, job: usize) -> &[Person] {
68 | &self.jobs[job].1
69 | }
70 | }
71 |
72 | impl Display for Day {
73 | fn fmt(&self, fmt: &mut Formatter) -> Result<(), fmt::Error> {
74 | for (job, people) in self.jobs.iter() {
75 | write!(fmt, "{}: ", job)?;
76 | for person in people.iter() {
77 | write!(fmt, "{}, ", person)?;
78 | }
79 | writeln!(fmt, "")?;
80 | }
81 | Ok(())
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/web/chart.rs:
--------------------------------------------------------------------------------
1 | use log::debug;
2 | use yew::prelude::*;
3 |
4 | use crate::data::*;
5 | use crate::web::people::PeopleStore;
6 | use yew::services::{storage::Area, StorageService};
7 |
8 | #[derive(Clone)]
9 | pub struct Chart {
10 | people_version: usize,
11 | week: Week,
12 | }
13 |
14 | #[derive(Clone, Default, PartialEq, Properties)]
15 | pub struct ChartProps {
16 | pub people_version: usize,
17 | }
18 |
19 | impl Chart {
20 | fn calculate() -> Self {
21 | debug!("calculating new week");
22 | let mut local_store = StorageService::new(Area::Local).expect("failed to get storage");
23 |
24 | let jobs = crate::default_jobs();
25 | let (people_version, people) = PeopleStore::restore(&mut local_store)
26 | .map(|p| (p.inc, p.people))
27 | .unwrap_or_else(|| (0, crate::default_people()));
28 | Self {
29 | people_version: people_version,
30 | week: crate::calculate(5, jobs, people),
31 | }
32 | }
33 | }
34 |
35 | impl Component for Chart {
36 | type Message = ();
37 | type Properties = ChartProps;
38 |
39 | fn create(_props: Self::Properties, _link: ComponentLink) -> Self {
40 | debug!("creating Chart");
41 | Self::calculate()
42 | }
43 |
44 | fn update(&mut self, _msg: Self::Message) -> ShouldRender {
45 | false
46 | }
47 |
48 | fn change(&mut self, props: Self::Properties) -> ShouldRender {
49 | if self.people_version != props.people_version {
50 | debug!("updating Chart");
51 | *self = Self::calculate();
52 | true
53 | } else {
54 | false
55 | }
56 | }
57 |
58 | fn view(&self) -> Html {
59 | let header = |name: &str| {
60 | html! {
61 | { format!("{}", name) } |
62 | }
63 | };
64 | let people_cell = |people: &[Person]| {
65 | let mut people_str = String::new();
66 | for person in people {
67 | people_str.push_str(person.name());
68 | people_str.push_str(", ");
69 | }
70 |
71 | html! {
72 | { people_str } |
73 | }
74 | };
75 | let job_row = |(job_idx, job): (usize, &Job)| {
76 | let days = self.week.days();
77 | html! {
78 | { header(job.name()) } { for days.iter().map(|d| people_cell(d.get_job_people(job_idx))) }
79 | }
80 | };
81 |
82 | html! {
83 | <>
84 | {"Job Chart"}
85 |
86 |
87 | | {"Job"} | { for self.week.days().iter().map(|d| header(d.name())) }
88 |
89 |
90 | { for self.week.jobs().enumerate().map(|j| job_row(j)) }
91 |
92 |
93 | >
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | #![recursion_limit = "2048"]
2 |
3 | pub mod data;
4 | pub mod web;
5 |
6 | use log::Level;
7 | use std::iter::*;
8 | use wasm_bindgen::prelude::*;
9 | use yew::prelude::*;
10 |
11 | use self::data::*;
12 |
13 | pub fn default_jobs() -> Vec {
14 | let mut jobs = Vec::::new();
15 | jobs.push(Job::new(
16 | "Breakfast dishes",
17 | vec![Ability::Teen, Ability::Child],
18 | ));
19 | jobs.push(Job::new(
20 | "Lunch preparation",
21 | vec![Ability::Adult, Ability::Adult],
22 | ));
23 | jobs.push(Job::new(
24 | "Lunch dishes",
25 | vec![Ability::Adult, Ability::Teen],
26 | ));
27 | jobs.push(Job::new(
28 | "Dinner Setting",
29 | vec![Ability::Teen, Ability::Child, Ability::Child],
30 | ));
31 | jobs.push(Job::new(
32 | "Dinner shopping and chef",
33 | vec![Ability::Adult, Ability::Adult],
34 | ));
35 | jobs.push(Job::new(
36 | "Dinner dishes",
37 | vec![Ability::Adult, Ability::Teen],
38 | ));
39 | jobs.push(Job::new("Late night dishes", vec![Ability::Teen]));
40 | jobs.push(Job::new("Cabin cleanup", vec![Ability::Adult]));
41 | jobs.push(Job::new("Nag", vec![Ability::Adult]));
42 |
43 | jobs
44 | }
45 |
46 | pub fn default_people() -> Vec {
47 | let mut people = Vec::::new();
48 | people.push(Person::new("Grandma", Ability::Adult));
49 | people.push(Person::new("Grandpa", Ability::Adult));
50 | people.push(Person::new("Mom", Ability::Adult));
51 | people.push(Person::new("Dad", Ability::Adult));
52 | people.push(Person::new("Aunt Jane", Ability::Adult));
53 | people.push(Person::new("Uncle Joe", Ability::Adult));
54 | people.push(Person::new("Jackie", Ability::Teen));
55 | people.push(Person::new("Jake", Ability::Teen));
56 | people.push(Person::new("Jill", Ability::Child));
57 | people.push(Person::new("Jeffrey", Ability::Child));
58 |
59 | return people;
60 | }
61 |
62 | pub fn calculate_day_jobs() -> Week {
63 | let jobs = default_jobs();
64 | let people = default_people();
65 | calculate(5, jobs, people)
66 | }
67 |
68 | pub fn calculate(num_days: usize, jobs: Vec, people: Vec) -> Week {
69 | let children = people
70 | .clone()
71 | .into_iter()
72 | .filter(|p| p.ability() == Ability::Child)
73 | .collect::>();
74 | let mut children_iter = children.iter().cycle();
75 |
76 | let teens = people
77 | .clone()
78 | .into_iter()
79 | .filter(|p| p.ability() == Ability::Teen)
80 | .collect::>();
81 | let mut teens_iter = teens.iter().cycle();
82 |
83 | let adults = people
84 | .clone()
85 | .into_iter()
86 | .filter(|p| p.ability() == Ability::Adult)
87 | .collect::>();
88 | let mut adults_iter = adults.iter().cycle();
89 |
90 | // make sure we have a good balance of jobs across adults, we nee the count of adult jobs
91 | let adult_job_count = jobs.iter().fold(0_usize, |count, j| {
92 | j.people().iter().filter(|a| **a == Ability::Adult).count() + count
93 | });
94 |
95 | let mut days = Vec::with_capacity(num_days);
96 | for i in 0..num_days {
97 | let day = Day::new(
98 | format!("day_{}", i),
99 | jobs.clone(),
100 | &mut children_iter,
101 | &mut teens_iter,
102 | &mut adults_iter,
103 | );
104 |
105 | // force an additional rotation to offset Dinner duty
106 | // we need to make sure we balance the rotation of major adult jobs
107 | if (adult_job_count + 1) == adults.len() {
108 | adults_iter.next();
109 | adults_iter.next();
110 | } else {
111 | adults_iter.next();
112 | }
113 |
114 | days.push(day);
115 | }
116 |
117 | Week::new(days)
118 | }
119 |
120 | #[wasm_bindgen(start)]
121 | pub fn start() -> Result<(), JsValue> {
122 | console_log::init_with_level(Level::Debug).expect("failed to initialize logger");
123 | yew::initialize();
124 |
125 | App::::new().mount_to_body_with_props(());
126 | yew::run_loop();
127 |
128 | Ok(())
129 | }
130 |
--------------------------------------------------------------------------------
/src/web/people.rs:
--------------------------------------------------------------------------------
1 | use log::{debug, error};
2 | use serde::{Deserialize, Serialize};
3 | use web_sys::HtmlSelectElement;
4 | use yew::callback::Callback;
5 | use yew::format::Json;
6 | use yew::prelude::*;
7 | use yew::services::{storage::Area, StorageService};
8 |
9 | use crate::data::*;
10 |
11 | const PEOPLE_KEY: &str = "people_v1";
12 | type IsEditting = bool;
13 | type Id = usize;
14 |
15 | pub enum PeopleMsg {
16 | AddPerson,
17 | SavePeople,
18 | EditPerson(Id),
19 | DeletePerson(Id),
20 | PersonNameInput(Id, String),
21 | PersonAbilityInput(Id, Ability),
22 | }
23 |
24 | #[derive(Clone)]
25 | pub struct PeopleModel {
26 | inc: usize,
27 | people: Vec<(Person, IsEditting)>,
28 | on_save: Option>,
29 | link: ComponentLink,
30 | }
31 |
32 | #[derive(Clone, Default, PartialEq, Properties)]
33 | pub struct PeopleProps {
34 | pub on_save: Option>,
35 | }
36 |
37 | #[derive(Clone, Serialize, Deserialize)]
38 | pub struct PeopleStore {
39 | pub inc: usize,
40 | pub people: Vec,
41 | }
42 |
43 | impl PeopleStore {
44 | pub fn restore(local_store: &mut StorageService) -> Option {
45 | let from_store = local_store.restore(PEOPLE_KEY);
46 | match from_store {
47 | Json(Ok(people)) => Some(people),
48 | // TODO: reset local store...
49 | Json(Err(err)) => {
50 | error!("could not load from local store: {}", err);
51 | None
52 | }
53 | }
54 | }
55 |
56 | pub fn store(&mut self, local_store: &mut StorageService) {
57 | self.inc += 1;
58 | debug!("saving people: {}", self.inc);
59 | local_store.store(PEOPLE_KEY, Json(self as &Self));
60 | }
61 | }
62 |
63 | impl From for PeopleStore {
64 | fn from(model: PeopleModel) -> Self {
65 | Self {
66 | inc: model.inc,
67 | people: model.people.into_iter().map(|(p, _)| p).collect(),
68 | }
69 | }
70 | }
71 |
72 | impl PeopleModel {
73 | fn from(
74 | model: PeopleStore,
75 | on_save: Option>,
76 | link: ComponentLink,
77 | ) -> Self {
78 | Self {
79 | inc: model.inc,
80 | people: model.people.into_iter().map(|p| (p, false)).collect(),
81 | on_save,
82 | link,
83 | }
84 | }
85 | }
86 |
87 | impl Component for PeopleModel {
88 | type Message = PeopleMsg;
89 | type Properties = PeopleProps;
90 |
91 | fn create(props: Self::Properties, link: ComponentLink) -> Self {
92 | debug!("creating PeopleModel");
93 |
94 | let mut local_store = StorageService::new(Area::Local).expect("failed to get storage");
95 |
96 | match PeopleStore::restore(&mut local_store) {
97 | Some(this) => Self {
98 | inc: this.inc,
99 | people: this.people.into_iter().map(|p| (p, false)).collect(),
100 | on_save: props.on_save,
101 | link,
102 | },
103 | None => {
104 | let people = crate::default_people();
105 | // TODO: make a borrowed type
106 | let mut people = PeopleStore {
107 | inc: 0,
108 | people: people,
109 | };
110 |
111 | people.store(&mut local_store);
112 | Self {
113 | inc: people.inc,
114 | people: people.people.into_iter().map(|p| (p, false)).collect(),
115 | on_save: props.on_save,
116 | link,
117 | }
118 | }
119 | }
120 | }
121 |
122 | fn update(&mut self, msg: Self::Message) -> ShouldRender {
123 | match msg {
124 | PeopleMsg::SavePeople => {
125 | debug!("saving PeopleModel");
126 | let mut local_store =
127 | StorageService::new(Area::Local).expect("failed to get storage");
128 | let mut people: PeopleStore = self.clone().into();
129 | people.store(&mut local_store);
130 | *self = PeopleModel::from(people, self.on_save.take(), self.link.clone());
131 |
132 | self.on_save.as_ref().map(|e| e.emit(self.inc));
133 | true
134 | }
135 | PeopleMsg::AddPerson => {
136 | debug!("adding a Person");
137 | let person = Person::new("Jane Doe", Ability::Adult);
138 | self.people.push((person, true));
139 | true
140 | }
141 | PeopleMsg::EditPerson(id) => {
142 | debug!("edit person: {}", id);
143 | self.people
144 | .get_mut(id)
145 | .map(|p| {
146 | if !p.1 {
147 | p.1 = true;
148 | true
149 | } else {
150 | false
151 | }
152 | })
153 | .unwrap_or(false)
154 | }
155 | PeopleMsg::DeletePerson(idx) => {
156 | let person = self.people.remove(idx);
157 | debug!("deleted {:?}", person);
158 | true
159 | }
160 | PeopleMsg::PersonNameInput(id, name) => self
161 | .people
162 | .get_mut(id)
163 | .map(|p| {
164 | debug!("saving name: {}", name);
165 | if p.0.name() != name {
166 | p.0.set_name(name);
167 | true
168 | } else {
169 | false
170 | }
171 | })
172 | .unwrap_or(false),
173 | PeopleMsg::PersonAbilityInput(id, ability) => self
174 | .people
175 | .get_mut(id)
176 | .map(|p| {
177 | debug!("saving name: {}", ability);
178 | if p.0.ability() != ability {
179 | p.0.set_ability(ability);
180 | true
181 | } else {
182 | false
183 | }
184 | })
185 | .unwrap_or(false),
186 | }
187 | }
188 |
189 | fn view(&self) -> Html {
190 | // let select = |is_selected: bool| {
191 | // html!{
192 | //
193 | // }
194 | // };
195 |
196 | let edit_delete = |id: Id, is_editting: IsEditting, link: &ComponentLink| {
197 | let on_edit = link.callback(PeopleMsg::EditPerson);
198 | let on_delete = link.callback(PeopleMsg::DeletePerson);
199 |
200 | html! {
201 |
202 | }
203 | };
204 | let person_row = |id: Id, person: &(Person, IsEditting), link: &ComponentLink| {
205 | let name_on_input = link.callback(|(i, n)| PeopleMsg::PersonNameInput(i, n));
206 | let ability_on_input = link.callback(|(i, a)| PeopleMsg::PersonAbilityInput(i, a));
207 |
208 | html! {
209 |
210 | |
211 | |
212 | { edit_delete(id, person.1, &self.link) } |
213 |
214 | }
215 | };
216 |
217 | html! {
218 | <>
219 | {"All the beautiful people"}
220 |
221 |
222 | | {"Person"} | {"Ability"} | {" "} |
223 |
224 |
225 | { for self.people.iter().enumerate().map(|(i, p)| person_row(i, p, &self.link)) }
226 |
227 |
228 | |
229 |
232 |
235 | //button onclick=|_| PeopleMsg::SavePeople, >{"Save all the People"}
236 | |
237 |
238 |
239 | >
240 | }
241 | }
242 | }
243 |
244 | // #[derive(Clone, Eq, PartialEq, Default)]
245 | // struct Select {
246 | // is_selected: bool,
247 | // }
248 |
249 | // impl Component for Select {
250 | // type Message = ();
251 | // type Properties = Self;
252 |
253 | // fn create(props: Self::Properties, _context: &mut Env) -> Self {
254 | // Self {
255 | // is_selected: props.is_selected,
256 | // }
257 | // }
258 |
259 | // fn update(&mut self, _msg: Self::Message, _context: &mut Env) -> ShouldRender {
260 | // true
261 | // }
262 |
263 | // fn change(
264 | // &mut self,
265 | // _props: Self::Properties,
266 | // _context: &mut Env,
267 | // ) -> ShouldRender {
268 | // true
269 | // }
270 | // }
271 |
272 | // impl Renderable for Select {
273 | // fn view(&self) -> Html {
274 | // html! {
275 | //
276 | // }
277 | // }
278 | // }
279 |
280 | /// EditDelete Component for a person row
281 | #[derive(Clone)]
282 | struct EditDelete {
283 | id: Id,
284 | is_editting: IsEditting,
285 | on_edit: Option>,
286 | on_delete: Option>,
287 | link: ComponentLink,
288 | }
289 |
290 | #[derive(Clone, PartialEq, Default, Properties)]
291 | struct EditDeleteProps {
292 | pub id: Id,
293 | pub is_editting: IsEditting,
294 | pub on_edit: Option>,
295 | pub on_delete: Option>,
296 | }
297 |
298 | enum EditDeleteMsg {
299 | Edit,
300 | Delete,
301 | }
302 |
303 | impl Component for EditDelete {
304 | type Message = EditDeleteMsg;
305 | type Properties = EditDeleteProps;
306 |
307 | fn create(props: Self::Properties, link: ComponentLink) -> Self {
308 | Self {
309 | id: props.id,
310 | is_editting: props.is_editting,
311 | on_edit: props.on_edit,
312 | on_delete: props.on_delete,
313 | link,
314 | }
315 | }
316 |
317 | fn update(&mut self, msg: Self::Message) -> ShouldRender {
318 | match msg {
319 | EditDeleteMsg::Edit => {
320 | debug!("editting: {}", self.id);
321 | if !self.is_editting {
322 | self.on_edit.as_ref().map(|c| c.emit(self.id));
323 | }
324 | }
325 | EditDeleteMsg::Delete => {
326 | debug!("deleting: {}", self.id);
327 | self.on_delete.as_ref().map(|c| c.emit(self.id));
328 | }
329 | }
330 |
331 | false
332 | }
333 |
334 | fn change(&mut self, props: Self::Properties) -> ShouldRender {
335 | if self.is_editting != props.is_editting {
336 | self.is_editting = props.is_editting;
337 | return true;
338 | }
339 | false
340 | }
341 |
342 | fn view(&self) -> Html {
343 | let disabled = if self.is_editting { "disabled" } else { "" };
344 |
345 | html! {
346 |
347 |
348 |
349 |
350 | }
351 | }
352 | }
353 |
354 | #[derive(Clone)]
355 | struct PersonName {
356 | id: Id,
357 | name: String,
358 | is_editting: IsEditting,
359 | on_input: Option>,
360 | link: ComponentLink,
361 | }
362 |
363 | #[derive(Clone, PartialEq, Default, Properties)]
364 | struct PersonNameProps {
365 | pub id: Id,
366 | pub name: String,
367 | pub is_editting: IsEditting,
368 | pub on_input: Option>,
369 | }
370 |
371 | enum PersonNameMsg {
372 | Input(String),
373 | }
374 |
375 | impl Component for PersonName {
376 | type Message = PersonNameMsg;
377 | type Properties = PersonNameProps;
378 |
379 | fn create(props: Self::Properties, link: ComponentLink) -> Self {
380 | Self {
381 | id: props.id,
382 | name: props.name.clone(),
383 | is_editting: props.is_editting,
384 | on_input: props.on_input,
385 | link,
386 | }
387 | }
388 |
389 | fn update(&mut self, msg: Self::Message) -> ShouldRender {
390 | match msg {
391 | PersonNameMsg::Input(n) => {
392 | debug!("input: {}, {}", self.id, self.name);
393 | if self.is_editting {
394 | self.on_input.as_ref().map(|c| c.emit((self.id, n)));
395 | }
396 | }
397 | }
398 |
399 | false
400 | }
401 |
402 | fn change(&mut self, props: Self::Properties) -> ShouldRender {
403 | let mut render = false;
404 | if self.is_editting != props.is_editting {
405 | self.is_editting = props.is_editting;
406 | render |= true;
407 | }
408 |
409 | if self.name != props.name {
410 | self.name = props.name;
411 | render |= true;
412 | }
413 | render
414 | }
415 |
416 | fn view(&self) -> Html {
417 | if self.is_editting {
418 | html! {
419 |
420 | }
421 | } else {
422 | html! {
423 | <>{ &self.name }>
424 | }
425 | }
426 | }
427 | }
428 |
429 | #[derive(Clone)]
430 | struct PersonAbility {
431 | id: Id,
432 | ability: Ability,
433 | is_editting: IsEditting,
434 | on_input: Option>,
435 | link: ComponentLink,
436 | }
437 | #[derive(Clone, PartialEq, Default, Properties)]
438 | struct PersonAbilityProps {
439 | pub id: Id,
440 | pub ability: Ability,
441 | pub is_editting: IsEditting,
442 | pub on_input: Option>,
443 | }
444 |
445 | enum PersonAbilityMsg {
446 | Input(HtmlSelectElement),
447 | }
448 |
449 | impl Component for PersonAbility {
450 | type Message = PersonAbilityMsg;
451 | type Properties = PersonAbilityProps;
452 |
453 | fn create(props: Self::Properties, link: ComponentLink) -> Self {
454 | Self {
455 | id: props.id,
456 | ability: props.ability.clone(),
457 | is_editting: props.is_editting,
458 | on_input: props.on_input,
459 | link,
460 | }
461 | }
462 |
463 | fn update(&mut self, msg: Self::Message) -> ShouldRender {
464 | match msg {
465 | PersonAbilityMsg::Input(se) => {
466 | debug!("input: {}, {:?}", self.id, se.selected_index());
467 |
468 | let enum_i32: i32 = se.selected_index();
469 | let ability = Ability::from_i32(enum_i32);
470 |
471 | debug!("input: {}, {}", self.id, ability);
472 | if self.is_editting {
473 | self.on_input.as_ref().map(|c| c.emit((self.id, ability)));
474 | }
475 | }
476 | }
477 |
478 | false
479 | }
480 |
481 | fn change(&mut self, props: Self::Properties) -> ShouldRender {
482 | let mut render = false;
483 | if self.is_editting != props.is_editting {
484 | self.is_editting = props.is_editting;
485 | render |= true;
486 | }
487 |
488 | if self.ability != props.ability {
489 | self.ability = props.ability;
490 | render |= true;
491 | }
492 | render
493 | }
494 |
495 | fn view(&self) -> Html {
496 | if self.is_editting {
497 | let select_ability = |ability: Ability| {
498 | let value = i32::from(ability).to_string();
499 | if self.ability == ability {
500 | html! {
501 |
502 | }
503 | } else {
504 | html! {
505 |
506 | }
507 | }
508 | };
509 |
510 | html! {
511 |
517 | }
518 | } else {
519 | html! {
520 | <>{ self.ability.to_str() }>
521 | }
522 | }
523 | }
524 | }
525 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | [[package]]
4 | name = "anyhow"
5 | version = "1.0.27"
6 | source = "registry+https://github.com/rust-lang/crates.io-index"
7 |
8 | [[package]]
9 | name = "anymap"
10 | version = "0.12.1"
11 | source = "registry+https://github.com/rust-lang/crates.io-index"
12 |
13 | [[package]]
14 | name = "autocfg"
15 | version = "1.0.0"
16 | source = "registry+https://github.com/rust-lang/crates.io-index"
17 |
18 | [[package]]
19 | name = "bincode"
20 | version = "1.2.1"
21 | source = "registry+https://github.com/rust-lang/crates.io-index"
22 | dependencies = [
23 | "byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
24 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
25 | ]
26 |
27 | [[package]]
28 | name = "boolinator"
29 | version = "2.4.0"
30 | source = "registry+https://github.com/rust-lang/crates.io-index"
31 |
32 | [[package]]
33 | name = "bumpalo"
34 | version = "3.2.1"
35 | source = "registry+https://github.com/rust-lang/crates.io-index"
36 |
37 | [[package]]
38 | name = "byteorder"
39 | version = "1.3.4"
40 | source = "registry+https://github.com/rust-lang/crates.io-index"
41 |
42 | [[package]]
43 | name = "bytes"
44 | version = "0.5.4"
45 | source = "registry+https://github.com/rust-lang/crates.io-index"
46 |
47 | [[package]]
48 | name = "cfg-if"
49 | version = "0.1.10"
50 | source = "registry+https://github.com/rust-lang/crates.io-index"
51 |
52 | [[package]]
53 | name = "cfg-match"
54 | version = "0.2.1"
55 | source = "registry+https://github.com/rust-lang/crates.io-index"
56 |
57 | [[package]]
58 | name = "console_error_panic_hook"
59 | version = "0.1.6"
60 | source = "registry+https://github.com/rust-lang/crates.io-index"
61 | dependencies = [
62 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
63 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
64 | ]
65 |
66 | [[package]]
67 | name = "console_log"
68 | version = "0.1.2"
69 | source = "registry+https://github.com/rust-lang/crates.io-index"
70 | dependencies = [
71 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
72 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
73 | ]
74 |
75 | [[package]]
76 | name = "dtoa"
77 | version = "0.4.3"
78 | source = "registry+https://github.com/rust-lang/crates.io-index"
79 |
80 | [[package]]
81 | name = "fnv"
82 | version = "1.0.6"
83 | source = "registry+https://github.com/rust-lang/crates.io-index"
84 |
85 | [[package]]
86 | name = "futures"
87 | version = "0.3.4"
88 | source = "registry+https://github.com/rust-lang/crates.io-index"
89 | dependencies = [
90 | "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
91 | "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
92 | "futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
93 | "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
94 | "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
95 | "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
96 | "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
97 | ]
98 |
99 | [[package]]
100 | name = "futures-channel"
101 | version = "0.3.4"
102 | source = "registry+https://github.com/rust-lang/crates.io-index"
103 | dependencies = [
104 | "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
105 | "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
106 | ]
107 |
108 | [[package]]
109 | name = "futures-core"
110 | version = "0.3.4"
111 | source = "registry+https://github.com/rust-lang/crates.io-index"
112 |
113 | [[package]]
114 | name = "futures-executor"
115 | version = "0.3.4"
116 | source = "registry+https://github.com/rust-lang/crates.io-index"
117 | dependencies = [
118 | "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
119 | "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
120 | "futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
121 | ]
122 |
123 | [[package]]
124 | name = "futures-io"
125 | version = "0.3.4"
126 | source = "registry+https://github.com/rust-lang/crates.io-index"
127 |
128 | [[package]]
129 | name = "futures-macro"
130 | version = "0.3.4"
131 | source = "registry+https://github.com/rust-lang/crates.io-index"
132 | dependencies = [
133 | "proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)",
134 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
135 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
136 | "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
137 | ]
138 |
139 | [[package]]
140 | name = "futures-sink"
141 | version = "0.3.4"
142 | source = "registry+https://github.com/rust-lang/crates.io-index"
143 |
144 | [[package]]
145 | name = "futures-task"
146 | version = "0.3.4"
147 | source = "registry+https://github.com/rust-lang/crates.io-index"
148 |
149 | [[package]]
150 | name = "futures-util"
151 | version = "0.3.4"
152 | source = "registry+https://github.com/rust-lang/crates.io-index"
153 | dependencies = [
154 | "futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
155 | "futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
156 | "futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
157 | "futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
158 | "futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
159 | "futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
160 | "memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
161 | "pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)",
162 | "proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)",
163 | "proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
164 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
165 | ]
166 |
167 | [[package]]
168 | name = "gloo"
169 | version = "0.2.1"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | dependencies = [
172 | "gloo-console-timer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
173 | "gloo-events 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
174 | "gloo-file 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
175 | "gloo-timers 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
176 | ]
177 |
178 | [[package]]
179 | name = "gloo-console-timer"
180 | version = "0.1.0"
181 | source = "registry+https://github.com/rust-lang/crates.io-index"
182 | dependencies = [
183 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
184 | ]
185 |
186 | [[package]]
187 | name = "gloo-events"
188 | version = "0.1.1"
189 | source = "registry+https://github.com/rust-lang/crates.io-index"
190 | dependencies = [
191 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
192 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
193 | ]
194 |
195 | [[package]]
196 | name = "gloo-file"
197 | version = "0.1.0"
198 | source = "registry+https://github.com/rust-lang/crates.io-index"
199 | dependencies = [
200 | "gloo-events 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
201 | "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
202 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
203 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
204 | ]
205 |
206 | [[package]]
207 | name = "gloo-timers"
208 | version = "0.2.1"
209 | source = "registry+https://github.com/rust-lang/crates.io-index"
210 | dependencies = [
211 | "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
212 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
213 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
214 | ]
215 |
216 | [[package]]
217 | name = "http"
218 | version = "0.2.0"
219 | source = "registry+https://github.com/rust-lang/crates.io-index"
220 | dependencies = [
221 | "bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)",
222 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
223 | "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
224 | ]
225 |
226 | [[package]]
227 | name = "indexmap"
228 | version = "1.3.2"
229 | source = "registry+https://github.com/rust-lang/crates.io-index"
230 | dependencies = [
231 | "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
232 | ]
233 |
234 | [[package]]
235 | name = "itoa"
236 | version = "0.4.2"
237 | source = "registry+https://github.com/rust-lang/crates.io-index"
238 |
239 | [[package]]
240 | name = "js-sys"
241 | version = "0.3.36"
242 | source = "registry+https://github.com/rust-lang/crates.io-index"
243 | dependencies = [
244 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
245 | ]
246 |
247 | [[package]]
248 | name = "kp-chart"
249 | version = "0.2.0"
250 | dependencies = [
251 | "console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
252 | "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
253 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
254 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
255 | "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
256 | "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
257 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
258 | "wasm-bindgen-futures 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
259 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
260 | "yew 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
261 | ]
262 |
263 | [[package]]
264 | name = "lazy_static"
265 | version = "1.4.0"
266 | source = "registry+https://github.com/rust-lang/crates.io-index"
267 |
268 | [[package]]
269 | name = "log"
270 | version = "0.4.8"
271 | source = "registry+https://github.com/rust-lang/crates.io-index"
272 | dependencies = [
273 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
274 | ]
275 |
276 | [[package]]
277 | name = "memchr"
278 | version = "2.3.3"
279 | source = "registry+https://github.com/rust-lang/crates.io-index"
280 |
281 | [[package]]
282 | name = "pin-utils"
283 | version = "0.1.0-alpha.4"
284 | source = "registry+https://github.com/rust-lang/crates.io-index"
285 |
286 | [[package]]
287 | name = "proc-macro-hack"
288 | version = "0.5.14"
289 | source = "registry+https://github.com/rust-lang/crates.io-index"
290 |
291 | [[package]]
292 | name = "proc-macro-nested"
293 | version = "0.1.4"
294 | source = "registry+https://github.com/rust-lang/crates.io-index"
295 |
296 | [[package]]
297 | name = "proc-macro2"
298 | version = "0.4.9"
299 | source = "registry+https://github.com/rust-lang/crates.io-index"
300 | dependencies = [
301 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
302 | ]
303 |
304 | [[package]]
305 | name = "proc-macro2"
306 | version = "1.0.9"
307 | source = "registry+https://github.com/rust-lang/crates.io-index"
308 | dependencies = [
309 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
310 | ]
311 |
312 | [[package]]
313 | name = "quote"
314 | version = "0.6.4"
315 | source = "registry+https://github.com/rust-lang/crates.io-index"
316 | dependencies = [
317 | "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
318 | ]
319 |
320 | [[package]]
321 | name = "quote"
322 | version = "1.0.3"
323 | source = "registry+https://github.com/rust-lang/crates.io-index"
324 | dependencies = [
325 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
326 | ]
327 |
328 | [[package]]
329 | name = "ryu"
330 | version = "1.0.3"
331 | source = "registry+https://github.com/rust-lang/crates.io-index"
332 |
333 | [[package]]
334 | name = "serde"
335 | version = "1.0.70"
336 | source = "registry+https://github.com/rust-lang/crates.io-index"
337 | dependencies = [
338 | "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
339 | ]
340 |
341 | [[package]]
342 | name = "serde_derive"
343 | version = "1.0.70"
344 | source = "registry+https://github.com/rust-lang/crates.io-index"
345 | dependencies = [
346 | "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
347 | "quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
348 | "syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)",
349 | ]
350 |
351 | [[package]]
352 | name = "serde_json"
353 | version = "1.0.24"
354 | source = "registry+https://github.com/rust-lang/crates.io-index"
355 | dependencies = [
356 | "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
357 | "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
358 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
359 | ]
360 |
361 | [[package]]
362 | name = "slab"
363 | version = "0.4.2"
364 | source = "registry+https://github.com/rust-lang/crates.io-index"
365 |
366 | [[package]]
367 | name = "syn"
368 | version = "0.14.5"
369 | source = "registry+https://github.com/rust-lang/crates.io-index"
370 | dependencies = [
371 | "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
372 | "quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
373 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
374 | ]
375 |
376 | [[package]]
377 | name = "syn"
378 | version = "1.0.17"
379 | source = "registry+https://github.com/rust-lang/crates.io-index"
380 | dependencies = [
381 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
382 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
383 | "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
384 | ]
385 |
386 | [[package]]
387 | name = "thiserror"
388 | version = "1.0.13"
389 | source = "registry+https://github.com/rust-lang/crates.io-index"
390 | dependencies = [
391 | "thiserror-impl 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
392 | ]
393 |
394 | [[package]]
395 | name = "thiserror-impl"
396 | version = "1.0.13"
397 | source = "registry+https://github.com/rust-lang/crates.io-index"
398 | dependencies = [
399 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
400 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
401 | "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
402 | ]
403 |
404 | [[package]]
405 | name = "unicode-xid"
406 | version = "0.1.0"
407 | source = "registry+https://github.com/rust-lang/crates.io-index"
408 |
409 | [[package]]
410 | name = "unicode-xid"
411 | version = "0.2.0"
412 | source = "registry+https://github.com/rust-lang/crates.io-index"
413 |
414 | [[package]]
415 | name = "wasm-bindgen"
416 | version = "0.2.59"
417 | source = "registry+https://github.com/rust-lang/crates.io-index"
418 | dependencies = [
419 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
420 | "wasm-bindgen-macro 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
421 | ]
422 |
423 | [[package]]
424 | name = "wasm-bindgen-backend"
425 | version = "0.2.59"
426 | source = "registry+https://github.com/rust-lang/crates.io-index"
427 | dependencies = [
428 | "bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
429 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
430 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
431 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
432 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
433 | "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
434 | "wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
435 | ]
436 |
437 | [[package]]
438 | name = "wasm-bindgen-futures"
439 | version = "0.4.9"
440 | source = "registry+https://github.com/rust-lang/crates.io-index"
441 | dependencies = [
442 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
443 | "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
444 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
445 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
446 | ]
447 |
448 | [[package]]
449 | name = "wasm-bindgen-macro"
450 | version = "0.2.59"
451 | source = "registry+https://github.com/rust-lang/crates.io-index"
452 | dependencies = [
453 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
454 | "wasm-bindgen-macro-support 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
455 | ]
456 |
457 | [[package]]
458 | name = "wasm-bindgen-macro-support"
459 | version = "0.2.59"
460 | source = "registry+https://github.com/rust-lang/crates.io-index"
461 | dependencies = [
462 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
463 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
464 | "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
465 | "wasm-bindgen-backend 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
466 | "wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
467 | ]
468 |
469 | [[package]]
470 | name = "wasm-bindgen-shared"
471 | version = "0.2.59"
472 | source = "registry+https://github.com/rust-lang/crates.io-index"
473 |
474 | [[package]]
475 | name = "web-sys"
476 | version = "0.3.36"
477 | source = "registry+https://github.com/rust-lang/crates.io-index"
478 | dependencies = [
479 | "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
480 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
481 | ]
482 |
483 | [[package]]
484 | name = "yew"
485 | version = "0.13.2"
486 | source = "registry+https://github.com/rust-lang/crates.io-index"
487 | dependencies = [
488 | "anyhow 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
489 | "anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
490 | "bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
491 | "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
492 | "cfg-match 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
493 | "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
494 | "futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
495 | "gloo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
496 | "http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
497 | "indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
498 | "js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
499 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
500 | "proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)",
501 | "proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
502 | "ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
503 | "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
504 | "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
505 | "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
506 | "thiserror 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
507 | "wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
508 | "wasm-bindgen-futures 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
509 | "web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)",
510 | "yew-macro 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
511 | ]
512 |
513 | [[package]]
514 | name = "yew-macro"
515 | version = "0.13.0"
516 | source = "registry+https://github.com/rust-lang/crates.io-index"
517 | dependencies = [
518 | "boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
519 | "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
520 | "proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)",
521 | "proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
522 | "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
523 | "syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
524 | ]
525 |
526 | [metadata]
527 | "checksum anyhow 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "013a6e0a2cbe3d20f9c60b65458f7a7f7a5e636c5d0f45a5a6aee5d4b1f01785"
528 | "checksum anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
529 | "checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
530 | "checksum bincode 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf"
531 | "checksum boolinator 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9"
532 | "checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
533 | "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
534 | "checksum bytes 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "130aac562c0dd69c56b3b1cc8ffd2e17be31d0b6c25b61c96b76231aa23e39e1"
535 | "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
536 | "checksum cfg-match 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8100e46ff92eb85bf6dc2930c73f2a4f7176393c84a9446b3d501e1b354e7b34"
537 | "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211"
538 | "checksum console_log 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1e7871d2947441b0fdd8e2bd1ce2a2f75304f896582c0d572162d48290683c48"
539 | "checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
540 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
541 | "checksum futures 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780"
542 | "checksum futures-channel 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8"
543 | "checksum futures-core 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a"
544 | "checksum futures-executor 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba"
545 | "checksum futures-io 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6"
546 | "checksum futures-macro 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7"
547 | "checksum futures-sink 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6"
548 | "checksum futures-task 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27"
549 | "checksum futures-util 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5"
550 | "checksum gloo 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68ce6f2dfa9f57f15b848efa2aade5e1850dc72986b87a2b0752d44ca08f4967"
551 | "checksum gloo-console-timer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b48675544b29ac03402c6dffc31a912f716e38d19f7e74b78b7e900ec3c941ea"
552 | "checksum gloo-events 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "088514ec8ef284891c762c88a66b639b3a730134714692ee31829765c5bc814f"
553 | "checksum gloo-file 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f9fecfe46b5dc3cc46f58e98ba580cc714f2c93860796d002eb3527a465ef49"
554 | "checksum gloo-timers 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f"
555 | "checksum http 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b708cc7f06493459026f53b9a61a7a121a5d1ec6238dee58ea4941132b30156b"
556 | "checksum indexmap 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "076f042c5b7b98f31d205f1249267e12a6518c1481e9dae9764af19b707d2292"
557 | "checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
558 | "checksum js-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1cb931d43e71f560c81badb0191596562bafad2be06a3f9025b845c847c60df5"
559 | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
560 | "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
561 | "checksum memchr 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
562 | "checksum pin-utils 0.1.0-alpha.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5894c618ce612a3fa23881b152b608bafb8c56cfc22f434a3ba3120b40f7b587"
563 | "checksum proc-macro-hack 0.5.14 (registry+https://github.com/rust-lang/crates.io-index)" = "fcfdefadc3d57ca21cf17990a28ef4c0f7c61383a28cb7604cf4a18e6ede1420"
564 | "checksum proc-macro-nested 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
565 | "checksum proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "cccdc7557a98fe98453030f077df7f3a042052fae465bb61d2c2c41435cfd9b6"
566 | "checksum proc-macro2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c09721c6781493a2a492a96b5a5bf19b65917fe6728884e7c44dd0c60ca3435"
567 | "checksum quote 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b71f9f575d55555aa9c06188be9d4e2bfc83ed02537948ac0d520c24d0419f1a"
568 | "checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
569 | "checksum ryu 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535622e6be132bccd223f4bb2b8ac8d53cda3c7a6394944d3b2b33fb974f9d76"
570 | "checksum serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "0c3adf19c07af6d186d91dae8927b83b0553d07ca56cbf7f2f32560455c91920"
571 | "checksum serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)" = "3525a779832b08693031b8ecfb0de81cd71cfd3812088fafe9a7496789572124"
572 | "checksum serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c6908c7b925cd6c590358a4034de93dbddb20c45e1d021931459fd419bf0e2"
573 | "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
574 | "checksum syn 0.14.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bad7abdf6633f07c7046b90484f1d9dc055eca39f8c991177b1046ce61dba9a"
575 | "checksum syn 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "0df0eb663f387145cab623dea85b09c2c5b4b0aef44e945d928e682fce71bb03"
576 | "checksum thiserror 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e3711fd1c4e75b3eff12ba5c40dba762b6b65c5476e8174c1a664772060c49bf"
577 | "checksum thiserror-impl 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2b85ba4c9aa32dd3343bd80eb8d22e9b54b7688c17ea3907f236885353b233"
578 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
579 | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
580 | "checksum wasm-bindgen 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "3557c397ab5a8e347d434782bcd31fc1483d927a6826804cec05cc792ee2519d"
581 | "checksum wasm-bindgen-backend 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "e0da9c9a19850d3af6df1cb9574970b566d617ecfaf36eb0b706b6f3ef9bd2f8"
582 | "checksum wasm-bindgen-futures 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "457414a91863c0ec00090dba537f88ab955d93ca6555862c29b6d860990b8a8a"
583 | "checksum wasm-bindgen-macro 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "0f6fde1d36e75a714b5fe0cffbb78978f222ea6baebb726af13c78869fdb4205"
584 | "checksum wasm-bindgen-macro-support 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "25bda4168030a6412ea8a047e27238cadf56f0e53516e1e83fec0a8b7c786f6d"
585 | "checksum wasm-bindgen-shared 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)" = "fc9f36ad51f25b0219a3d4d13b90eb44cd075dff8b6280cca015775d7acaddd8"
586 | "checksum web-sys 0.3.36 (registry+https://github.com/rust-lang/crates.io-index)" = "721c6263e2c66fd44501cc5efbfa2b7dfa775d13e4ea38c46299646ed1f9c70a"
587 | "checksum yew 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "35e21ea7b89b427fe0db9922cad08f51e5d9464434b3843414b253008b7cc0d1"
588 | "checksum yew-macro 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7799777bca19f96d9eb0c865e53c489565ffb890b9d48b58c9c50ef5c8df3532"
589 |
--------------------------------------------------------------------------------
/docs/kp-chart.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | if( typeof Rust === "undefined" ) {
4 | var Rust = {};
5 | }
6 |
7 | (function( root, factory ) {
8 | if( typeof define === "function" && define.amd ) {
9 | define( [], factory );
10 | } else if( typeof module === "object" && module.exports ) {
11 | module.exports = factory();
12 | } else {
13 | Rust.kp_chart = factory();
14 | }
15 | }( this, function() {
16 | return (function( module_factory ) {
17 | var instance = module_factory();
18 |
19 | if( typeof window === "undefined" && typeof process === "object" ) {
20 | var fs = require( "fs" );
21 | var path = require( "path" );
22 | var wasm_path = path.join( __dirname, "kp-chart.wasm" );
23 | var buffer = fs.readFileSync( wasm_path );
24 | var mod = new WebAssembly.Module( buffer );
25 | var wasm_instance = new WebAssembly.Instance( mod, instance.imports );
26 | return instance.initialize( wasm_instance );
27 | } else {
28 | return fetch( "kp-chart.wasm", {credentials: "same-origin"} )
29 | .then( function( response ) { return response.arrayBuffer(); } )
30 | .then( function( bytes ) { return WebAssembly.compile( bytes ); } )
31 | .then( function( mod ) { return WebAssembly.instantiate( mod, instance.imports ) } )
32 | .then( function( wasm_instance ) {
33 | var exports = instance.initialize( wasm_instance );
34 | console.log( "Finished loading Rust wasm module 'kp_chart'" );
35 | return exports;
36 | })
37 | .catch( function( error ) {
38 | console.log( "Error loading Rust wasm module 'kp_chart':", error );
39 | throw error;
40 | });
41 | }
42 | }( function() {
43 | var Module = {};
44 |
45 | Module.STDWEB_PRIVATE = {};
46 |
47 | // This is based on code from Emscripten's preamble.js.
48 | Module.STDWEB_PRIVATE.to_utf8 = function to_utf8( str, addr ) {
49 | for( var i = 0; i < str.length; ++i ) {
50 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
51 | // See http://unicode.org/faq/utf_bom.html#utf16-3
52 | // For UTF8 byte structure, see http://en.wikipedia.org/wiki/UTF-8#Description and https://www.ietf.org/rfc/rfc2279.txt and https://tools.ietf.org/html/rfc3629
53 | var u = str.charCodeAt( i ); // possibly a lead surrogate
54 | if( u >= 0xD800 && u <= 0xDFFF ) {
55 | u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt( ++i ) & 0x3FF);
56 | }
57 |
58 | if( u <= 0x7F ) {
59 | HEAPU8[ addr++ ] = u;
60 | } else if( u <= 0x7FF ) {
61 | HEAPU8[ addr++ ] = 0xC0 | (u >> 6);
62 | HEAPU8[ addr++ ] = 0x80 | (u & 63);
63 | } else if( u <= 0xFFFF ) {
64 | HEAPU8[ addr++ ] = 0xE0 | (u >> 12);
65 | HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63);
66 | HEAPU8[ addr++ ] = 0x80 | (u & 63);
67 | } else if( u <= 0x1FFFFF ) {
68 | HEAPU8[ addr++ ] = 0xF0 | (u >> 18);
69 | HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63);
70 | HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63);
71 | HEAPU8[ addr++ ] = 0x80 | (u & 63);
72 | } else if( u <= 0x3FFFFFF ) {
73 | HEAPU8[ addr++ ] = 0xF8 | (u >> 24);
74 | HEAPU8[ addr++ ] = 0x80 | ((u >> 18) & 63);
75 | HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63);
76 | HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63);
77 | HEAPU8[ addr++ ] = 0x80 | (u & 63);
78 | } else {
79 | HEAPU8[ addr++ ] = 0xFC | (u >> 30);
80 | HEAPU8[ addr++ ] = 0x80 | ((u >> 24) & 63);
81 | HEAPU8[ addr++ ] = 0x80 | ((u >> 18) & 63);
82 | HEAPU8[ addr++ ] = 0x80 | ((u >> 12) & 63);
83 | HEAPU8[ addr++ ] = 0x80 | ((u >> 6) & 63);
84 | HEAPU8[ addr++ ] = 0x80 | (u & 63);
85 | }
86 | }
87 | };
88 |
89 | Module.STDWEB_PRIVATE.noop = function() {};
90 | Module.STDWEB_PRIVATE.to_js = function to_js( address ) {
91 | var kind = HEAPU8[ address + 12 ];
92 | if( kind === 0 ) {
93 | return undefined;
94 | } else if( kind === 1 ) {
95 | return null;
96 | } else if( kind === 2 ) {
97 | return HEAP32[ address / 4 ];
98 | } else if( kind === 3 ) {
99 | return HEAPF64[ address / 8 ];
100 | } else if( kind === 4 ) {
101 | var pointer = HEAPU32[ address / 4 ];
102 | var length = HEAPU32[ (address + 4) / 4 ];
103 | return Module.STDWEB_PRIVATE.to_js_string( pointer, length );
104 | } else if( kind === 5 ) {
105 | return false;
106 | } else if( kind === 6 ) {
107 | return true;
108 | } else if( kind === 7 ) {
109 | var pointer = HEAPU32[ address / 4 ];
110 | var length = HEAPU32[ (address + 4) / 4 ];
111 | var output = [];
112 | for( var i = 0; i < length; ++i ) {
113 | output.push( Module.STDWEB_PRIVATE.to_js( pointer + i * 16 ) );
114 | }
115 | return output;
116 | } else if( kind === 8 ) {
117 | var value_array_pointer = HEAPU32[ address / 4 ];
118 | var length = HEAPU32[ (address + 4) / 4 ];
119 | var key_array_pointer = HEAPU32[ (address + 8) / 4 ];
120 | var output = {};
121 | for( var i = 0; i < length; ++i ) {
122 | var key_pointer = HEAPU32[ (key_array_pointer + i * 8) / 4 ];
123 | var key_length = HEAPU32[ (key_array_pointer + 4 + i * 8) / 4 ];
124 | var key = Module.STDWEB_PRIVATE.to_js_string( key_pointer, key_length );
125 | var value = Module.STDWEB_PRIVATE.to_js( value_array_pointer + i * 16 );
126 | output[ key ] = value;
127 | }
128 | return output;
129 | } else if( kind === 9 ) {
130 | return Module.STDWEB_PRIVATE.acquire_js_reference( HEAP32[ address / 4 ] );
131 | } else if( kind === 10 ) {
132 | var adapter_pointer = HEAPU32[ address / 4 ];
133 | var pointer = HEAPU32[ (address + 4) / 4 ];
134 | var deallocator_pointer = HEAPU32[ (address + 8) / 4 ];
135 | var output = function() {
136 | if( pointer === 0 ) {
137 | throw new ReferenceError( "Already dropped Rust function called!" );
138 | }
139 |
140 | var args = Module.STDWEB_PRIVATE.alloc( 16 );
141 | Module.STDWEB_PRIVATE.serialize_array( args, arguments );
142 | Module.STDWEB_PRIVATE.dyncall( "vii", adapter_pointer, [pointer, args] );
143 | var result = Module.STDWEB_PRIVATE.tmp;
144 | Module.STDWEB_PRIVATE.tmp = null;
145 |
146 | return result;
147 | };
148 |
149 | output.drop = function() {
150 | output.drop = Module.STDWEB_PRIVATE.noop;
151 | var function_pointer = pointer;
152 | pointer = 0;
153 |
154 | Module.STDWEB_PRIVATE.dyncall( "vi", deallocator_pointer, [function_pointer] );
155 | };
156 |
157 | return output;
158 | } else if( kind === 13 ) {
159 | var adapter_pointer = HEAPU32[ address / 4 ];
160 | var pointer = HEAPU32[ (address + 4) / 4 ];
161 | var deallocator_pointer = HEAPU32[ (address + 8) / 4 ];
162 | var output = function() {
163 | if( pointer === 0 ) {
164 | throw new ReferenceError( "Already called or dropped FnOnce function called!" );
165 | }
166 |
167 | output.drop = Module.STDWEB_PRIVATE.noop;
168 | var function_pointer = pointer;
169 | pointer = 0;
170 |
171 | var args = Module.STDWEB_PRIVATE.alloc( 16 );
172 | Module.STDWEB_PRIVATE.serialize_array( args, arguments );
173 | Module.STDWEB_PRIVATE.dyncall( "vii", adapter_pointer, [function_pointer, args] );
174 | var result = Module.STDWEB_PRIVATE.tmp;
175 | Module.STDWEB_PRIVATE.tmp = null;
176 |
177 | return result;
178 | };
179 |
180 | output.drop = function() {
181 | output.drop = Module.STDWEB_PRIVATE.noop;
182 | var function_pointer = pointer;
183 | pointer = 0;
184 |
185 | Module.STDWEB_PRIVATE.dyncall( "vi", deallocator_pointer, [function_pointer] );
186 | };
187 |
188 | return output;
189 | } else if( kind === 14 ) {
190 | var pointer = HEAPU32[ address / 4 ];
191 | var length = HEAPU32[ (address + 4) / 4 ];
192 | var array_kind = HEAPU32[ (address + 8) / 4 ];
193 | var pointer_end = pointer + length;
194 |
195 | switch( array_kind ) {
196 | case 0:
197 | return HEAPU8.subarray( pointer, pointer_end );
198 | case 1:
199 | return HEAP8.subarray( pointer, pointer_end );
200 | case 2:
201 | return HEAPU16.subarray( pointer, pointer_end );
202 | case 3:
203 | return HEAP16.subarray( pointer, pointer_end );
204 | case 4:
205 | return HEAPU32.subarray( pointer, pointer_end );
206 | case 5:
207 | return HEAP32.subarray( pointer, pointer_end );
208 | case 6:
209 | return HEAPF32.subarray( pointer, pointer_end );
210 | case 7:
211 | return HEAPF64.subarray( pointer, pointer_end );
212 | }
213 | } else if( kind === 15 ) {
214 | return Module.STDWEB_PRIVATE.get_raw_value( HEAPU32[ address / 4 ] );
215 | }
216 | };
217 |
218 | Module.STDWEB_PRIVATE.serialize_object = function serialize_object( address, value ) {
219 | var keys = Object.keys( value );
220 | var length = keys.length;
221 | var key_array_pointer = Module.STDWEB_PRIVATE.alloc( length * 8 );
222 | var value_array_pointer = Module.STDWEB_PRIVATE.alloc( length * 16 );
223 | HEAPU8[ address + 12 ] = 8;
224 | HEAPU32[ address / 4 ] = value_array_pointer;
225 | HEAPU32[ (address + 4) / 4 ] = length;
226 | HEAPU32[ (address + 8) / 4 ] = key_array_pointer;
227 | for( var i = 0; i < length; ++i ) {
228 | var key = keys[ i ];
229 | var key_length = Module.STDWEB_PRIVATE.utf8_len( key );
230 | var key_pointer = Module.STDWEB_PRIVATE.alloc( key_length );
231 | Module.STDWEB_PRIVATE.to_utf8( key, key_pointer );
232 |
233 | var key_address = key_array_pointer + i * 8;
234 | HEAPU32[ key_address / 4 ] = key_pointer;
235 | HEAPU32[ (key_address + 4) / 4 ] = key_length;
236 |
237 | Module.STDWEB_PRIVATE.from_js( value_array_pointer + i * 16, value[ key ] );
238 | }
239 | };
240 |
241 | Module.STDWEB_PRIVATE.serialize_array = function serialize_array( address, value ) {
242 | var length = value.length;
243 | var pointer = Module.STDWEB_PRIVATE.alloc( length * 16 );
244 | HEAPU8[ address + 12 ] = 7;
245 | HEAPU32[ address / 4 ] = pointer;
246 | HEAPU32[ (address + 4) / 4 ] = length;
247 | for( var i = 0; i < length; ++i ) {
248 | Module.STDWEB_PRIVATE.from_js( pointer + i * 16, value[ i ] );
249 | }
250 | };
251 |
252 | Module.STDWEB_PRIVATE.from_js = function from_js( address, value ) {
253 | var kind = Object.prototype.toString.call( value );
254 | if( kind === "[object String]" ) {
255 | var length = Module.STDWEB_PRIVATE.utf8_len( value );
256 | var pointer = 0;
257 | if( length > 0 ) {
258 | pointer = Module.STDWEB_PRIVATE.alloc( length );
259 | Module.STDWEB_PRIVATE.to_utf8( value, pointer );
260 | }
261 | HEAPU8[ address + 12 ] = 4;
262 | HEAPU32[ address / 4 ] = pointer;
263 | HEAPU32[ (address + 4) / 4 ] = length;
264 | } else if( kind === "[object Number]" ) {
265 | if( value === (value|0) ) {
266 | HEAPU8[ address + 12 ] = 2;
267 | HEAP32[ address / 4 ] = value;
268 | } else {
269 | HEAPU8[ address + 12 ] = 3;
270 | HEAPF64[ address / 8 ] = value;
271 | }
272 | } else if( value === null ) {
273 | HEAPU8[ address + 12 ] = 1;
274 | } else if( value === undefined ) {
275 | HEAPU8[ address + 12 ] = 0;
276 | } else if( value === false ) {
277 | HEAPU8[ address + 12 ] = 5;
278 | } else if( value === true ) {
279 | HEAPU8[ address + 12 ] = 6;
280 | } else if( kind === "[object Symbol]" ) {
281 | var id = Module.STDWEB_PRIVATE.register_raw_value( value );
282 | HEAPU8[ address + 12 ] = 15;
283 | HEAP32[ address / 4 ] = id;
284 | } else {
285 | var refid = Module.STDWEB_PRIVATE.acquire_rust_reference( value );
286 | HEAPU8[ address + 12 ] = 9;
287 | HEAP32[ address / 4 ] = refid;
288 | }
289 | };
290 |
291 | // This is ported from Rust's stdlib; it's faster than
292 | // the string conversion from Emscripten.
293 | Module.STDWEB_PRIVATE.to_js_string = function to_js_string( index, length ) {
294 | index = index|0;
295 | length = length|0;
296 | var end = (index|0) + (length|0);
297 | var output = "";
298 | while( index < end ) {
299 | var x = HEAPU8[ index++ ];
300 | if( x < 128 ) {
301 | output += String.fromCharCode( x );
302 | continue;
303 | }
304 | var init = (x & (0x7F >> 2));
305 | var y = 0;
306 | if( index < end ) {
307 | y = HEAPU8[ index++ ];
308 | }
309 | var ch = (init << 6) | (y & 63);
310 | if( x >= 0xE0 ) {
311 | var z = 0;
312 | if( index < end ) {
313 | z = HEAPU8[ index++ ];
314 | }
315 | var y_z = ((y & 63) << 6) | (z & 63);
316 | ch = init << 12 | y_z;
317 | if( x >= 0xF0 ) {
318 | var w = 0;
319 | if( index < end ) {
320 | w = HEAPU8[ index++ ];
321 | }
322 | ch = (init & 7) << 18 | ((y_z << 6) | (w & 63));
323 |
324 | output += String.fromCharCode( 0xD7C0 + (ch >> 10) );
325 | ch = 0xDC00 + (ch & 0x3FF);
326 | }
327 | }
328 | output += String.fromCharCode( ch );
329 | continue;
330 | }
331 | return output;
332 | };
333 |
334 | Module.STDWEB_PRIVATE.id_to_ref_map = {};
335 | Module.STDWEB_PRIVATE.id_to_refcount_map = {};
336 | Module.STDWEB_PRIVATE.ref_to_id_map = new WeakMap();
337 | // Not all types can be stored in a WeakMap
338 | Module.STDWEB_PRIVATE.ref_to_id_map_fallback = new Map();
339 | Module.STDWEB_PRIVATE.last_refid = 1;
340 |
341 | Module.STDWEB_PRIVATE.id_to_raw_value_map = {};
342 | Module.STDWEB_PRIVATE.last_raw_value_id = 1;
343 |
344 | Module.STDWEB_PRIVATE.acquire_rust_reference = function( reference ) {
345 | if( reference === undefined || reference === null ) {
346 | return 0;
347 | }
348 |
349 | var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map;
350 | var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map;
351 | var ref_to_id_map = Module.STDWEB_PRIVATE.ref_to_id_map;
352 | var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback;
353 |
354 | var refid = ref_to_id_map.get( reference );
355 | if( refid === undefined ) {
356 | refid = ref_to_id_map_fallback.get( reference );
357 | }
358 | if( refid === undefined ) {
359 | refid = Module.STDWEB_PRIVATE.last_refid++;
360 | try {
361 | ref_to_id_map.set( reference, refid );
362 | } catch (e) {
363 | ref_to_id_map_fallback.set( reference, refid );
364 | }
365 | }
366 |
367 | if( refid in id_to_ref_map ) {
368 | id_to_refcount_map[ refid ]++;
369 | } else {
370 | id_to_ref_map[ refid ] = reference;
371 | id_to_refcount_map[ refid ] = 1;
372 | }
373 |
374 | return refid;
375 | };
376 |
377 | Module.STDWEB_PRIVATE.acquire_js_reference = function( refid ) {
378 | return Module.STDWEB_PRIVATE.id_to_ref_map[ refid ];
379 | };
380 |
381 | Module.STDWEB_PRIVATE.increment_refcount = function( refid ) {
382 | Module.STDWEB_PRIVATE.id_to_refcount_map[ refid ]++;
383 | };
384 |
385 | Module.STDWEB_PRIVATE.decrement_refcount = function( refid ) {
386 | var id_to_refcount_map = Module.STDWEB_PRIVATE.id_to_refcount_map;
387 | if( 0 == --id_to_refcount_map[ refid ] ) {
388 | var id_to_ref_map = Module.STDWEB_PRIVATE.id_to_ref_map;
389 | var ref_to_id_map_fallback = Module.STDWEB_PRIVATE.ref_to_id_map_fallback;
390 | var reference = id_to_ref_map[ refid ];
391 | delete id_to_ref_map[ refid ];
392 | delete id_to_refcount_map[ refid ];
393 | ref_to_id_map_fallback.delete(reference);
394 | }
395 | };
396 |
397 | Module.STDWEB_PRIVATE.register_raw_value = function( value ) {
398 | var id = Module.STDWEB_PRIVATE.last_raw_value_id++;
399 | Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ] = value;
400 | return id;
401 | };
402 |
403 | Module.STDWEB_PRIVATE.unregister_raw_value = function( id ) {
404 | delete Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ];
405 | };
406 |
407 | Module.STDWEB_PRIVATE.get_raw_value = function( id ) {
408 | return Module.STDWEB_PRIVATE.id_to_raw_value_map[ id ];
409 | };
410 |
411 | Module.STDWEB_PRIVATE.alloc = function alloc( size ) {
412 | return Module.web_malloc( size );
413 | };
414 |
415 | Module.STDWEB_PRIVATE.dyncall = function( signature, ptr, args ) {
416 | return Module.web_table.get( ptr ).apply( null, args );
417 | };
418 |
419 | // This is based on code from Emscripten's preamble.js.
420 | Module.STDWEB_PRIVATE.utf8_len = function utf8_len( str ) {
421 | var len = 0;
422 | for( var i = 0; i < str.length; ++i ) {
423 | // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! So decode UTF16->UTF32->UTF8.
424 | // See http://unicode.org/faq/utf_bom.html#utf16-3
425 | var u = str.charCodeAt( i ); // possibly a lead surrogate
426 | if( u >= 0xD800 && u <= 0xDFFF ) {
427 | u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt( ++i ) & 0x3FF);
428 | }
429 |
430 | if( u <= 0x7F ) {
431 | ++len;
432 | } else if( u <= 0x7FF ) {
433 | len += 2;
434 | } else if( u <= 0xFFFF ) {
435 | len += 3;
436 | } else if( u <= 0x1FFFFF ) {
437 | len += 4;
438 | } else if( u <= 0x3FFFFFF ) {
439 | len += 5;
440 | } else {
441 | len += 6;
442 | }
443 | }
444 | return len;
445 | };
446 |
447 | Module.STDWEB_PRIVATE.prepare_any_arg = function( value ) {
448 | var arg = Module.STDWEB_PRIVATE.alloc( 16 );
449 | Module.STDWEB_PRIVATE.from_js( arg, value );
450 | return arg;
451 | };
452 |
453 | Module.STDWEB_PRIVATE.acquire_tmp = function( dummy ) {
454 | var value = Module.STDWEB_PRIVATE.tmp;
455 | Module.STDWEB_PRIVATE.tmp = null;
456 | return value;
457 | };
458 |
459 |
460 |
461 | var HEAP8 = null;
462 | var HEAP16 = null;
463 | var HEAP32 = null;
464 | var HEAPU8 = null;
465 | var HEAPU16 = null;
466 | var HEAPU32 = null;
467 | var HEAPF32 = null;
468 | var HEAPF64 = null;
469 |
470 | Object.defineProperty( Module, 'exports', { value: {} } );
471 |
472 | function __web_on_grow() {
473 | var buffer = Module.instance.exports.memory.buffer;
474 | HEAP8 = new Int8Array( buffer );
475 | HEAP16 = new Int16Array( buffer );
476 | HEAP32 = new Int32Array( buffer );
477 | HEAPU8 = new Uint8Array( buffer );
478 | HEAPU16 = new Uint16Array( buffer );
479 | HEAPU32 = new Uint32Array( buffer );
480 | HEAPF32 = new Float32Array( buffer );
481 | HEAPF64 = new Float64Array( buffer );
482 | }
483 |
484 | return {
485 | imports: {
486 | env: {
487 | "__extjs_80d6d56760c65e49b7be8b6b01c1ea861b046bf0": function($0) {
488 | Module.STDWEB_PRIVATE.decrement_refcount( $0 );
489 | },
490 | "__extjs_da39a3ee5e6b4b0d3255bfef95601890afd80709": function($0) {
491 |
492 | },
493 | "__extjs_9f22d4ca7bc938409787341b7db181f8dd41e6df": function($0) {
494 | Module.STDWEB_PRIVATE.increment_refcount( $0 );
495 | },
496 | "__extjs_4cc2b2ed53586a2bd32ca2206724307e82bb32ff": function($0, $1) {
497 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). appendChild (($1));
498 | },
499 | "__extjs_e5fb9179be14d883494f9afd3d5f19a87ee532cc": function($0, $1) {
500 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). nextSibling ;})());
501 | },
502 | "__extjs_b26a87e444d448e2efeef401f8474b1886c40ae0": function($0, $1) {
503 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). lastChild ;})());
504 | },
505 | "__extjs_0aced9e2351ced72f1ff99645a129132b16c0d3c": function($0) {
506 | var value = Module.STDWEB_PRIVATE.get_raw_value( $0 );return Module.STDWEB_PRIVATE.register_raw_value( value );
507 | },
508 | "__extjs_db0226ae1bbecd407e9880ee28ddc70fc3322d9c": function($0) {
509 | $0 = Module.STDWEB_PRIVATE.to_js($0);Module.STDWEB_PRIVATE.unregister_raw_value (($0));
510 | },
511 | "__extjs_7e5e0af700270c95236d095748467db3ee37c15b": function($0, $1) {
512 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). checked = ($1);
513 | },
514 | "__extjs_de2896a7ccf316486788a4d0bc433c25d2f1a12b": function($0) {
515 | var r = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (r instanceof DOMException) && (r.name === "NotFoundError");
516 | },
517 | "__extjs_d16972c13e7882e1313d54277c2688b305eebc63": function($0) {
518 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof HTMLTextAreaElement) | 0;
519 | },
520 | "__extjs_55930e70138d1eac196bf34081691354e06aa248": function($0, $1) {
521 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). sessionStorage ;})());
522 | },
523 | "__extjs_cf32fb39093cd2549f37c2d392ef3198dcaa2ad4": function($0) {
524 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof Node) | 0;
525 | },
526 | "__extjs_ff5103e6cc179d13b4c7a785bdce2708fd559fc0": function($0) {
527 | Module.STDWEB_PRIVATE.tmp = Module.STDWEB_PRIVATE.to_js( $0 );
528 | },
529 | "__extjs_a8e1d9cfe0b41d7d61b849811ad1cfba32de989b": function($0, $1, $2) {
530 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). createElement (($2));})());
531 | },
532 | "__extjs_a342681e5c1e3fb0bdeac6e35d67bf944fcd4102": function($0, $1) {
533 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). value ;})());
534 | },
535 | "__extjs_02719998c6ece772fc2c8c3dd585272cdb2a127e": function($0, $1) {
536 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). add (($1));
537 | },
538 | "__extjs_425fcd9ee090672474c80ebf7d7b7719e5ba47fc": function($0) {
539 | $0 = Module.STDWEB_PRIVATE.to_js($0);console.debug (($0));
540 | },
541 | "__extjs_792ff14631f0ebffafcf6ed24405be73234b64ba": function($0, $1) {
542 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). classList ;})());
543 | },
544 | "__extjs_e031828dc4b7f1b8d9625d60486f03b0936c3f4f": function($0, $1, $2) {
545 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){try {return {value : function (){return ($1). removeChild (($2));}(), success : true};}catch (error){return {error : error , success : false};}})());
546 | },
547 | "__extjs_2ff57da66ea0e6d13328bc60a5a5dbfee840cbf2": function($0, $1, $2) {
548 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);var listener = ($0); ($1). removeEventListener (($2), listener); listener.drop ();
549 | },
550 | "__extjs_c41297f1f679af47d6390b4b617d1a8375706933": function($0) {
551 | $0 = Module.STDWEB_PRIVATE.to_js($0);console.error (($0));
552 | },
553 | "__extjs_a619fcd124d0713b9c1330733bb52e7a93475a4b": function($0, $1) {
554 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){var self = ($1); if (self.selectedIndex < 0){return null ;}else {return self.selectedIndex ;}})());
555 | },
556 | "__extjs_a3b76c5b7916fd257ee3f362dc672b974e56c476": function($0, $1) {
557 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). success ;})());
558 | },
559 | "__extjs_6ca5ed896d5e65a07120817a084b0c9d1668daf5": function($0) {
560 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof HTMLInputElement) | 0;
561 | },
562 | "__extjs_dc4a9844a3da9e83cb7a74b4e08eed6ff1be91f9": function($0, $1, $2) {
563 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). createTextNode (($2));})());
564 | },
565 | "__extjs_5ecfd7ee5cecc8be26c1e6e3c90ce666901b547c": function($0, $1) {
566 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). error ;})());
567 | },
568 | "__extjs_7ed1f62e776725bc93d54f5154abfb28a460024a": function($0) {
569 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof MouseEvent) | 0;
570 | },
571 | "__extjs_4028145202a86da6f0ee9067e044568730858725": function($0) {
572 | $0 = Module.STDWEB_PRIVATE.to_js($0);($0). type = "" ;
573 | },
574 | "__extjs_f484b2485bfbca4799114a1eed5e17c124da2193": function($0, $1) {
575 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). localStorage ;})());
576 | },
577 | "__extjs_74d5764ddc102a8d3b6252116087a68f2db0c9d4": function($0) {
578 | Module.STDWEB_PRIVATE.from_js($0, (function(){return window ;})());
579 | },
580 | "__extjs_1bec6cd85a41c300a38db6f77d11403ddcfae787": function($0) {
581 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof Element) | 0;
582 | },
583 | "__extjs_c023351d5bff43ef3dd317b499821cd4e71492f0": function($0) {
584 | var r = Module.STDWEB_PRIVATE.acquire_js_reference( $0 );return (r instanceof DOMException) && (r.name === "HierarchyRequestError");
585 | },
586 | "__extjs_27ff97ff577dd39402cb36ac5c70bcb0711afba8": function($0, $1, $2) {
587 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). getItem (($2));})());
588 | },
589 | "__extjs_aafcab8f69692c3778f32d5ffbed6214b6ecf266": function($0) {
590 | $0 = Module.STDWEB_PRIVATE.to_js($0);($0). stopPropagation ();
591 | },
592 | "__extjs_b79ab773ae35a43a8d7a215353fdb0413bd6224c": function($0, $1) {
593 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). nodeValue = ($1);
594 | },
595 | "__extjs_39e486671818674ef5d1eeb54119acb740296cc9": function($0, $1, $2) {
596 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);($0). setItem (($1), ($2));
597 | },
598 | "__extjs_97495987af1720d8a9a923fa4683a7b683e3acd6": function($0, $1) {
599 | console.error( 'Panic error message:', Module.STDWEB_PRIVATE.to_js_string( $0, $1 ) );
600 | },
601 | "__extjs_72fc447820458c720c68d0d8e078ede631edd723": function($0, $1, $2) {
602 | console.error( 'Panic location:', Module.STDWEB_PRIVATE.to_js_string( $0, $1 ) + ':' + $2 );
603 | },
604 | "__extjs_8dc3eee0077e1d4de8467d5817789266b81b33ad": function($0, $1) {
605 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). type = ($1);
606 | },
607 | "__extjs_4077c66de83a520233f5f35f5a8f3073f5bac5fc": function($0, $1, $2, $3) {
608 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);$3 = Module.STDWEB_PRIVATE.to_js($3);Module.STDWEB_PRIVATE.from_js($0, (function(){try {return {value : function (){return ($1). insertBefore (($2), ($3));}(), success : true};}catch (error){return {error : error , success : false};}})());
609 | },
610 | "__extjs_3d06b88dd7c8555dc8918ce12a4aa30730e8d3ba": function($0) {
611 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof HTMLSelectElement) | 0;
612 | },
613 | "__extjs_3fdba5930b45aa718ed8a660c7a88a76e22a21d8": function($0, $1) {
614 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). remove (($1));
615 | },
616 | "__extjs_5ac38c9ecbb9a6f75e30e71400dabbd8d3562771": function($0) {
617 | return (Module.STDWEB_PRIVATE.acquire_js_reference( $0 ) instanceof Event) | 0;
618 | },
619 | "__extjs_4f184f99dbb48468f75bc10e9fc4b1707e193775": function($0, $1, $2) {
620 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);($0). setAttribute (($1), ($2));
621 | },
622 | "__extjs_dc2fd915bd92f9e9c6a3bd15174f1414eee3dbaf": function() {
623 | console.error( 'Encountered a panic!' );
624 | },
625 | "__extjs_7c5535365a3df6a4cc1f59c4a957bfce1dbfb8ee": function($0, $1, $2, $3) {
626 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);$3 = Module.STDWEB_PRIVATE.to_js($3);Module.STDWEB_PRIVATE.from_js($0, (function(){var listener = ($1); ($2). addEventListener (($3), listener); return listener ;})());
627 | },
628 | "__extjs_e7aa18dc6d8c65f9c161c079ef483a13d144e4d3": function($0, $1) {
629 | $1 = Module.STDWEB_PRIVATE.to_js($1);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). nodeName ;})());
630 | },
631 | "__extjs_74e6b3628156d1f468b2cc770c3cd6665ca63ace": function($0, $1) {
632 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). removeAttribute (($1));
633 | },
634 | "__extjs_1c8769c3b326d77ceb673ada3dc887cf1d509509": function($0) {
635 | Module.STDWEB_PRIVATE.from_js($0, (function(){return document ;})());
636 | },
637 | "__extjs_4f998a6a2e8abfce697424379bb997930abe9f9e": function($0, $1) {
638 | $0 = Module.STDWEB_PRIVATE.to_js($0);$1 = Module.STDWEB_PRIVATE.to_js($1);($0). value = ($1);
639 | },
640 | "__extjs_496ebd7b1bc0e6eebd7206e8bee7671ea3b8006f": function($0, $1, $2) {
641 | $1 = Module.STDWEB_PRIVATE.to_js($1);$2 = Module.STDWEB_PRIVATE.to_js($2);Module.STDWEB_PRIVATE.from_js($0, (function(){return ($1). querySelector (($2));})());
642 | },
643 | "__web_on_grow": __web_on_grow
644 | }
645 | },
646 | initialize: function( instance ) {
647 | Object.defineProperty( Module, 'instance', { value: instance } );
648 | Object.defineProperty( Module, 'web_malloc', { value: Module.instance.exports.__web_malloc } );
649 | Object.defineProperty( Module, 'web_free', { value: Module.instance.exports.__web_free } );
650 | Object.defineProperty( Module, 'web_table', { value: Module.instance.exports.__web_table } );
651 |
652 |
653 | __web_on_grow();
654 | Module.instance.exports.main();
655 |
656 | return Module.exports;
657 | }
658 | };
659 | }
660 | ));
661 | }));
662 |
--------------------------------------------------------------------------------